 
.. note::

    Bonjour et bienvenue dans la Communauté Facebook des passionnés de Raspberry Pi, Arduino et ESP32 de SunFounder ! Plongez plus profondément dans l'univers des Raspberry Pi, Arduino et ESP32 avec d'autres passionnés.

    **Pourquoi rejoindre ?**

    - **Support d'experts** : Résolvez les problèmes après-vente et les défis techniques avec l'aide de notre communauté et de notre équipe.
    - **Apprendre et partager** : Échangez des astuces et des tutoriels pour améliorer vos compétences.
    - **Aperçus exclusifs** : Accédez en avant-première aux annonces de nouveaux produits et aux aperçus.
    - **Réductions spéciales** : Profitez de réductions exclusives sur nos produits les plus récents.
    - **Promotions festives et cadeaux** : Participez à des cadeaux et des promotions de vacances.

    👉 Prêt à explorer et à créer avec nous ? Cliquez [|link_sf_facebook|] et rejoignez-nous aujourd'hui !

.. _4.1.10_py_pi5:

4.1.7 Ventilateur Intelligent
=================================

Introduction
----------------

Dans ce projet, nous allons utiliser des moteurs, des boutons et des thermistances 
pour fabriquer un ventilateur intelligent manuel + automatique dont la vitesse du vent est réglable.

Composants nécessaires
---------------------------------

Pour ce projet, nous avons besoin des composants suivants.

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

Il est certainement pratique d'acheter un kit complet, voici le lien :

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

    *   - Nom	
        - ÉLÉMENTS DANS CE KIT
        - LIEN
    *   - Kit Raphael
        - 337
        - |link_Raphael_kit|

Vous pouvez également les acheter séparément via les liens ci-dessous.

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

    *   - INTRODUCTION AUX COMPOSANTS
        - LIEN D'ACHAT

    *   - :ref:`cpn_gpio_extension_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|

Schéma
------------------------

============ ======== ======== ===
Nom T-Board  Physique 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

Procédures Expérimentales
-----------------------------

**Étape 1 :** Construire le circuit.

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

.. note::
    Le module d'alimentation peut utiliser une pile de 9V avec le connecteur de pile 
    9V dans le kit. Insérez le capuchon de cavalier du module d'alimentation dans les 
    bandes de bus 5V de la plaque d'essai.

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

**Étape 2** : Accédez au dossier du code.

.. raw:: html

   <run></run>

.. code-block:: 

    cd ~/raphael-kit/python-pi5

**Étape 3** : Exécutez.

.. raw:: html

   <run></run>

.. code-block:: 

    sudo python3 4.1.10_SmartFan_zero.py

Lorsque le code s'exécute, démarrez le ventilateur en appuyant sur le bouton. 
Chaque fois que vous appuyez, un niveau de vitesse est ajusté vers le haut ou 
vers le bas. Il y a **5** niveaux de vitesse : **0~4**. Lorsqu'il est réglé sur 
la 4\ :sup:`e` vitesse et que vous appuyez sur le bouton, le ventilateur s'arrête 
avec une vitesse du vent de **0**.

Une fois que la température augmente ou diminue de plus de 2℃, la vitesse augmente 
ou diminue automatiquement d'un niveau.

Code
--------

.. note::
    Vous pouvez **Modifier/Réinitialiser/Copier/Exécuter/Arrêter** le code ci-dessous. Mais avant cela, vous devez accéder au chemin du code source comme ``raphael-kit/python-pi5``. Après avoir modifié le code, vous pouvez l'exécuter directement pour voir l'effet.

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



Explication du Code
------------------------

#. Importe des classes pour gérer un moteur et un bouton, et la fonction sleep pour introduire des pauses. De plus, elle importe la bibliothèque ADC0834 pour la mesure de la température et la bibliothèque mathématique pour les calculs.

   .. code-block:: python

       #!/usr/bin/env python3

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

#. Configure le bouton sur la broche GPIO 22 et configure le moteur avec des broches GPIO spécifiques pour le contrôle. Initialise le module ADC0834 pour la mesure de la température. Initialise également des variables pour surveiller le niveau de vitesse du moteur et les températures.

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

#. Définit une fonction pour lire et calculer la température du capteur, convertissant la lecture en 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

#. Introduit une fonction pour ajuster la vitesse du moteur selon le niveau spécifié.

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

#. Implémente une fonction pour changer manuellement le niveau de vitesse du moteur à l'aide d'un bouton, et lie cette fonction à l'événement de pression du bouton.

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

#. La fonction principale, conçue pour ajuster continuellement la vitesse du moteur en réponse aux fluctuations de température, reste à implémenter.

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

#. Exécute la fonction principale et garantit que le moteur s'arrête si le script est interrompu.

   .. code-block:: python

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


