.. note::

    Hallo und willkommen in der SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasten-Gemeinschaft auf Facebook! Tauchen Sie tiefer ein in die Welt von Raspberry Pi, Arduino und ESP32 mit anderen Enthusiasten.

    **Warum beitreten?**

    - **Expertenunterstützung**: Lösen Sie Nachverkaufsprobleme und technische Herausforderungen mit Hilfe unserer Gemeinschaft und unseres Teams.
    - **Lernen & Teilen**: Tauschen Sie Tipps und Anleitungen aus, um Ihre Fähigkeiten zu verbessern.
    - **Exklusive Vorschauen**: Erhalten Sie frühzeitigen Zugang zu neuen Produktankündigungen und exklusiven Einblicken.
    - **Spezialrabatte**: Genießen Sie exklusive Rabatte auf unsere neuesten Produkte.
    - **Festliche Aktionen und Gewinnspiele**: Nehmen Sie an Gewinnspielen und Feiertagsaktionen teil.

    👉 Sind Sie bereit, mit uns zu erkunden und zu erschaffen? Klicken Sie auf [|link_sf_facebook|] und treten Sie heute bei!

.. _4.1.15_py_pi5:

4.1.12 Alarmglocke
=========================

Einführung
-----------------

In diesem Projekt werden wir ein manuelles Alarmsystem bauen. Sie können den Kippschalter durch einen Thermistor oder einen lichtempfindlichen Sensor ersetzen, um einen Temperaturalarm oder einen Lichtalarm zu erstellen.

Benötigte Komponenten
------------------------------

Für dieses Projekt benötigen wir die folgenden Komponenten.

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

Es ist definitiv praktisch, ein ganzes Kit zu kaufen, hier ist der Link:

.. list-table::
    :widths: 20 20 20
    :header-rows: 1

    *   - Name	
        - ARTIKEL IN DIESEM KIT
        - LINK
    *   - Raphael Kit
        - 337
        - |link_Raphael_kit|

Sie können sie auch separat über die untenstehenden Links kaufen.

.. list-table::
    :widths: 30 20
    :header-rows: 1

    *   - KOMPONENTENVORSTELLUNG
        - KAUF-LINK

    *   - :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|

Schaltplan
-------------------------

============ ======== ======== ===
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

Experimentelle Verfahren
-----------------------------

**Schritt 1**: Bauen Sie den Schaltkreis.

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

**Schritt 2:** Verzeichnis wechseln.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python-pi5

**Schritt 3:** Ausführen.

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 4.1.15_AlarmBell_zero.py

Nachdem das Programm gestartet wurde, wird der Kippschalter nach rechts umgelegt, und der Summer gibt Alarmsignale aus. Gleichzeitig blinken die roten und grünen LEDs in einer bestimmten Frequenz.

.. warning::

    Wenn die Fehlermeldung ``RuntimeError: Cannot determine SOC peripheral base address`` angezeigt wird, lesen Sie bitte :ref:`faq_soc`

**Code**

.. note::
    Sie können den untenstehenden Code **Modifizieren/Zurücksetzen/Kopieren/Ausführen/Stoppen**. Aber davor müssen Sie zum Quellcodepfad wie ``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()

**Code-Erklärung**

#. Dieser Abschnitt umfasst das Importieren wesentlicher Bibliotheken für die Implementierung von Verzögerungen und Threading. Außerdem werden die Klassen LED, Button und TonalBuzzer aus der gpiozero-Bibliothek importiert, die für die Steuerung von GPIO-Geräten auf einem Raspberry Pi entscheidend sind.

   .. code-block:: python

       #!/usr/bin/env python3

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

#. Einrichtung eines Buzzers am GPIO-Pin 22, zweier LEDs an den GPIO-Pins 17 und 27 sowie Initialisierung eines Buttons am GPIO-Pin 18. Ein globaler Flag wird ebenfalls definiert, um den Zustand des Buzzers und der LEDs zu verwalten.

   .. 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

#. Diese Funktion steuert das Blinken der LEDs basierend auf dem Zustand des Flags. Wenn das Flag gesetzt (1) ist, wechseln sich die LEDs mit dem Ein- und Ausschalten ab. Ist das Flag nicht gesetzt (0), werden beide LEDs ausgeschaltet.

   .. 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()


#. Die Melodie wird als eine Sequenz von Noten (Frequenz) und Dauern (Sekunden) definiert.

   .. 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)
       ]

#. Spielt eine vordefinierte Melodie, wenn das Flag gesetzt ist. Die Melodie stoppt, wenn das Flag während des Spiels zurückgesetzt wird.

   .. 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

#. Überprüft kontinuierlich den Zustand des Buttons, um das Flag zu setzen oder zurückzusetzen.

   .. 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

#. Threads für ``buzzerWork`` und ``ledWork`` werden gestartet, sodass sie parallel zur Hauptfunktion laufen können.

   .. 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()

#. Stoppt den Buzzer und schaltet die LEDs aus, wenn das Programm unterbrochen wird, um einen sauberen Ausstieg zu gewährleisten.

   .. code-block:: python

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