.. note::
Bonjour et bienvenue dans la communauté SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts sur Facebook ! Plongez dans l’univers du Raspberry Pi, d’Arduino et de l’ESP32 avec d’autres passionnés.
**Pourquoi rejoindre ?**
- **Support d’experts** : Résolvez vos problèmes après-vente et vos défis techniques avec l’aide de notre communauté et de notre équipe.
- **Apprendre & partager** : Échangez des astuces et tutoriels pour améliorer vos compétences.
- **Aperçus exclusifs** : Profitez d’un accès anticipé aux annonces et avant-premières de nouveaux produits.
- **Réductions spéciales** : Bénéficiez de remises exclusives sur nos nouveaux produits.
- **Promotions festives et concours** : Participez à des concours et promotions de fêtes.
👉 Prêt(e) à explorer et créer avec nous ? Cliquez sur [|link_sf_facebook|] et rejoignez-nous dès aujourd’hui !
.. _3.1.8_py_pi5_mcp3008:
3.1.8 Moniteur de surchauffe (MCP3008)
======================================
.. note::
.. image:: ../img/mcp3008_and_adc0834.jpg
:width: 25%
:align: left
Selon la version de votre kit, veuillez identifier si vous avez **ADC0834** ou **MCP3008** et suivre la section correspondante.
Introduction
------------
Vous pouvez vouloir créer un dispositif de surveillance de surchauffe adapté à diverses situations, par exemple, en usine, si l’on souhaite déclencher une alarme et arrêter automatiquement la machine lorsqu’un circuit surchauffe.
Dans ce projet, nous allons utiliser une thermistance, un joystick, un buzzer, une LED et un écran LCD pour réaliser un dispositif intelligent de surveillance de température dont le seuil est ajustable.
Composants requis
-----------------
Dans ce projet, nous aurons besoin des composants suivants.
.. image:: ../python_pi5/img/list2_Overheat_Monitor.png
:width: 800
:align: center
Schéma de câblage
-----------------
============ ======== ======== ===
Nom carte T Physique wiringPi BCM
SPICE0 Pin 24 10 8
SPIMOSI Pin 19 12 10
SPIMISO Pin 21 13 9
SPISCLK Pin 23 14 11
GPIO22 Pin15 3 22
GPIO23 Pin16 4 23
GPIO24 Pin18 5 24
SDA1 Pin 3
SCL1 Pin 5
============ ======== ======== ===
.. image:: ../python_pi5/img/schematic_over_monitor_mcp3008.png
:align: center
Procédure expérimentale
-----------------------
**Étape 1 :** Construire le circuit.
.. image:: ../python_pi5/img/july24_3.1.8_overheat_monitor_mcp3008.png
**Étape 2 :** Configurer l’interface SPI et installer la bibliothèque ``spidev`` (voir :ref:`spi_configuration` pour des instructions détaillées). Si vous avez déjà effectué ces étapes, vous pouvez les ignorer.
**Étape 3 :** Aller dans le dossier du code.
.. raw:: html
.. code-block::
cd ~/davinci-kit-for-raspberry-pi/python-pi5
**Étape 4 :** Lancer le fichier exécutable.
.. raw:: html
.. code-block::
sudo python3 3.1.8-2_OverheatMonitor_zero.py
Lorsque le code s’exécute, la température actuelle et le seuil de température élevée **40** s’affichent sur l’écran **I2C LCD1602**.
Si la température actuelle est supérieure au seuil, le buzzer et la LED se déclenchent pour vous alerter.
Le **joystick** est utilisé ici pour ajuster le seuil de température élevée.
En basculant le **joystick** sur l’axe X ou Y, on peut augmenter ou diminuer le seuil actuel.
En appuyant à nouveau sur le **joystick**, on réinitialise le seuil à sa valeur initiale.
.. note::
* Si vous obtenez l’erreur ``FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'``, référez-vous à :ref:`i2c_config` pour activer l’I2C.
* Si vous obtenez ``ModuleNotFoundError: No module named 'smbus2'``, exécutez ``sudo apt install python3-smbus2``.
* Si l’erreur ``OSError: [Errno 121] Remote I/O error`` apparaît, cela signifie que le module est mal câblé ou défectueux.
* Si le code et le câblage sont corrects mais que le LCD n’affiche rien, vous pouvez tourner le potentiomètre à l’arrière pour augmenter le contraste.
.. warning::
Si un message d’erreur apparaît ``RuntimeError: Cannot determine SOC peripheral base address``, veuillez vous référer à :ref:`faq_soc`.
**Code**
--------
.. note::
Vous pouvez **Modifier/Réinitialiser/Copier/Exécuter/Arrêter** le code ci-dessous.
Mais avant cela, vous devez vous placer dans le chemin du code source comme ``davinci-kit-for-raspberry-pi/python``.
Après modification, vous pouvez l’exécuter directement pour voir le résultat.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import LCD1602
from gpiozero import LED, Buzzer, Button
import spidev
import time
import math
# Initialiser le bouton du joystick, le buzzer et la LED
Joy_BtnPin = Button(22) # GPIO22, Pin15
buzzPin = Buzzer(23) # GPIO23, Pin16
ledPin = LED(24) # GPIO24, Pin18
# Seuil initial de température élevée
upperTem = 40
# Initialiser le SPI pour MCP3008 (Bus 0, CE0 -> GPIO8 / Pin24)
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000 # 1 MHz
# Initialiser le LCD (adresse I2C 0x27, rétroéclairage activé)
LCD1602.init(0x27, 1)
def read_adc(channel):
"""
Lire une valeur analogique depuis le MCP3008 (0–7)
"""
if channel < 0 or channel > 7:
return -1
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 0x03) << 8) | adc[2]
return value
def get_joystick_value():
"""
Lit les valeurs du joystick et renvoie une variation en fonction de sa position.
"""
x_val = read_adc(1)
y_val = read_adc(2)
if x_val > 800:
return 1
elif x_val < 200:
return -1
elif y_val > 800:
return -10
elif y_val < 200:
return 10
else:
return 0
def upper_tem_setting():
"""
Ajuste et affiche le seuil de température élevée sur le 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():
"""
Lit la température actuelle depuis le capteur et la renvoie en Celsius.
"""
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0 # Tension à travers la résistance fixe
if Vr == 0:
return 0 # Évite la division par zéro
Rt = 10000.0 * Vr / (3.3 - Vr) # Formule ajustée : tension sur la thermistance = (3.3 - Vr)
temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
Cel = temp - 273.15
return round(Cel, 2)
def monitoring_temp():
"""
Surveille et affiche la température actuelle et le seuil.
Active le buzzer et la LED si la température dépasse la limite.
"""
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()
# Boucle principale
try:
lastState = 1
stage = 0
while True:
currentState = Joy_BtnPin.value
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:
LCD1602.clear()
spi.close()
Explication du code
-------------------
#. Cette section importe les bibliothèques nécessaires. ``LCD1602`` pour l’affichage via I2C, ``gpiozero`` pour la LED, le buzzer et le bouton, ``spidev`` pour communiquer avec le MCP3008, ainsi que ``time`` et ``math`` pour les temporisations et calculs de température.
.. code-block:: python
#!/usr/bin/env python3
import LCD1602
from gpiozero import LED, Buzzer, Button
import spidev
import time
import math
#. Initialise les composants matériels connectés aux broches GPIO :
* ``Button(22)`` pour le bouton du joystick.
* ``Buzzer(23)`` et ``LED(24)`` comme indicateurs en cas de haute température.
.. code-block:: python
Joy_BtnPin = Button(22) # GPIO22, Pin15
buzzPin = Buzzer(23) # GPIO23, Pin16
ledPin = LED(24) # GPIO24, Pin18
#. Définit le seuil initial de température, initialise le SPI pour MCP3008 et l’écran LCD1602.
.. code-block:: python
upperTem = 40
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
LCD1602.init(0x27, 1)
#. ``read_adc(channel)`` lit la valeur analogique d’un canal (0–7) du MCP3008 et renvoie une valeur 10 bits.
.. code-block:: python
def read_adc(channel):
if channel < 0 or channel > 7:
return -1
adc = spi.xfer2([1, (8 + channel) << 4, 0])
value = ((adc[1] & 0x03) << 8) | adc[2]
return value
#. ``get_joystick_value()`` lit la position du joystick et renvoie une valeur de variation selon l’axe X ou Y pour ajuster le seuil.
.. code-block:: python
def get_joystick_value():
x_val = read_adc(1)
y_val = read_adc(2)
if x_val > 800:
return 1
elif x_val < 200:
return -1
elif y_val > 800:
return -10
elif y_val < 200:
return 10
else:
return 0
#. ``upper_tem_setting()`` ajuste le seuil de température via le joystick et l’affiche sur le LCD.
.. code-block:: python
def upper_tem_setting():
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)
#. ``temperature()`` lit la valeur de la thermistance, calcule la tension, la résistance, puis la température en °C via l’approximation Steinhart–Hart.
.. code-block:: python
def temperature():
"""
Reads the current temperature from the sensor and returns it in Celsius.
"""
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0 # Voltage across the fixed resistor
if Vr == 0:
return 0 # Prevent division by zero
Rt = 10000.0 * Vr / (3.3 - Vr) # Adjusted formula: thermistor voltage is (3.3 - Vr)
temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
Cel = temp - 273.15
return round(Cel, 2)
#. ``monitoring_temp()`` compare la température actuelle au seuil et active le buzzer et la LED si elle est dépassée.
.. code-block:: python
def monitoring_temp():
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 principale alterne entre le mode réglage et le mode surveillance grâce au bouton du joystick.
.. code-block:: python
try:
lastState = 1
stage = 0
while True:
currentState = Joy_BtnPin.value
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()
#. Le bloc ``except`` assure l’extinction du LCD et la fermeture du SPI lors de l’interruption du programme.
.. code-block:: python
except KeyboardInterrupt:
LCD1602.clear()
spi.close()