.. 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_mcp3008:
4.1.10 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 des moteurs, des boutons et des thermistances pour réaliser
un ventilateur intelligent manuel + automatique dont la vitesse de rotation est réglable.
Composants requis
-----------------
Dans ce projet, nous avons besoin des composants suivants :
.. image:: ../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:: ../img/schematic_3.1.4_smart_fan_mcp3008.png
:align: center
Procédure expérimentale
-----------------------
**Étape 1 :** Construire le circuit.
.. image:: ../img/july24_3.1.4_smart_fan_mcp3008.png
.. note::
Le module d’alimentation peut utiliser une pile 9 V avec le connecteur fourni dans le kit.
Insérez le cavalier du module d’alimentation dans les rails 5 V de la breadboard.
.. image:: ../img/image118.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
**Étape 4 :** Exécuter.
.. raw:: html
.. code-block::
sudo python3 4.1.10-2_SmartFan.py
Lorsque le code s’exécute, démarrez le ventilateur en appuyant sur le bouton.
À chaque appui, un niveau de vitesse est augmenté ou diminué.
Il y a **5** niveaux de vitesse : **0 ~ 4**.
Lorsqu’il est réglé au 4\ :sup:`e` niveau et que vous appuyez sur le bouton, le ventilateur s’arrête (vitesse **0**).
Dès que la température monte ou descend de plus de 2 °C, 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``.
Après modification, vous pouvez exécuter directement le code pour voir l’effet.
.. raw:: html
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
import math
# Configuration des broches
BTN_PIN = 22 # Bouton
MOTOR_IN1 = 5 # Moteur avant
MOTOR_IN2 = 6 # Moteur arrière
MOTOR_EN = 13 # Broche PWM
# Configuration GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(MOTOR_IN1, GPIO.OUT)
GPIO.setup(MOTOR_IN2, GPIO.OUT)
GPIO.setup(MOTOR_EN, GPIO.OUT)
# Configuration PWM pour le moteur
pwm = GPIO.PWM(MOTOR_EN, 1000) # 1 kHz
pwm.start(0)
# Initialiser SPI pour MCP3008
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
# Variables globales
level = 0
currentTemp = 0
markTemp = 0
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
def temperature():
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0
Rt = 10000.0 * Vr / (3.3 - Vr)
tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
Cel = tempK - 273.15
return Cel
def motor_run(level):
if level == 0:
GPIO.output(MOTOR_IN1, GPIO.LOW)
GPIO.output(MOTOR_IN2, GPIO.LOW)
pwm.ChangeDutyCycle(0)
return 0
if level >= 4:
level = 4
GPIO.output(MOTOR_IN1, GPIO.HIGH)
GPIO.output(MOTOR_IN2, GPIO.LOW)
pwm.ChangeDutyCycle(level * 25)
return level
def changeLevel(channel):
global level, currentTemp, markTemp
print("Bouton pressé")
level = (level + 1) % 5
markTemp = currentTemp
# Détection de l’événement bouton
GPIO.add_event_detect(BTN_PIN, GPIO.FALLING, callback=changeLevel, bouncetime=300)
def main():
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)
time.sleep(0.2)
try:
main()
except KeyboardInterrupt:
pass
finally:
pwm.stop()
GPIO.cleanup()
spi.close()
Explication du code
-------------------
#. **Importation des modules nécessaires :**
- ``RPi.GPIO`` pour le contrôle GPIO (bouton et moteur)
- ``spidev`` pour communiquer avec le MCP3008
- ``time`` pour la gestion du délai
- ``math`` pour le calcul de la température
.. code-block:: python
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
import math
#. **Configuration des broches :**
- Bouton sur GPIO22 (avec résistance pull-up interne)
- Moteur contrôlé par GPIO5 (avant), GPIO6 (arrière) et GPIO13 (PWM)
.. code-block:: python
BTN_PIN = 22
MOTOR_IN1 = 5
MOTOR_IN2 = 6
MOTOR_EN = 13
GPIO.setmode(GPIO.BCM)
GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(MOTOR_IN1, GPIO.OUT)
GPIO.setup(MOTOR_IN2, GPIO.OUT)
GPIO.setup(MOTOR_EN, GPIO.OUT)
pwm = GPIO.PWM(MOTOR_EN, 1000)
pwm.start(0)
#. **Communication SPI :** Initialisation du bus SPI pour MCP3008 (Bus 0, CE0) à 1 MHz.
.. code-block:: python
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 1000000
#. **Fonction ``read_adc()`` :** Lecture d’une valeur analogique 10 bits (0–1023) d’un canal MCP3008 donné.
.. 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
#. **Fonction ``temperature()`` :** Convertit la tension analogique en résistance puis calcule la température en utilisant l’équation de Steinhart–Hart.
.. code-block:: python
def temperature():
analogVal = read_adc(0)
Vr = 3.3 * analogVal / 1023.0
Rt = 10000.0 * Vr / (3.3 - Vr)
tempK = 1.0 / (((math.log(Rt / 10000.0)) / 3950.0) + (1.0 / (273.15 + 25.0)))
Cel = tempK - 273.15
return Cel
#. **Fonction ``motor_run()`` :**
- Arrête le moteur au niveau 0
- Fait tourner le moteur en avant pour les niveaux 1–4 avec un cycle PWM de 25 % à 100 %.
.. code-block:: python
def motor_run(level):
if level == 0:
GPIO.output(MOTOR_IN1, GPIO.LOW)
GPIO.output(MOTOR_IN2, GPIO.LOW)
pwm.ChangeDutyCycle(0)
return 0
if level >= 4:
level = 4
GPIO.output(MOTOR_IN1, GPIO.HIGH)
GPIO.output(MOTOR_IN2, GPIO.LOW)
pwm.ChangeDutyCycle(level * 25)
return level
#. **Fonction ``changeLevel()`` :**
- Incrémente cycliquement la vitesse du moteur (0 à 4) lors d’un appui sur le bouton
- Enregistre la température actuelle comme référence.
.. code-block:: python
def changeLevel(channel):
global level, currentTemp, markTemp
print("Button pressed")
level = (level + 1) % 5
markTemp = currentTemp
GPIO.add_event_detect(BTN_PIN, GPIO.FALLING, callback=changeLevel, bouncetime=300)
#. **Boucle principale :**
- Surveille la variation de température : baisse ou hausse de plus de 2 °C
- Ajuste la vitesse du moteur d’un niveau vers le bas ou vers le haut
- Met à jour la vitesse toutes les 0,2 s.
.. code-block:: python
def main():
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)
time.sleep(0.2)
#. **Nettoyage (Ctrl+C) :** Arrête le moteur, libère les broches GPIO et ferme SPI proprement.
.. code-block:: python
try:
main()
except KeyboardInterrupt:
pass
finally:
pwm.stop()
GPIO.cleanup()
spi.close()