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 [Ici] et rejoignez‑nous dès aujourd’hui !

4.1.10 Ventilateur intelligent (MCP3008)

Note

../_images/mcp3008_and_adc0834.jpg

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 :

../_images/list2_Smart_Fan.png

Il est évidemment plus pratique d’acheter un kit complet, voici le lien :

Nom

ÉLÉMENTS DANS CE KIT

LIEN

Kit Raphael

337

Raphael Kit

Vous pouvez également les acheter séparément via les liens ci‑dessous :

INTRODUCTION DU COMPOSANT

LIEN D’ACHAT

Carte d’extension GPIO

ACHETER

Plaque d’expérimentation (Breadboard)

ACHETER

Fils de Liaison

ACHETER

Résistance

ACHETER

Module d’Alimentation

-

Thermistance

ACHETER

L293D

-

MCP3008

-

Bouton

ACHETER

Moteur à courant continu

ACHETER

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

../_images/schematic_3.1.4_smart_fan_mcp3008.png

Procédure expérimentale

Étape 1 : Construire le circuit.

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

../_images/image118.jpeg

Étape 2 : Configurer l’interface SPI et installer la bibliothèque spidev (voir Configuration SPI 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.

cd ~/raphael-kit/python

Étape 4 : Exécuter.

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

#!/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

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

    #!/usr/bin/env python3
    
    import RPi.GPIO as GPIO
    import spidev
    import time
    import math
    
  2. Configuration des broches :

    • Bouton sur GPIO22 (avec résistance pull-up interne)

    • Moteur contrôlé par GPIO5 (avant), GPIO6 (arrière) et GPIO13 (PWM)

    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)
    
  3. Communication SPI : Initialisation du bus SPI pour MCP3008 (Bus 0, CE0) à 1 MHz.

    spi = spidev.SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 1000000
    
  4. Fonction ``read_adc()`` : Lecture d’une valeur analogique 10 bits (0–1023) d’un canal MCP3008 donné.

    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
    
  5. Fonction ``temperature()`` : Convertit la tension analogique en résistance puis calcule la température en utilisant l’équation de Steinhart–Hart.

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

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

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

    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)
    
  9. Nettoyage (Ctrl+C) : Arrête le moteur, libère les broches GPIO et ferme SPI proprement.

    try:
        main()
    except KeyboardInterrupt:
        pass
    finally:
        pwm.stop()
        GPIO.cleanup()
        spi.close()