.. 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.3_py:

4.1.3 Sprachuhr
==========================

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

In diesem Projekt werden wir eine Sprachuhr mit einem Lautsprecher und einer 4-stelligen 7-Segment-Anzeige erstellen. Die 4-stellige 7-Segment-Anzeige zeigt die Uhrzeit an, und der Lautsprecher gibt die Uhrzeit stündlich aus.

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

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

.. image:: ../img/3.1.17components.png
  :width: 800
  :align: center

Es ist definitiv praktisch, ein ganzes Set 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 einzeln über die untenstehenden Links kaufen.

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

    *   - KOMPONENTENBESCHREIBUNG
        - 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_audio_speaker`
        - \-
    *   - :ref:`cpn_4_digit`
        - \-
    *   - :ref:`cpn_74hc595`
        - |link_74hc595_buy|


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

============ ======== ======== ===
T-Board Name physical wiringPi BCM
GPIO17       Pin 11   0        17
GPIO27       Pin 13   2        27
GPIO22       Pin 15   3        22
SPIMOSI      Pin 19   12       10
GPIO18       Pin 12   1        18
GPIO23       Pin 16   4        23
GPIO24       Pin 18   5        24
============ ======== ======== ===

.. image:: ../img/schmatic_4_digit.png

.. image:: ../img/3.1.17_schematic.png
  :width: 500
  :align: center

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

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

.. image:: ../img/3.1.17fritzing.png
  :width: 900
  :align: center

Vor diesem Projekt müssen Sie sicherstellen, dass Sie :ref:`3.1.4_py` abgeschlossen haben.

**Schritt 2:** Verwenden Sie den Befehl ``date``, um die lokale Zeit anzuzeigen.

.. raw:: html

   <run></run>

.. code-block:: 

    date

Wenn die lokale Zeit nicht mit der tatsächlichen Zeit übereinstimmt, müssen Sie den folgenden Befehl verwenden, um die Zeitzone einzustellen.

.. raw:: html

   <run></run>

.. code-block:: 

    sudo dpkg-reconfigure tzdata

Wählen Sie Ihre Zeitzone aus.

.. image:: ../img/tzdata.png

**Schritt 3:** Gehen Sie in den Ordner des Codes.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python/

**Schritt 4:** Ausführen.

.. raw:: html

   <run></run>

.. code-block::

    python3 4.1.3_SpeechClock.py

Wenn der Code ausgeführt wird, zeigt die 4-stellige 7-Segment-Anzeige die Uhrzeit an und schlägt stündlich an.

**Code**

.. note::
    Sie können den untenstehenden Code **Modifizieren/Zurücksetzen/Kopieren/Ausführen/Stoppen**. Davor müssen Sie jedoch zum Quellcodepfad wie ``raphael-kit/python`` gehen. Nach der Modifikation können Sie ihn direkt ausführen, um den Effekt zu sehen.

.. raw:: html

    <run></run>

.. code-block:: python

    import RPi.GPIO as GPIO
    from tts import TTS
    import time

    tts = TTS(engine="espeak")
    tts.lang('en-US')

    SDI = 24
    RCLK = 23
    SRCLK = 18

    placePin = (10, 22, 27, 17)
    number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90)

    def setup():
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(SDI, GPIO.OUT)
        GPIO.setup(RCLK, GPIO.OUT)
        GPIO.setup(SRCLK, GPIO.OUT)
        for i in placePin:
            GPIO.setup(i, GPIO.OUT)

    def clearDisplay():
        for i in range(8):
            GPIO.output(SDI, 1)
            GPIO.output(SRCLK, GPIO.HIGH)
            GPIO.output(SRCLK, GPIO.LOW)
        GPIO.output(RCLK, GPIO.HIGH)
        GPIO.output(RCLK, GPIO.LOW)    

    def hc595_shift(data): 
        for i in range(8):
            GPIO.output(SDI, 0x80 & (data << i))
            GPIO.output(SRCLK, GPIO.HIGH)
            GPIO.output(SRCLK, GPIO.LOW)
        GPIO.output(RCLK, GPIO.HIGH)
        GPIO.output(RCLK, GPIO.LOW)

    def pickDigit(digit):
        for i in placePin:
            GPIO.output(i,GPIO.LOW)
        GPIO.output(placePin[digit], GPIO.HIGH)

    def loop():
        status = 0                   
        while True:
            time.localtime(time.time())
            hour = int(time.strftime('%H',time.localtime(time.time())))
            minute = int(time.strftime('%M',time.localtime(time.time())))

            clearDisplay() 
            pickDigit(0)  
            hc595_shift(number[minute % 10])
            
            clearDisplay()
            pickDigit(1)
            hc595_shift(number[minute % 100//10])

            clearDisplay()
            pickDigit(2)
            hc595_shift(number[hour % 10])

            clearDisplay()
            pickDigit(3)
            hc595_shift(number[hour % 100//10])

            if minute == 0 and status == 0:
                tts.say('The time is now ' + str(hour) + ' hours and ' + str(minute) + ' minutes')
                status = 1
            elif minute != 0:
                status = 0

    def destroy():   # When "Ctrl+C" is pressed, the function is executed.
        GPIO.cleanup()

    if __name__ == '__main__':  # Program starting from here
        setup()
        try:
            loop()
        except KeyboardInterrupt:
            destroy()

**Code-Erklärung**

.. code-block:: python

    time.localtime(time.time())
    hour = int(time.strftime('%H',time.localtime(time.time())))
    minute = int(time.strftime('%M',time.localtime(time.time())))

Durch die Funktion ``time.time()`` erhalten wir den Zeitstempel der aktuellen Zeit (die Anzahl der seit der Epoche 1970 verstrichenen Sekunden im Fließkommawert). Anschließend verwenden wir die Zeitformatierungsmethode des Zeitmoduls ``(time.localtime(time.time()))``, um den aktuellen Zeitstempel zu verarbeiten, sodass wir den Zeitstempel als Ortszeit formatieren können.

Das Eingabeergebnis lautet:

``time.struct_time(tm_year=2021, tm_mon=5, tm_mday=28, tm_hour=13, tm_min=54, tm_sec=26, tm_wday=4, tm_yday=148, tm_isdst=0)``

Zuletzt verwenden wir die Methode ``time.strftime()`` um die umfangreiche Informationskette in das von uns gewünschte Format zu bringen. Wenn Sie die aktuelle Stunde erhalten möchten, können Sie dies durch die Funktion ``time.strftime('%H',time.localtime(time.time()))`` tun.

Die Ausgabe der durch Änderung des ersten Parameters spezifizierten formatierten Zeichenkette sind unten aufgelistet.

+----+-------------------------------------------------------------+
| %y | Zweistellige Jahresdarstellung(00-99)                       |
+----+-------------------------------------------------------------+
| %Y | Vierstellige Jahresdarstellung(0000-9999)                   |
+----+-------------------------------------------------------------+
| %m | Monat(01-12)                                                |
+----+-------------------------------------------------------------+
| %H | Tag des Monats(0-31)                                        |
+----+-------------------------------------------------------------+
| %I | Stunden in einer 24-Stunden-Uhr(0-23)                       |
+----+-------------------------------------------------------------+
| %M | Stunden in einer 12-Stunden-Uhr(01-12)                      |
+----+-------------------------------------------------------------+
| %y | Minuten(00-59)                                              |
+----+-------------------------------------------------------------+
| %S | Sekunde(00-59)                                              |
+----+-------------------------------------------------------------+
| %a | Lokaler vereinfachter Wochentagsname                        |
+----+-------------------------------------------------------------+
| %A | Vollständiger lokaler Wochentagsname                        |
+----+-------------------------------------------------------------+
| %b | Lokaler vereinfachter Monatsname                            |
+----+-------------------------------------------------------------+
| %B | Vollständiger lokaler Monatsname                            |
+----+-------------------------------------------------------------+
| %c | Lokale entsprechende Datums- und Zeitdarstellung            |
+----+-------------------------------------------------------------+
| %j | Tag des Jahres(001-366)                                     |
+----+-------------------------------------------------------------+
| %p | Das Äquivalent von lokalem Vormittag oder Nachmittag        |
+----+-------------------------------------------------------------+
| %U | Anzahl der Wochen eines Jahres(00-53), beginnend mit Sonntag|
+----+-------------------------------------------------------------+
| %w | Woche (0-6), beginnend mit Sonntag                          |
+----+-------------------------------------------------------------+
| %W | Anzahl der Wochen eines Jahres(00-53), beginnend mit Montag |
+----+-------------------------------------------------------------+
| %x | Lokale entsprechende Datumsdarstellung                      |
+----+-------------------------------------------------------------+
| %X | Lokale entsprechende Zeitdarstellung                        |
+----+-------------------------------------------------------------+
| %Z | Der Name der aktuellen Zeitzone                             |
+----+-------------------------------------------------------------+

.. note::
    Die Ausgabe der Methode ``time.strftime()`` sind alles String-Variablen. Bevor Sie diese verwenden, denken Sie daran, eine erzwungene Typumwandlung durchzuführen.

.. code-block:: python

    clearDisplay() 
    pickDigit(0)  
    hc595_shift(number[minute % 10])
    
    clearDisplay()
    pickDigit(1)
    hc595_shift(number[minute % 100//10])

    clearDisplay()
    pickDigit(2)
    hc595_shift(number[hour % 10])

    clearDisplay()
    pickDigit(3)
    hc595_shift(number[hour % 100//10])

Die Zehnerstelle der Stunde wird auf der ersten 7-Segment-Digitalanzeige angezeigt, die Einerstelle auf der zweiten. 
Anschließend wird die Zehnerstelle der Minuten auf der dritten Digitalanzeige und die Einerstelle auf der letzten angezeigt.

.. code-block:: python

    if minute == 0 and status == 0:
        tts.say('The time is now ' + str(hour) + ' hours and ' + str(minute) + ' minutes')
        status = 1
    elif minute != 0:
        status = 0

Wenn die Minutenzahl 0 beträgt (also stündlich), wird der Raspberry Pi TTS verwenden, um uns die Uhrzeit anzusagen.

Phänomen-Bild
------------------------

.. image:: ../img/4.1.3speech_clock.JPG
   :align: center
