.. note::

    こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ！Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。

    **参加する理由は？**

    - **エキスパートサポート**：コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。
    - **学び＆共有**：ヒントやチュートリアルを交換してスキルを向上させましょう。
    - **独占的なプレビュー**：新製品の発表や先行プレビューに早期アクセスしましょう。
    - **特別割引**：最新製品の独占割引をお楽しみください。
    - **祭りのプロモーションとギフト**：ギフトや祝日のプロモーションに参加しましょう。

    👉 私たちと一緒に探索し、創造する準備はできていますか？[|link_sf_facebook|]をクリックして今すぐ参加しましょう！

.. _4.1.15_py_pi5:

4.1.12 アラームベル
=======================


概要
-----------------

このプロジェクトでは、手動アラームデバイスを作成します。トグルスイッチをサーミスタまたは光感知センサーに置き換えて、温度アラームまたは光アラームを作成できます。

必要な部品
------------------------------

このプロジェクトには、次のコンポーネントが必要です。

.. image:: ../python_pi5/img/4.1.15_alarm_bell_list.png
    :width: 800
    :align: center

一式を購入するのが便利です、こちらがリンクです： 

.. 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_resistor`
        - |link_resistor_buy|
    *   - :ref:`cpn_led`
        - |link_led_buy|
    *   - :ref:`cpn_buzzer`
        - |link_passive_buzzer_buy|
    *   - :ref:`cpn_slide_switch`
        - |link_slide_switch_buy|
    *   - :ref:`cpn_transistor`
        - |link_transistor_buy|
    *   - :ref:`cpn_capacitor`
        - |link_capacitor_buy|

回路図
-------------------------


============ ======== ======== ===
T-Board Name physical wiringPi BCM
GPIO17       Pin 11   0        17
GPIO18       Pin 12   1        18
GPIO27       Pin 13   2        27
GPIO22       Pin 15   3        22
============ ======== ======== ===

.. image:: ../python_pi5/img/4.1.15_alarm_bell_schematic.png
    :width: 600
    :align: center

実験手順
-----------------------------

**ステップ 1**: 回路を組み立てます。

.. image:: ../python_pi5/img/4.1.15_alarm_bell_circuit.png

**ステップ 2**: ディレクトリを変更します。

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python-pi5

**ステップ 3**: 実行します。

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 3.1.10_AlarmBell_zero.py

プログラムを起動した後、トグルスイッチを右に切り替えると、ブザーからアラーム音が鳴ります。同時に、赤と緑のLEDが一定の頻度で点滅します。

コード
----------------

.. note::
    以下のコードを **修正/リセット/コピー/実行/停止** することができます。ただし、その前に ``raphael-kit/python-pi5`` のソースコードパスに移動する必要があります。

.. raw:: html

    <run></run>

.. code-block:: python

    #!/usr/bin/env python3

    from gpiozero import LED, Button, TonalBuzzer
    import time
    import threading

    # Initialize TonalBuzzer on GPIO pin 22
    BeepPin = TonalBuzzer(22)

    # Initialize LEDs on GPIO pins 17 and 27
    ALedPin = LED(17)
    BLedPin = LED(27)

    # Initialize Button on GPIO pin 18
    switchPin = Button(18)

    # Global flag to control the buzzer and LED states
    flag = 0

    def ledWork():
        """
        Control LED blinking pattern based on the flag state.
        When flag is set, alternately blink ALedPin and BLedPin.
        """
        while True:
            if flag:
                # Alternate blinking of LEDs
                ALedPin.on()
                time.sleep(0.5)
                ALedPin.off()
                BLedPin.on()
                time.sleep(0.5)
                BLedPin.off()
            else:
                # Turn off both LEDs if flag is not set
                ALedPin.off()
                BLedPin.off()

    # Define the musical tune as a list of notes and their durations
    tune = [
        ('C4', 0.1), ('E4', 0.1), ('G4', 0.1), 
        (None, 0.1), 
        ('E4', 0.1), ('G4', 0.1), ('C5', 0.1), 
        (None, 0.1), 
        ('C5', 0.1), ('G4', 0.1), ('E4', 0.1), 
        (None, 0.1), 
        ('G4', 0.1), ('E4', 0.1), ('C4', 0.1), 
        (None, 0.1)
    ]

    def buzzerWork():
        """
        Play a tune using the buzzer based on the flag state.
        The tune is played only when the flag is set.
        """
        while True:
            for note, duration in tune:
                if flag == 0:
                    break
                print(note)  # Output the current note to the console
                BeepPin.play(note)  # Play the current note
                time.sleep(duration)  # Pause for the duration of the note
            BeepPin.stop()  # Stop the buzzer after playing the tune

    def main():
        """
        Monitor button press to update the flag state.
        Sets the flag when the button is pressed.
        """
        global flag
        while True:
            flag = 1 if switchPin.is_pressed else 0

    try:
        # Initialize and start threads for buzzer and LED control
        tBuzz = threading.Thread(target=buzzerWork)
        tBuzz.start()
        tLed = threading.Thread(target=ledWork)
        tLed.start()
        main()

    except KeyboardInterrupt:
        # Stop the buzzer and turn off LEDs on program interruption
        BeepPin.stop()
        ALedPin.off()    
        BLedPin.off()


**コードの説明**

1. このセグメントでは、遅延とスレッド処理の実装に必要なライブラリのインポートを行います。また、Raspberry Pi上のGPIOデバイスを制御するために、gpiozeroライブラリからLED、Button、およびTonalBuzzerクラスもインポートしています。

   .. code-block:: python

       #!/usr/bin/env python3

       from gpiozero import LED, Button, TonalBuzzer
       import time
       import threading

2. GPIOピン22にブザー、GPIOピン17と27にLED、GPIOピン18にボタンをセットアップします。ブザーとLEDの状態を管理するために、グローバルフラグも定義されています。

   .. code-block:: python

       # Initialize TonalBuzzer on GPIO pin 22
       BeepPin = TonalBuzzer(22)

       # Initialize LEDs on GPIO pins 17 and 27
       ALedPin = LED(17)
       BLedPin = LED(27)

       # Initialize Button on GPIO pin 18
       switchPin = Button(18)

       # Global flag to control the buzzer and LED states
       flag = 0


3. この関数は、フラグの状態に応じてLEDの点滅を制御します。フラグが設定されている（1）場合、各LEDをオンとオフに交互に切り替えます。フラグが設定されていない（0）場合、両方のLEDをオフにします。

   .. code-block:: python

       def ledWork():
           """
           Control LED blinking pattern based on the flag state.
           When flag is set, alternately blink ALedPin and BLedPin.
           """
           while True:
               if flag:
                   # Alternate blinking of LEDs
                   ALedPin.on()
                   time.sleep(0.5)
                   ALedPin.off()
                   BLedPin.on()
                   time.sleep(0.5)
                   BLedPin.off()
               else:
                   # Turn off both LEDs if flag is not set
                   ALedPin.off()
                   BLedPin.off()

4. 音楽の音符（周波数）と持続時間（秒）のシーケンスである「tune」が定義されています。

   .. code-block:: python

       # Define the musical tune as a list of notes and their durations
       tune = [
           ('C4', 0.1), ('E4', 0.1), ('G4', 0.1), 
           (None, 0.1), 
           ('E4', 0.1), ('G4', 0.1), ('C5', 0.1), 
           (None, 0.1), 
           ('C5', 0.1), ('G4', 0.1), ('E4', 0.1), 
           (None, 0.1), 
           ('G4', 0.1), ('E4', 0.1), ('C4', 0.1), 
           (None, 0.1)
       ]

5. フラグが設定されている場合に予め定義されたメロディを演奏します。演奏中にフラグが解除されると、演奏が停止します。

   .. code-block:: python

       def buzzerWork():
           """
           Play a tune using the buzzer based on the flag state.
           The tune is played only when the flag is set.
           """
           while True:
               for note, duration in tune:
                   if flag == 0:
                       break
                   print(note)  # Output the current note to the console
                   BeepPin.play(note)  # Play the current note
                   time.sleep(duration)  # Pause for the duration of the note
               BeepPin.stop()  # Stop the buzzer after playing the tune

6. ボタンの状態を確認し、フラグを設定または解除します。

   .. code-block:: python

       def main():
           """
           Monitor button press to update the flag state.
           Sets the flag when the button is pressed.
           """
           global flag
           while True:
               flag = 1 if switchPin.is_pressed else 0

7. ``buzzerWork`` と ``ledWork`` のスレッドを開始し、それらをメイン関数と同時に実行できるようにします。

   .. code-block:: python

       try:
           # Initialize and start threads for buzzer and LED control
           tBuzz = threading.Thread(target=buzzerWork)
           tBuzz.start()
           tLed = threading.Thread(target=ledWork)
           tLed.start()
           main()


8. プログラムが中断されたときに、きれいに終了するように、ブザーを停止し、LEDをオフにします。

   .. code-block:: python

       except KeyboardInterrupt:
           # Stop the buzzer and turn off LEDs on program interruption
           BeepPin.stop()
           ALedPin.off()    
           BLedPin.off()