Nota

Ciao, benvenuto nella Community Facebook di appassionati SunFounder Raspberry Pi & Arduino & ESP32! Approfondisci Raspberry Pi, Arduino ed ESP32 con altri appassionati.

Perché unirsi?

  • Supporto esperto: Risolvi problemi post-vendita e sfide tecniche con l’aiuto della nostra community e del nostro team.

  • Impara e condividi: Scambia suggerimenti e tutorial per migliorare le tue competenze.

  • Anteprime esclusive: Ottieni accesso anticipato agli annunci di nuovi prodotti e alle anteprime.

  • Sconti speciali: Goditi sconti esclusivi sui nostri prodotti più recenti.

  • Promozioni festive e giveaway: Partecipa a giveaway e promozioni festive.

👉 Pronto a esplorare e creare con noi? Clicca [Qui] e unisciti oggi stesso!

4.1.7 Ventilatore intelligente (MCP3008)

Nota

../_images/mcp3008_and_adc0834.jpg

A seconda della versione del kit, identifica se hai ADC0834 o MCP3008 e procedi con la sezione corrispondente.

Introduzione

In questo progetto utilizzeremo motori, pulsanti e termistori per realizzare un ventilatore intelligente manuale + automatico, la cui velocità del vento è regolabile.

Componenti richiesti

In questo progetto, abbiamo bisogno dei seguenti componenti.

../_images/list2_Smart_Fan1.png

È sicuramente comodo acquistare un kit completo, ecco il link:

Nome

ARTICOLI IN QUESTO KIT

LINK

Raphael Kit

337

Raphael Kit

Puoi anche acquistarli separatamente dai link sottostanti.

INTRODUZIONE COMPONENTE

LINK DI ACQUISTO

Scheda di estensione GPIO

ACQUISTA

Breadboard

ACQUISTA

Cavi Jumper

ACQUISTA

Resistore

ACQUISTA

Modulo di Alimentazione

-

Termistore

ACQUISTA

L293D

-

MCP3008

-

Pulsante

ACQUISTA

Motore DC

ACQUISTA

Schema elettrico

Nome T-Board

fisico

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

Procedure sperimentali

Passo 1: Costruisci il circuito.

../_images/july24_3.1.4_smart_fan_mcp30081.png

Nota

Il modulo di alimentazione può utilizzare una batteria da 9V con la clip batteria da 9V inclusa nel kit.

../_images/4.1.10_smart_fan_battery.jpeg

Passo 2: Configura l’interfaccia SPI e installa la libreria spidev (vedi Configurazione SPI per istruzioni dettagliate). Se hai già completato questi passaggi, puoi saltarli.

Passo 3: Vai nella cartella del codice.

cd ~/raphael-kit/python-pi5

Passo 4: Esegui.

sudo python3 4.1.10-2_SmartFan_zero.py

Quando il codice è in esecuzione, avvia il ventilatore premendo il pulsante. Ogni volta che lo premi, la velocità aumenta o diminuisce di un livello. Ci sono 5 tipi di velocità: 0~4. Quando è impostata la quarta velocità e premi il pulsante, il ventilatore si ferma con velocità 0.

Una volta che la temperatura aumenta o diminuisce di oltre 2℃, la velocità si regola automaticamente di un livello superiore o inferiore.

Codice

Nota

Puoi Modificare/Resettare/Copiare/Eseguire/Fermare il codice qui sotto. Prima, però, devi andare al percorso del codice sorgente, ad esempio raphael-kit/python-pi5. Dopo aver modificato il codice, puoi eseguirlo direttamente per vederne l’effetto.

#!/usr/bin/env python3

from gpiozero import Motor, Button
from time import sleep
import spidev
import math

# Inizializza SPI per MCP3008
spi = spidev.SpiDev()
spi.open(0, 0)  # Bus 0, CE0 (GPIO8 / pin fisico 24)
spi.max_speed_hz = 1000000  # 1 MHz

# Inizializza GPIO per il pulsante e il controllo del motore
BtnPin = Button(22)  # GPIO22 (pin fisico 15)
motor = Motor(forward=5, backward=6, enable=13)  # GPIO5, GPIO6, GPIO13

# Variabili per tracciare il livello di velocità del motore e le temperature
level = 0
currentTemp = 0
markTemp = 0

