.. note::
こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。
**参加する理由は?**
- **エキスパートサポート**:コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。
- **学び&共有**:ヒントやチュートリアルを交換してスキルを向上させましょう。
- **独占的なプレビュー**:新製品の発表や先行プレビューに早期アクセスしましょう。
- **特別割引**:最新製品の独占割引をお楽しみください。
- **祭りのプロモーションとギフト**:ギフトや祝日のプロモーションに参加しましょう。
👉 私たちと一緒に探索し、創造する準備はできていますか?[|link_sf_facebook|]をクリックして今すぐ参加しましょう!
.. _2.1.6_py_pi5:
2.1.6 ロータリーエンコーダーモジュール
================================================
はじめに
------------
このプロジェクトでは、ロータリーエンコーダーについて学びます。ロータリーエンコーダーは、厳密なタイミングのシーケンスで一連の定期的なパルスを持つ電子スイッチです。ICと併用すると、増加、減少、ページ送りなどの操作や、マウスのスクロール、メニュー選択などが実現できます。
必要な部品
------------------------------
このプロジェクトには、次のコンポーネントが必要です。
.. image:: ../python_pi5/img/2.1.6_rotary_encoder_list.png
一式を購入するのが便利です、こちらがリンクです:
.. list-table::
:widths: 20 20 20
:header-rows: 1
* - 名前
- このキットのアイテム
- リンク
* - Raphael Kit
- 337
- |link_Raphael_kit|
以下のリンクから別々に購入することもできます。
.. list-table::
:widths: 30 20
:header-rows: 1
* - コンポーネントの紹介
- 購入リンク
* - :ref:`cpn_gpio_board`
- |link_gpio_board_buy|
* - :ref:`cpn_breadboard`
- |link_breadboard_buy|
* - :ref:`cpn_wires`
- |link_wires_buy|
* - :ref:`cpn_rotary_encoder`
- |link_rotary_encoder_buy|
回路図
------------------------
.. image:: ../python_pi5/img/2.1.6_rotary_encoder_schematic.png
:align: center
実験手順
-----------------------
**ステップ 1:** 回路を組み立てる。
.. image:: ../python_pi5/img/2.1.6_rotary_encoder_circuit.png
この例では、ロータリーエンコーダーのピンをブレッドボードと40ピンケーブルを使用してラズベリーパイに直接接続し、ロータリーエンコーダーのGNDをGNDに、「+」を5Vに、SWをデジタルGPIO27に、DTをデジタルGPIO18に、CLKをデジタルGPIO17に接続します。
**ステップ 2:** コードファイルを開く。
.. raw:: html
.. code-block::
cd ~/raphael-kit/python-pi5
**ステップ 3:** 実行する。
.. raw:: html
.. code-block::
sudo python3 2.1.6_RotaryEncoder_zero.py
シェル上でカウントが表示されます。ロータリーエンコーダーを時計回りに回すと、カウントが増えます。反時計回りに回すと、カウントが減ります。ロータリーエンコーダーのスイッチを押すと、数値がゼロに戻ります。
.. warning::
エラー メッセージ ``RuntimeError: Cannot determine SOC peripheral base address`` が表示された場合は、 :ref:`faq_soc` を参照してください。
**コード**
.. note::
下記のコードを **変更/リセット/コピー/実行/停止** することができます。しかし、その前に ``raphael-kit/python-pi5`` のようなソースコードのパスに移動する必要があります。コードを変更した後、直接実行して効果を見ることができます。
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import RotaryEncoder, Button
from time import sleep
# Initialize the rotary encoder and button
encoder = RotaryEncoder(a=17, b=18) # Rotary Encoder connected to GPIO pins 17 (CLK) and 18 (DT)
button = Button(27) # Button connected to GPIO pin 27
global_counter = 0 # Track the rotary encoder's position
def rotary_change():
""" Update the global counter based on the rotary encoder's rotation. """
global global_counter
global_counter += encoder.steps # Adjust counter based on encoder steps
encoder.steps = 0 # Reset encoder steps after updating counter
print('Global Counter =', global_counter) # Display current counter value
def reset_counter():
""" Reset the global counter to zero when the button is pressed. """
global global_counter
global_counter = 0 # Reset the counter
print('Counter reset') # Indicate counter reset
# Assign the reset_counter function to button press event
button.when_pressed = reset_counter
try:
# Monitor rotary encoder continuously and process changes
while True:
rotary_change() # Handle rotary encoder changes
sleep(0.1) # Short delay to reduce CPU load
except KeyboardInterrupt:
# Gracefully handle a keyboard interrupt (Ctrl+C)
pass
**コード解析**
#. ``gpiozero`` ライブラリから ``RotaryEncoder`` と ``Button`` クラスをインポートし、遅延のために ``sleep`` 関数を使用します。
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import RotaryEncoder, Button
from time import sleep
#. GPIOピン17と18にロータリーエンコーダーを、GPIOピン27にボタンを初期化します。
.. code-block:: python
# Initialize the rotary encoder and button
encoder = RotaryEncoder(a=17, b=18) # Rotary Encoder connected to GPIO pins 17 (CLK) and 18 (DT)
button = Button(27) # Button connected to GPIO pin 27
#. ロータリーエンコーダーの位置を追跡するために ``global_counter`` グローバル変数を宣言します。
.. code-block:: python
global_counter = 0 # Track the rotary encoder's position
#. ロータリーエンコーダーの回転に基づいてグローバルカウンターを更新する ``rotary_change`` 関数を定義します。
.. code-block:: python
def rotary_change():
""" Update the global counter based on the rotary encoder's rotation. """
global global_counter
global_counter += encoder.steps # Adjust counter based on encoder steps
encoder.steps = 0 # Reset encoder steps after updating counter
print('Global Counter =', global_counter) # Display current counter value
#. ボタンが押されたときにグローバルカウンターをゼロにリセットする ``reset_counter`` 関数を定義します。
.. code-block:: python
def reset_counter():
""" Reset the global counter to zero when the button is pressed. """
global global_counter
global_counter = 0 # Reset the counter
print('Counter reset') # Indicate counter reset
#. ボタンが押されたときに呼び出されるように ``reset_counter`` 関数を割り当てます。
.. code-block:: python
# Assign the reset_counter function to button press event
button.when_pressed = reset_counter
#. 継続的なループ内でスクリプトは ``rotary_change`` を呼び出してロータリーエンコーダーの変更を処理し、CPU負荷を減らすために短い遅延を導入します。KeyboardInterruptsを優雅に処理するためにtry-exceptブロックを使用します。
.. code-block:: python
try:
# Monitor rotary encoder continuously and process changes
while True:
rotary_change() # Handle rotary encoder changes
sleep(0.1) # Short delay to reduce CPU load
except KeyboardInterrupt:
# Gracefully handle a keyboard interrupt (Ctrl+C)
pass