.. include:: /index.rst
:start-after: start_hello_message
:end-before: end_hello_message
.. _py_buton:
2.1 ボタン
==============
**はじめに**
このプロジェクトでは、ボタンを使ってLEDを制御する方法を学びます。ボタンは、さまざまな電子工作プロジェクトにおいて、回路やシステムとやり取りするための基本的な入力デバイスです。
----------------------------------------------
**必要なもの**
このプロジェクトを行うには、以下のコンポーネントが必要です。
.. list-table::
:widths: 30 20
:header-rows: 1
* - COMPONENT
- PURCHASE LINK
* - :ref:`cpn_breadboard`
- |link_breadboard_buy|
* - :ref:`cpn_wires`
- |link_wires_buy|
* - :ref:`cpn_resistor`
- |link_resistor_buy|
* - :ref:`cpn_led`
- |link_led_buy|
* - :ref:`cpn_button`
- |link_button_buy|
* - :ref:`cpn_fusion_hat`
- \-
* - Raspberry Pi
- \-
----------------------------------------------
**回路図**
このプロジェクトでは、ノーマルオープン型のボタンをRaspberry Piの入力として使用します。ボタンが押されると、GPIO17はハイレベル信号(3.3V)を受け取ります。Raspberry Piはこの信号を検出し、LEDを点灯させます。回路の接続は以下の図のとおりです。
.. image:: img/fzz/2.1.1_sch.png
:width: 80%
:align: center
----------------------------------------------
**配線図**
以下の手順に従って回路を組み立ててください。
1. LEDのアノード(長い脚)を、電流制限用抵抗を介してGPIOピン(GPIO22)に接続します。
2. LEDのカソード(短い脚)をGNDに接続します。
3. ボタンの一方の端子をGPIO17に、もう一方の端子をGNDに接続します。
.. image:: img/fzz/2.1.1_bb.png
:width: 80%
:align: center
----------------------------------------------
**サンプルの実行**
このチュートリアルで使用するすべてのサンプルコードは ``ai-lab-kit`` ディレクトリに含まれています。
以下の手順でサンプルを実行してください。
.. raw:: html
.. code-block:: shell
cd ~/ai-lab-kit/python/
sudo python3 2.1_Button.py
このPythonスクリプトは、ボタンでLEDを制御するインタラクティブな構成を示しています。実行すると、次のように動作します。
1. ボタン(GPIO17に接続)を押すと、LED(GPIO22に接続)が点灯します。
2. ボタンを離すと、LEDが消灯します。
3. プログラムは継続的に動作し、ボタンの押下および解放イベントを監視してLEDを制御します。
----------------------------------------------
**コード**
以下のPythonコードは、ボタンの押下と解放に応じてLEDを切り替えます。
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
from fusion_hat.pin import Pin, Mode, Pull
from signal import pause # Import pause function from signal module
# Initialize an LED object on GPIO pin 22
led = Pin(22,mode=Mode.OUT)
# Initialize a Button object on GPIO pin 17
button = Pin(17, mode=Mode.IN, pull=Pull.DOWN)
# # Link the button's "when_activated" event to the LED's high() method
button.when_activated = led.high
# # Link the button's "when_deactivated" event to the LED's low() method
button.when_deactivated = led.low
# Run an event loop that waits for button events and keeps the script running
print("CTRL + C to exit")
pause()
----------------------------------------------
**コードの解説**
1. **ライブラリのインポート**
``fusion_hat`` ライブラリはGPIO制御のためのシンプルなインターフェースを提供し、 ``signal`` モジュールはプログラムを継続実行させるために使用します。
.. code-block:: python
#!/usr/bin/env python3
from fusion_hat.pin import Pin, Mode, Pull
from signal import pause # Import pause function from signal module
2. **コンポーネントの初期化**
LEDはGPIO22に接続し、ボタンはGPIO17に接続します。
.. code-block:: python
# Initialize an LED object on GPIO pin 22
led = Pin(22,mode=Mode.OUT)
# Initialize a Button object on GPIO pin 17
button = Pin(17, mode=Mode.IN, pull=Pull.DOWN)
3. **イベント処理**
``when_activated`` と ``when_deactivated`` のイベントを、それぞれLEDの ``high()`` メソッドと ``low()`` メソッドに関連付けます。これにより、ボタンを押すとLEDが点灯し、ボタンを離すと消灯します。
.. code-block:: python
button.when_activated = led.high
button.when_deactivated = led.low
4. **イベントループ**
``pause()`` 関数によりプログラムを継続実行し、ボタンの押下および解放イベントを待機します。
.. code-block:: python
pause()
----------------------------------------------
**トラブルシューティング**
1. **LEDが点灯しない**
- **原因**: GPIOピンの接続ミス、またはLEDの配線に問題がある可能性があります。
- **対処方法**: LEDのプラス側の脚がGPIO22に接続され、マイナス側の脚が抵抗を介してGNDに接続されていることを確認してください。
2. **ボタンを押しても反応しない**
- **原因**: ボタンの配線、またはGPIOピンの設定が正しくない可能性があります。
- **対処方法**: ボタンがGPIO17とGNDに正しく接続されていることを確認してください。
3. **ボタンの状態に関係なくLEDが点灯したまま、または消灯したままになる**
- **原因**: ボタンのイベントが正しく検出されていない可能性があります。
- **対処方法**: マルチメーターや簡単な回路を使って、ボタン自体が正常に動作しているか確認してください。
----------------------------------------------
**拡張アイデア**
1. **LEDの状態をトグルする**
ボタンを押すたびにLEDを単純に点灯・消灯するのではなく、状態を切り替えるようにスクリプトを変更できます。
.. code-block:: python
def toggle():
if led.value() == 1:
led.off()
else:
led.on()
button.when_activated = toggle
2. **複数のLED**
1つのボタンで複数のLEDを制御し、異なる点灯パターンを切り替えることができます。
.. code-block:: python
leds = [LED(17), LED(27), LED(22)]
current_led = 0
def cycle_leds():
global current_led
leds[current_led].off()
current_led = (current_led + 1) % len(leds)
leds[current_led].on()
button.when_activated = cycle_leds
3. **ボタンの押下時間**
ボタンを押している時間の長さに応じて、異なる動作を行う機能を追加できます。
.. code-block:: python
from time import time
press_time = None
def start_timer():
global press_time
press_time = time()
def check_duration():
global press_time
duration = time() - press_time
if duration < 2:
led.on()
else:
led.off()
button.when_activated = start_timer
button.when_deactivated = check_duration
4. **デバウンス処理**
より正確にボタン押下を検出するために、ソフトウェアデバウンスを実装できます。
.. code-block:: python
from time import time
press_time = None
debounce_time = 0.2
def press():
global press_time
press_time = time()
def debounce():
global press_time
current_time = time()
duration = current_time - press_time
if duration < debounce_time:
return
else:
led.on()
button.when_activated = press
button.when_deactivated = debounce
----------------------------------------------
**まとめ**
このプロジェクトでは、Fusion HAT+を使ってボタンでLEDを制御する方法を紹介しました。ボタンは汎用性の高いコンポーネントであり、基本的な回路から複雑なインタラクティブシステムまで、さまざまなアプリケーションに活用できます。