def read_adc(channel):
    """
    Legge il valore analogico dal canale 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():
    """
    Legge e calcola la temperatura corrente dal sensore.
    Ritorna:
        float: Temperatura attuale in Celsius.
    """
    analogVal = read_adc(0)  # Termistore collegato a CH0
    Vr = 3.3 * analogVal / 1023.0  # Sistema a 3,3V
    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):
    """
    Regola la velocità del motore in base al livello specificato.
    Argomenti:
        level (int): livello di velocità desiderato.
    Ritorna:
        int: livello di velocità regolato.
    """
    if level == 0:
        motor.stop()
        return 0
    if level >= 4:
        level = 4
    motor.forward(speed=float(level / 4))
    return level

def changeLevel():
    """
    Cambia il livello di velocità del motore quando si preme il pulsante e aggiorna la temperatura di riferimento.
    """
    global level, currentTemp, markTemp
    print("Pulsante premuto")
    level = (level + 1) % 5
    markTemp = currentTemp

# Associa l'evento di pressione del pulsante alla funzione changeLevel
BtnPin.when_pressed = changeLevel

def main():
    """
    Funzione principale per monitorare continuamente e rispondere alle variazioni di temperatura.
    """
    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)

# Esegue la funzione principale e gestisce KeyboardInterrupt
try:
    main()
except KeyboardInterrupt:
    motor.stop()
    spi.close()

Spiegazione del codice

  1. Importa le librerie per il controllo di motore e pulsante, la comunicazione SPI con MCP3008 e i calcoli matematici. gpiozero viene utilizzata per controllare i dispositivi GPIO, spidev per la comunicazione SPI con MCP3008 e math per calcolare la temperatura dalla resistenza.

    from gpiozero import Motor, Button
    from time import sleep
    import spidev
    import math
    
  2. Inizializza la comunicazione SPI sul bus 0, dispositivo 0 (CE0), collegato al chip ADC MCP3008.

    spi = spidev.SpiDev()
    spi.open(0, 0)
    spi.max_speed_hz = 1000000
    
  3. Configura GPIO22 come input per il pulsante e definisce il motore con GPIO5 (avanti), GPIO6 (indietro) e GPIO13 (enable). Dichiara variabili globali per il livello di velocità del motore e il monitoraggio della temperatura.

    BtnPin = Button(22)
    motor = Motor(forward=5, backward=6, enable=13)
    level = 0
    currentTemp = 0
    markTemp = 0
    
  4. Funzione per leggere valori analogici dall’MCP3008 su un canale specificato tramite SPI. Il valore restituito è un numero a 10 bit (0–1023).

    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. Funzione per leggere la temperatura dal termistore. Converte il valore ADC in tensione, calcola la resistenza e poi la temperatura in Celsius usando l’approssimazione Steinhart–Hart.

    def temperature():
        analogVal = read_adc(0)
        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
    
  6. Funzione per controllare la velocità del motore in base al livello (0–4). A livello 0, il motore si ferma; per i livelli 1–4, la velocità PWM viene impostata proporzionalmente.

    def motor_run(level):
        if level == 0:
            motor.stop()
            return 0
        if level >= 4:
            level = 4
        motor.forward(speed=float(level / 4))
        return level
    
  7. Gestore dell’evento del pulsante per incrementare il livello della velocità ciclicamente da 0 a 4. Aggiorna anche la temperatura di riferimento quando cambia il livello.

    def changeLevel():
        global level, currentTemp, markTemp
        level = (level + 1) % 5
        markTemp = currentTemp
    
    BtnPin.when_pressed = changeLevel
    
  8. Logica principale che legge continuamente la temperatura e la confronta con un valore di riferimento (markTemp). Se la differenza di temperatura è ±2°C, il livello di velocità viene regolato di conseguenza. Il motore viene aggiornato in ogni ciclo, con un piccolo ritardo per evitare commutazioni rapide.

    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)
            sleep(0.2)
    
  9. Il programma viene eseguito all’interno di un blocco try-except e garantisce che il motore si fermi e la connessione SPI venga chiusa correttamente in caso di interruzione con Ctrl+C.

    try:
        main()
    except KeyboardInterrupt:
        motor.stop()
        spi.close()