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

4.1.10 Moniteur de surchauffe
================================

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

Vous pourriez vouloir fabriquer un dispositif de surveillance de la surchauffe 
applicable à diverses situations, par exemple, dans une usine, si nous voulons 
avoir une alarme et un arrêt automatique de la machine en cas de surchauffe du 
circuit. Dans ce projet, nous utiliserons une thermistance, un joystick, un buzzer, 
une LED et un LCD pour créer un dispositif intelligent de surveillance de la température 
dont le seuil est réglable.

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

Pour ce projet, nous avons besoin des composants suivants.

.. image:: ../python_pi5/img/4.1.13_overheat_monitor_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_led`
        - |link_led_buy|
    *   - :ref:`cpn_joystick`
        - \-
    *   - :ref:`cpn_adc0834`
        - \-
    *   - :ref:`cpn_transistor`
        - |link_transistor_buy|
    *   - :ref:`cpn_i2c_lcd`
        - |link_i2clcd1602_buy|
    *   - :ref:`cpn_thermistor`
        - |link_thermistor_buy|
    *   - :ref:`cpn_buzzer`
        - \-

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

============ ======== ======== ===
Nom T-Board  Physique wiringPi BCM
GPIO17       Pin 11   0        17
GPIO18       Pin 12   1        18
GPIO27       Pin 13   2        27
GPIO22       Pin15    3        22
GPIO23       Pin16    4        23
GPIO24       Pin18    5        24
SDA1         Pin 3             
SCL1         Pin 5             
============ ======== ======== ===

.. image:: ../python_pi5/img/4.1.13_overheat_monitor_schematic.png
   :align: center

Procédures expérimentales
-----------------------------

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

.. image:: ../python_pi5/img/4.1.13_overheat_monitor_circuit.png


**Étape 2 :** Aller dans le dossier du code.

.. raw:: html

   <run></run>

.. code-block:: 

    cd ~/raphael-kit/python-pi5

**Étape 3 :** Exécuter le fichier exécutable.

.. raw:: html

   <run></run>

.. code-block:: 

    sudo python3 4.1.13_OverheatMonitor_zero.py

Lorsque le code s'exécute, la température actuelle et le seuil de haute 
température **40** s'affichent sur l'écran **I2C LCD1602**. Si la température 
actuelle dépasse le seuil, le buzzer et la LED s'activent pour vous alerter.

Le **joystick** vous permet de régler le seuil de haute température. En le basculant 
dans la direction de l'axe X ou de l'axe Y, vous pouvez augmenter ou diminuer le seuil 
de haute température actuel. Appuyez à nouveau sur le **joystick** pour réinitialiser 
le seuil à sa valeur initiale.

.. note::

    * Si vous obtenez l'erreur ``FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'``, vous devez vous référer à :ref:`i2c_config` pour activer l'I2C.
    * Si vous obtenez l'erreur ``ModuleNotFoundError: No module named 'smbus2'``, veuillez exécuter ``sudo pip3 install smbus2``.
    * Si l'erreur ``OSError: [Errno 121] Remote I/O error`` apparaît, cela signifie que le module est mal câblé ou que le module est défectueux.
    * Si le code et le câblage sont corrects, mais que le LCD n'affiche toujours pas de contenu, vous pouvez tourner le potentiomètre à l'arrière pour augmenter le contraste.

.. warning::

    Si vous recevez le message d'erreur ``RuntimeError: Cannot determine SOC peripheral base address``, veuillez consulter :ref:`faq_soc`

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

   import LCD1602
   from gpiozero import LED, Buzzer, Button
   import ADC0834
   import time
   import math

   # Initialize joystick button, buzzer, and LED
   Joy_BtnPin = Button(22)
   buzzPin = Buzzer(23)
   ledPin = LED(24)

   # Set initial upper temperature threshold
   upperTem = 40

   # Setup ADC and LCD modules
   ADC0834.setup()
   LCD1602.init(0x27, 1)

   def get_joystick_value():
       """
       Reads the joystick values and returns a change value based on the joystick's position.
       """
       x_val = ADC0834.getResult(1)
       y_val = ADC0834.getResult(2)
       if x_val > 200:
           return 1
       elif x_val < 50:
           return -1
       elif y_val > 200:
           return -10
       elif y_val < 50:
           return 10
       else:
           return 0

   def upper_tem_setting():
       """
       Adjusts and displays the upper temperature threshold on the LCD.
       """
       global upperTem
       LCD1602.write(0, 0, 'Upper Adjust: ')
       change = int(get_joystick_value())
       upperTem += change
       strUpperTem = str(upperTem)
       LCD1602.write(0, 1, strUpperTem)
       LCD1602.write(len(strUpperTem), 1, '              ')
       time.sleep(0.1)

   def temperature():
       """
       Reads the current temperature from the sensor and returns it in Celsius.
       """
       analogVal = ADC0834.getResult()
       Vr = 5 * float(analogVal) / 255
       Rt = 10000 * Vr / (5 - Vr)
       temp = 1 / (((math.log(Rt / 10000)) / 3950) + (1 / (273.15 + 25)))
       Cel = temp - 273.15
       return round(Cel, 2)

   def monitoring_temp():
       """
       Monitors and displays the current temperature and upper temperature threshold. 
       Activates buzzer and LED if the temperature exceeds the upper limit.
       """
       global upperTem
       Cel = temperature()
       LCD1602.write(0, 0, 'Temp: ')
       LCD1602.write(0, 1, 'Upper: ')
       LCD1602.write(6, 0, str(Cel))
       LCD1602.write(7, 1, str(upperTem))
       time.sleep(0.1)
       if Cel >= upperTem:
           buzzPin.on()
           ledPin.on()
       else:
           buzzPin.off()
           ledPin.off()

   # Main execution loop
   try:
       lastState = 1
       stage = 0
       while True:
           currentState = Joy_BtnPin.value
           # Toggle between settings and monitoring mode
           if currentState == 1 and lastState == 0:
               stage = (stage + 1) % 2
               time.sleep(0.1)
               LCD1602.clear()
           lastState = currentState
           if stage == 1:
               upper_tem_setting()
           else:
               monitoring_temp()
   except KeyboardInterrupt:
       # Clean up and exit
       LCD1602.clear()
       ADC0834.destroy()


**Explication du code**

#. Cette section importe les bibliothèques nécessaires au projet. ``LCD1602`` est pour l'affichage LCD, ``gpiozero`` fournit des classes pour LED, Buzzer et Button, ``ADC0834`` est pour la conversion analogique-numérique, et ``time`` et ``math`` sont des bibliothèques standard de Python pour les fonctions liées au temps et les opérations mathématiques, respectivement.

   .. code-block:: python

       #!/usr/bin/env python3

       import LCD1602
       from gpiozero import LED, Buzzer, Button
       import ADC0834
       import time
       import math

#. Ici, le bouton du joystick, le buzzer et la LED sont initialisés. ``Button(22)`` crée un objet bouton connecté au GPIO pin 22. ``Buzzer(23)`` et ``LED(24)`` initialisent le buzzer et la LED aux GPIO pins 23 et 24, respectivement.

   .. code-block:: python

       # Initialize joystick button, buzzer, and LED
       Joy_BtnPin = Button(22)
       buzzPin = Buzzer(23)
       ledPin = LED(24)

#. Définit la limite de température supérieure initiale et initialise les modules ADC et LCD. Le LCD est initialisé avec une adresse (``0x27``) et un mode (``1``).

   .. code-block:: python

       # Set initial upper temperature threshold
       upperTem = 40

       # Setup ADC and LCD modules
       ADC0834.setup()
       LCD1602.init(0x27, 1)

#. Cette fonction lit les valeurs du joystick à l'aide d'ADC0834. Elle renvoie une valeur de changement basée sur la position du joystick, qui sera utilisée pour ajuster le seuil de température.

   .. code-block:: python

       def get_joystick_value():
           """
           Reads the joystick values and returns a change value based on the joystick's position.
           """
           x_val = ADC0834.getResult(1)
           y_val = ADC0834.getResult(2)
           if x_val > 200:
               return 1
           elif x_val < 50:
               return -1
           elif y_val > 200:
               return -10
           elif y_val < 50:
               return 10
           else:
               return 0

#. Ajuste la limite de température supérieure en utilisant l'entrée du joystick. La nouvelle limite est affichée sur le LCD.

   .. code-block:: python

       def upper_tem_setting():
           """
           Adjusts and displays the upper temperature threshold on the LCD.
           """
           global upperTem
           LCD1602.write(0, 0, 'Upper Adjust: ')
           change = int(get_joystick_value())
           upperTem += change
           strUpperTem = str(upperTem)
           LCD1602.write(0, 1, strUpperTem)
           LCD1602.write(len(strUpperTem), 1, '              ')
           time.sleep(0.1)

#. Lit la température actuelle du capteur en utilisant ADC0834 et la convertit en Celsius.

   .. code-block:: python

       def temperature():
           """
           Reads the current temperature from the sensor and returns it in Celsius.
           """
           analogVal = ADC0834.getResult()
           Vr = 5 * float(analogVal) / 255
           Rt = 10000 * Vr / (5 - Vr)
           temp = 1 / (((math.log(Rt / 10000)) / 3950) + (1 / (273.15 + 25)))
           Cel = temp - 273.15
           return round(Cel, 2)

#. Surveille et affiche la température actuelle et la limite supérieure. Si la température dépasse la limite supérieure, le buzzer et la LED sont activés.

   .. code-block:: python

       def monitoring_temp():
           """
           Monitors and displays the current temperature and upper temperature threshold. 
           Activates buzzer and LED if the temperature exceeds the upper limit.
           """
           global upperTem
           Cel = temperature()
           LCD1602.write(0, 0, 'Temp: ')
           LCD1602.write(0, 1, 'Upper: ')
           LCD1602.write(6, 0, str(Cel))
           LCD1602.write(7, 1, str(upperTem))
           time.sleep(0.1)
           if Cel >= upperTem:
               buzzPin.on()
               ledPin.on()
           else:
               buzzPin.off()
               ledPin.off()

#. La boucle d'exécution principale alterne entre les modes de réglage et de surveillance en fonction des pressions sur le bouton du joystick. Elle met continuellement à jour soit le réglage de la température, soit surveille la température actuelle.

   .. code-block:: python

       # Main execution loop
       try:
           lastState = 1
           stage = 0
           while True:
               currentState = Joy_BtnPin.value
               # Toggle between settings and monitoring mode
               if currentState == 1 and lastState == 0:
                   stage = (stage + 1) % 2
                   time.sleep(0.1)
                   LCD1602.clear()
               lastState = currentState
               if stage == 1:
                   upper_tem_setting()
               else:
                   monitoring_temp()

#. Cette section assure un nettoyage et une libération appropriés des ressources lorsque le programme est interrompu.

   .. code-block:: python

       except KeyboardInterrupt:
           # Clean up and exit
           LCD1602.clear()
           ADC0834.destroy()