.. 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.10_py_pi5:

4.1.7 Intelligenter Ventilator
===========================================

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

In diesem Projekt werden wir Motoren, Tasten und Thermistoren verwenden, um einen manuellen + automatischen intelligenten Ventilator zu bauen, dessen Windgeschwindigkeit einstellbar ist.

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

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

.. image:: ../python_pi5/img/4.1.10_smart_fan_list.png
    :width: 800
    :align: center

Es ist definitiv praktisch, ein komplettes 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 einzeln ü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_power_module`
        - \-
    *   - :ref:`cpn_thermistor`
        - |link_thermistor_buy|
    *   - :ref:`cpn_l293d`
        - \-
    *   - :ref:`cpn_adc0834`
        - \-
    *   - :ref:`cpn_button`
        - |link_button_buy|
    *   - :ref:`cpn_motor`
        - |link_motor_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
GPIO5        Pin 29   21       5
GPIO6        Pin 31   22       6
GPIO13       Pin 33   23       13
============ ======== ======== ===

.. image:: ../python_pi5/img/4.1.10_smart_fan_schematic.png
   :align: center

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

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

.. image:: ../python_pi5/img/4.1.10_smart_fan_circuit.png

.. note::
    Das Strommodul kann eine 9-V-Batterie mit der im Kit enthaltenen 9-V-Batterieklemme verwenden. Stecken Sie die Jumperkappe des Strommoduls in die 5V-Stromschienen des Steckbretts.

.. image:: ../python_pi5/img/4.1.10_smart_fan_battery.jpeg
   :align: center

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

.. 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.10_SmartFan_zero.py

Während der Code ausgeführt wird, starten Sie den Ventilator, indem Sie die Taste drücken. Jedes Mal, wenn Sie drücken, wird eine Geschwindigkeitsstufe nach oben oder unten angepasst. Es gibt **5** Arten von Geschwindigkeitsstufen: **0~4**. Wenn Sie auf die 4. Geschwindigkeitsstufe eingestellt sind und die Taste drücken, hört der Ventilator auf zu arbeiten und zeigt eine Windgeschwindigkeit von **0** an.

Sobald die Temperatur um mehr als 2°C steigt oder fällt, wird die Geschwindigkeit automatisch um eine Stufe schneller oder langsamer.

Code
--------

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

.. raw:: html

    <run></run>

.. code-block:: python

   #!/usr/bin/env python3

   from gpiozero import Motor, Button
   from time import sleep
   import ADC0834
   import math

   # Initialize GPIO pins for the button and motor control
   BtnPin = Button(22)
   motor = Motor(forward=5, backward=6, enable=13)

   # Initialize the ADC0834 module for temperature sensing
   ADC0834.setup()

   # Initialize variables to track the motor speed level and temperatures
   level = 0
   currentTemp = 0
   markTemp = 0

   def temperature():
       """
       Reads and calculates the current temperature from the sensor.
       Returns:
           float: The current temperature in Celsius.
       """
       # Read analog value from the ADC0834 module
       analogVal = ADC0834.getResult()
       # Convert analog value to voltage and then to resistance
       Vr = 5 * float(analogVal) / 255
       Rt = 10000 * Vr / (5 - Vr)
       # Calculate temperature in Celsius
       temp = 1 / (((math.log(Rt / 10000)) / 3950) + (1 / (273.15 + 25)))
       Cel = temp - 273.15
       return Cel

   def motor_run(level):
       """
       Adjusts the motor speed based on the specified level.
       Args:
           level (int): Desired motor speed level.
       Returns:
           int: Adjusted motor speed level.
       """
       # Stop the motor if the level is 0
       if level == 0:
           motor.stop()
           return 0
       # Cap the level at 4 for maximum speed
       if level >= 4:
           level = 4
       # Set the motor speed
       motor.forward(speed=float(level / 4))
       return level

   def changeLevel():
       """
       Changes the motor speed level when the button is pressed and updates the reference temperature.
       """
       global level, currentTemp, markTemp
       print("Button pressed")
       # Cycle through levels 0-4
       level = (level + 1) % 5
       # Update the reference temperature
       markTemp = currentTemp

   # Bind the button press event to changeLevel function
   BtnPin.when_pressed = changeLevel

   def main():
       """
       Main function to continuously monitor and respond to temperature changes.
       """
       global level, currentTemp, markTemp
       # Set initial reference temperature
       markTemp = temperature()
       while True:
           # Continuously read current temperature
           currentTemp = temperature()
           # Adjust motor level based on temperature difference
           if level != 0:
               if currentTemp - markTemp <= -2:
                   level -= 1
                   markTemp = currentTemp
               elif currentTemp - markTemp >= 2:
                   if level < 4:
                       level += 1
                   markTemp = currentTemp
           # Run the motor at the adjusted level
           level = motor_run(level)

   # Run the main function and handle KeyboardInterrupt
   try:
       main()
   except KeyboardInterrupt:
       # Stop the motor when the script is interrupted
       motor.stop()


Code-Erklärung
---------------------

#. Importiert Klassen zur Verwaltung eines Motors und einer Taste sowie die Sleep-Funktion für Pausen. Zusätzlich werden die ADC0834-Bibliothek für die Temperaturmessung und die Math-Bibliothek für mathematische Berechnungen importiert.

   .. code-block:: python

       #!/usr/bin/env python3

       from gpiozero import Motor, Button
       from time import sleep
       import ADC0834
       import math

#. Richtet die Taste an GPIO-Pin 22 ein und konfiguriert den Motor mit spezifischen GPIO-Pins zur Steuerung. Initialisiert das ADC0834-Modul für die Temperaturmessung. Initialisiert auch Variablen zur Überwachung der Motorgeschwindigkeitsstufe und der Temperaturen.

   .. code-block:: python

       # Initialize GPIO pins for the button and motor control
       BtnPin = Button(22)
       motor = Motor(forward=5, backward=6, enable=13)

       # Initialize the ADC0834 module for temperature sensing
       ADC0834.setup()

       # Initialize variables to track the motor speed level and temperatures
       level = 0
       currentTemp = 0
       markTemp = 0

#. Definiert eine Funktion zum Lesen und Berechnen der Temperatur vom Sensor, Umrechnung der Messwerte in Celsius.

   .. code-block:: python

       def temperature():
           """
           Reads and calculates the current temperature from the sensor.
           Returns:
               float: The current temperature in Celsius.
           """
           # Read analog value from the ADC0834 module
           analogVal = ADC0834.getResult()
           # Convert analog value to voltage and then to resistance
           Vr = 5 * float(analogVal) / 255
           Rt = 10000 * Vr / (5 - Vr)
           # Calculate temperature in Celsius
           temp = 1 / (((math.log(Rt / 10000)) / 3950) + (1 / (273.15 + 25)))
           Cel = temp - 273.15
           return Cel

#. Führt eine Funktion ein, um die Motorgeschwindigkeit entsprechend der angegebenen Stufe anzupassen.

   .. code-block:: python

       def motor_run(level):
           """
           Adjusts the motor speed based on the specified level.
           Args:
               level (int): Desired motor speed level.
           Returns:
               int: Adjusted motor speed level.
           """
           # Stop the motor if the level is 0
           if level == 0:
               motor.stop()
               return 0
           # Cap the level at 4 for maximum speed
           if level >= 4:
               level = 4
           # Set the motor speed
           motor.forward(speed=float(level / 4))
           return level

#. Implementiert eine Funktion, um die Motorgeschwindigkeitsstufe manuell mit einer Taste zu ändern, und bindet diese Funktion an das Druckereignis der Taste.

   .. code-block:: python

       def changeLevel():
           """
           Changes the motor speed level when the button is pressed and updates the reference temperature.
           """
           global level, currentTemp, markTemp
           print("Button pressed")
           # Cycle through levels 0-4
           level = (level + 1) % 5
           # Update the reference temperature
           markTemp = currentTemp

       # Bind the button press event to changeLevel function
       BtnPin.when_pressed = changeLevel

#. Die Hauptfunktion, die entwickelt wurde, um die Motorgeschwindigkeit kontinuierlich an Temperaturschwankungen anzupassen, bleibt zu implementieren.

   .. code-block:: python

       def main():
           """
           Main function to continuously monitor and respond to temperature changes.
           """
           global level, currentTemp, markTemp
           # Set initial reference temperature
           markTemp = temperature()
           while True:
               # Continuously read current temperature
               currentTemp = temperature()
               # Adjust motor level based on temperature difference
               if level != 0:
                   if currentTemp - markTemp <= -2:
                       level -= 1
                       markTemp = currentTemp
                   elif currentTemp - markTemp >= 2:
                       if level < 4:
                           level += 1
                       markTemp = currentTemp
               # Run the motor at the adjusted level
               level = motor_run(level)

#. Führt die Hauptfunktion aus und stellt sicher, dass der Motor stoppt, wenn das Skript unterbrochen wird.


   .. code-block:: python

       # Run the main function and handle KeyboardInterrupt
       try:
           main()
       except KeyboardInterrupt:
           # Stop the motor when the script is interrupted
           motor.stop()



