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
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.
È sicuramente comodo acquistare un kit completo, ecco il link:
Nome |
ARTICOLI IN QUESTO KIT |
LINK |
|---|---|---|
Raphael Kit |
337 |
Puoi anche acquistarli separatamente dai link sottostanti.
INTRODUZIONE COMPONENTE |
LINK DI ACQUISTO |
|---|---|
- |
|
- |
|
- |
|
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 |
Procedure sperimentali
Passo 1: Costruisci il circuito.
Nota
Il modulo di alimentazione può utilizzare una batteria da 9V con la clip batteria da 9V inclusa nel kit.
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
Importa le librerie per il controllo di motore e pulsante, la comunicazione SPI con MCP3008 e i calcoli matematici.
gpiozeroviene utilizzata per controllare i dispositivi GPIO,spidevper la comunicazione SPI con MCP3008 emathper calcolare la temperatura dalla resistenza.from gpiozero import Motor, Button from time import sleep import spidev import math
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
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
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
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
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
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
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)
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()