Nota
Ciao, benvenuto nella Community Facebook di appassionati di 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 l’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.10 Ventilatore Intelligente (MCP3008)
Nota
A seconda della versione del tuo 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 con velocità del vento regolabile.
Componenti richiesti
In questo progetto, ci servono i seguenti componenti.
È sicuramente conveniente 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 l’apposito connettore presente nel kit. Inserisci il ponticello del modulo di alimentazione nel bus da 5V della breadboard.
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
Passo 4: Esegui.
sudo python3 4.1.10-2_SmartFan.py
Durante l’esecuzione del codice, avvia il ventilatore premendo il pulsante. Ogni volta che premi, la velocità aumenta o diminuisce di 1 livello. Sono presenti 5 livelli di velocità: 0~4. Quando è impostato il 4° livello di velocità e premi nuovamente il pulsante, il ventilatore si ferma con velocità 0.
Quando la temperatura aumenta o diminuisce di più di 2℃, la velocità cambia automaticamente di 1 livello in più o in meno.
Codice
Nota
Puoi Modificare/Resettare/Copiare/Eseguire/Fermare il codice qui sotto.
Prima però devi andare nel percorso del codice sorgente come raphael-kit/python.
Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l’effetto.
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import spidev
import time
import math
# Configurazione pin
BTN_PIN = 22 # Pulsante GPIO (pin fisico 15)
MOTOR_IN1 = 5 # Motore avanti
MOTOR_IN2 = 6 # Motore indietro
MOTOR_EN = 13 # Pin abilitazione PWM
# Impostazione 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)
# Impostazione PWM per il controllo della velocità del motore
pwm = GPIO.PWM(MOTOR_EN, 1000) # Frequenza 1kHz
pwm.start(0)
# Inizializzazione SPI per MCP3008
spi = spidev.SpiDev()
spi.open(0, 0) # Bus 0, CE0
spi.max_speed_hz = 1000000 # 1 MHz
# Variabili globali
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) # Mappa livello (1–4) a 25%–100%
return level
def changeLevel(channel):
global level, currentTemp, markTemp
print("Pulsante premuto")
level = (level + 1) % 5
markTemp = currentTemp
# Aggiungi rilevamento evento per la pressione del pulsante
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()
Spiegazione del codice
Importa i moduli richiesti:
RPi.GPIOper il controllo GPIO (pulsante e motore),spidevper la comunicazione con l’ADC MCP3008,timeper i ritardi,mathper il calcolo della temperatura con funzioni logaritmiche.
import RPi.GPIO as GPIO import spidev import time import math
Imposta i pin GPIO:
Pulsante su GPIO22 (con pull-up interno),
Controllo motore tramite GPIO5 (avanti), GPIO6 (indietro) e GPIO13 (abilitazione 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)
Inizializza la comunicazione SPI con MCP3008 (Bus 0, CE0) a 1 MHz.
spi = spidev.SpiDev() spi.open(0, 0) spi.max_speed_hz = 1000000
Definisce
read_adc()per leggere un valore analogico a 10 bit (0–1023) dal canale MCP3008 specificato (0–7).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
Definisce
temperature()per:Convertire la tensione analogica in resistenza,
Applicare l’equazione di Steinhart–Hart per calcolare la temperatura in Celsius.
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
Definisce
motor_run()per:Fermare il motore al livello 0,
Far girare il motore in avanti con velocità crescente basata sui livelli 1–4, con duty cycle PWM dal 25% al 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
Definisce la callback
changeLevel()per la pressione del pulsante:Aumenta ciclicamente il livello del motore (0 a 4),
Registra la temperatura corrente come nuovo riferimento.
def changeLevel(channel): global level, currentTemp, markTemp print("Pulsante premuto") level = (level + 1) % 5 markTemp = currentTemp GPIO.add_event_detect(BTN_PIN, GPIO.FALLING, callback=changeLevel, bouncetime=300)
Definisce il ciclo
main()per:Monitorare la variazione di temperatura rispetto al valore di riferimento,
Diminuire la velocità se la temperatura scende di almeno 2°C,
Aumentare la velocità se la temperatura sale di almeno 2°C,
Regolare la velocità del motore ogni 0,2 secondi.
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)
Avvia la funzione principale e garantisce la chiusura corretta con Ctrl+C (ferma il motore, ripulisce i GPIO, chiude la SPI).
try: main() except KeyboardInterrupt: pass finally: pwm.stop() GPIO.cleanup() spi.close()