.. note::
Bonjour et bienvenue dans la communauté SunFounder Raspberry Pi & Arduino & ESP32 sur Facebook !
Plongez plus profondément dans l’univers 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 :** Obtenez un accès anticipé aux annonces de nouveaux produits et aux avant‑premières.
- **Réductions spéciales :** Profitez de remises exclusives sur nos derniers produits.
- **Promotions et concours festifs :** Participez à des concours et promotions de vacances.
👉 Prêt à explorer et créer avec nous ? Cliquez sur [|link_sf_facebook|] et rejoignez‑nous dès aujourd’hui !
.. _4.1.10_py_pi5_mcp3008:
4.1.7 Ventilateur intelligent (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
------------
Dans ce projet, nous utiliserons un moteur, un bouton et une thermistance pour créer
un ventilateur intelligent, manuel + automatique, dont la vitesse est réglable.
Composants requis
-----------------
Dans ce projet, nous avons besoin des composants suivants :
.. image:: ../python_pi5/img/list2_Smart_Fan.png
:width: 800
:align: center
Il est évidemment plus 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 DU COMPOSANT
- 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_mcp3008`
- \-
* - :ref:`cpn_button`
- |link_button_buy|
* - :ref:`cpn_motor`
- |link_motor_buy|
Schéma
------
============ ======== ======== ===
Nom T-Board physique wiringPi BCM
SPICE0 Pin 24 10 8
SPIMOSI Pin 19 12 10
SPIMISO Pin 21 13 9
SPISCLK Pin 23 14 11
GPIO22 Pin 15 3 22
GPIO5 Pin 29 21 5
GPIO6 Pin 31 22 6
GPIO13 Pin 33 23 13
============ ======== ======== ===
.. image:: ../python_pi5/img/schematic_3.1.4_smart_fan_mcp3008.png
:align: center
:width: 800
Procédure expérimentale
-----------------------
**Étape 1 :** Construire le circuit.
.. image:: ../python_pi5/img/july24_3.1.4_smart_fan_mcp3008.png
:width: 800
.. note::
Le module d’alimentation peut utiliser une pile 9 V avec l’attache 9 V fournie dans le kit.
.. image:: ../python_pi5/img/4.1.10_smart_fan_battery.jpeg
:align: center
**É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 :** Accéder au dossier du code.
.. raw:: html
.. code-block::
cd ~/raphael-kit/python-pi5
**Étape 4 :** Exécuter.
.. raw:: html
.. code-block::
sudo python3 4.1.10-2_SmartFan_zero.py
Une fois le code exécuté, démarrez le ventilateur en appuyant sur le bouton.
Chaque pression modifie la vitesse d’un niveau. Il existe **5** vitesses : **0 ~ 4**.
Si la vitesse est à 4 et que vous appuyez de nouveau sur le bouton,
le ventilateur s’arrête (**0**).
Dès que la température varie 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 aller dans le chemin du code source comme ``raphael-kit/python-pi5``.
Après modification, vous pouvez exécuter directement le code pour voir l’effet.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import Motor, Button
from time import sleep
import spidev
import math
# Initialisation SPI pour MCP3008
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CE0 (GPIO8 / pin physique 24)
spi.max_speed_hz = 1000000 # 1 MHz
# Initialisation du bouton et du moteur
BtnPin = Button(22) # GPIO22 (pin physique 15)
motor = Motor(forward=5, backward=6, enable=13) # GPIO5, GPIO6, GPIO13
# Variables globales
level = 0
currentTemp = 0
markTemp = 0
def read_adc(channel):
"""
Lit la valeur analogique du canal 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 temperature():
"""
Lit et calcule la température en °C depuis le capteur.
"""
analogVal = read_adc(0) # Thermistance connectée à CH0
Vr = 3.3 * analogVal / 1023.0
Rt = 10000.0 * Vr / (3.3 - Vr)
temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
Cel = temp - 273.15
return Cel
def motor_run(level):
"""
Ajuste la vitesse du moteur selon le niveau.
"""
if level == 0:
motor.stop()
return 0
if level >= 4:
level = 4
motor.forward(speed=float(level / 4))
return level
def changeLevel():
"""
Change la vitesse du moteur lors d’un appui sur le bouton
et met à jour la température de référence.
"""
global level, currentTemp, markTemp
print("Bouton appuyé")
level = (level + 1) % 5
markTemp = currentTemp
# Associer l’événement du bouton à la fonction
BtnPin.when_pressed = changeLevel
def main():
"""
Fonction principale : surveille la température et ajuste la vitesse.
"""
global level, currentTemp, markTemp
markTemp = temperature()
while True:
currentTemp = temperature()
if level != 0:
if currentTemp - markTemp <= -2:
level -= 1
markTemp = currentTemp
elif currentTemp - markTemp >= 2:
if level < 4:
level += 1
markTemp = currentTemp
level = motor_run(level)
sleep(0.2)
try:
main()
except KeyboardInterrupt:
motor.stop()
spi.close()
Explication du code
-------------------
#. **Importation des bibliothèques** : ``gpiozero`` pour contrôler le moteur et le bouton,
``spidev`` pour la communication SPI avec MCP3008 et ``math`` pour les calculs de température.
.. code-block:: python
#!/usr/bin/env python3
from gpiozero import Motor, Button
from time import sleep
import spidev
import math
#. **Initialisation SPI** : bus 0, périphérique 0 (CE0), vitesse de 1 MHz.
.. code-block:: python
# Initialize SPI for MCP3008
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CE0 (GPIO8 / physical pin 24)
spi.max_speed_hz = 1000000 # 1 MHz
#. **Configuration des E/S** : GPIO22 comme entrée bouton, moteur configuré avec GPIO5 (avant), GPIO6 (arrière) et GPIO13 (PWM).
.. code-block:: python
# Initialize GPIO pins for the button and motor control
BtnPin = Button(22) # GPIO22 (physical pin 15)
motor = Motor(forward=5, backward=6, enable=13) # GPIO5, GPIO6, GPIO13
# Initialize variables to track the motor speed level and temperatures
level = 0
currentTemp = 0
markTemp = 0
#. **Lecture ADC** : fonction ``read_adc()`` pour obtenir la valeur analogique (0–1023).
.. code-block:: python
def read_adc(channel):
"""
Reads analog value from MCP3008 channel (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
#. **Température** : fonction ``temperature()`` qui calcule la température en Celsius via l’équation de Steinhart–Hart.
.. code-block:: python
def temperature():
"""
Reads and calculates the current temperature from the sensor.
Returns:
float: The current temperature in Celsius.
"""
analogVal = read_adc(0) # Assuming thermistor connected to CH0
Vr = 3.3 * analogVal / 1023.0 # For 3.3V system
Rt = 10000.0 * Vr / (3.3 - Vr)
temp = 1 / (((math.log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)))
Cel = temp - 273.15
return Cel
#. **Contrôle du moteur** : fonction ``motor_run()`` qui ajuste la vitesse selon le niveau (0–4).
.. 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.
"""
if level == 0:
motor.stop()
return 0
if level >= 4:
level = 4
motor.forward(speed=float(level / 4))
return level
#. **Gestion du bouton** : fonction ``changeLevel()`` pour changer le niveau et actualiser la température de référence.
.. 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")
level = (level + 1) % 5
markTemp = currentTemp
# Bind the button press event to changeLevel function
BtnPin.when_pressed = changeLevel
#. **Boucle principale** : ajuste automatiquement la vitesse si la température varie de ±2 °C.
.. code-block:: python
def main():
"""
Main function to continuously monitor and respond to temperature changes.
"""
global level, currentTemp, markTemp
markTemp = temperature()
while True:
currentTemp = temperature()
if level != 0:
if currentTemp - markTemp <= -2:
level -= 1
markTemp = currentTemp
elif currentTemp - markTemp >= 2:
if level < 4:
level += 1
markTemp = currentTemp
level = motor_run(level)
sleep(0.2)
#. **Gestion des interruptions** : arrête le moteur et ferme la connexion SPI lors de Ctrl+C.
.. code-block:: python
# Run the main function and handle KeyboardInterrupt
try:
main()
except KeyboardInterrupt:
motor.stop()
spi.close()