Nota
Ciao, benvenuto nella Community SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! 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: Accedi in anticipo agli annunci dei 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!
3.1.4 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à regolabile.
Componenti necessari
In questo progetto sono necessari i seguenti componenti.
È sicuramente conveniente acquistare un kit completo, ecco il link:
Nome |
ELEMENTI IN QUESTO KIT |
LINK |
|---|---|---|
Kit Raphael |
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: Monta il circuito.
Nota
Il modulo di alimentazione può utilizzare una batteria da 9V con il connettore per batteria 9V incluso nel kit. Inserisci il ponticello del modulo di alimentazione nel bus a 5V della breadboard.
Passo 2: Entra nella cartella del codice.
cd ~/raphael-kit/c/3.1.4-2/
Passo 3: Compila.
gcc 3.1.4_SmartFan.c -o SmartFan -lwiringPi -lm
Passo 4: Esegui il file eseguibile sopra.
./SmartFan
Quando il codice è in esecuzione, avvia il ventilatore premendo il pulsante. Ogni volta che premi, la velocità aumenta o diminuisce di 1 livello. Sono disponibili 5 livelli di velocità: 0~4. Quando è impostata la 4a velocità e premi il pulsante, il ventilatore si ferma con velocità 0.
Una volta che la temperatura sale o scende di oltre 2℃, la velocità viene automaticamente aumentata o diminuita di un livello.
Nota
Se non funziona dopo l’esecuzione o compare un errore del tipo: "wiringPi.h: No such file or directory", fai riferimento a Installazione e verifica di WiringPi.
Codice
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <stdio.h>
#include <softPwm.h>
#include <math.h>
#define SPI_CHANNEL 0
#define SPI_SPEED 1000000
#define MotorPin1 21
#define MotorPin2 22
#define MotorEnable 23
#define BtnPin 3
int read_ADC(int channel)
{
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1; // Bit di avvio
buffer[1] = (8 + channel) << 4; // Modalità single-ended e canale
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int result = ((buffer[1] & 3) << 8) | buffer[2];
return result;
}
int temperture()
{
int analogVal = read_ADC(0);
double Vr = 3.3 * analogVal / 1023.0; // Usa 3.3V come Vref per MCP3008
double Rt = 10000.0 * Vr / (3.3 - Vr);
double temp = 1 / (((log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)));
double cel = temp - 273.15;
double Fah = cel * 1.8 + 32;
printf("Celsius: %.2f C Fahrenheit: %.2f F\n", cel, Fah);
return (int)cel;
}
int motor(int level)
{
if (level == 0) {
digitalWrite(MotorEnable, LOW);
return 0;
}
if (level >= 4) {
level = 4;
}
digitalWrite(MotorEnable, HIGH);
softPwmWrite(MotorPin1, level * 25);
return level;
}
void setup()
{
if (wiringPiSetup() == -1) {
printf("setup wiringPi fallito!\n");
return;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("setup SPI fallito!\n");
return;
}
softPwmCreate(MotorPin1, 0, 100);
softPwmCreate(MotorPin2, 0, 100);
pinMode(MotorEnable, OUTPUT);
pinMode(BtnPin, INPUT);
}
int main(void)
{
setup();
int currentState, lastState = 0;
int level = 0;
int currentTemp, markTemp = 0;
while (1) {
currentState = digitalRead(BtnPin);
currentTemp = temperture();
if (currentTemp <= 0) continue;
if (currentState == 1 && lastState == 0) {
level = (level + 1) % 5;
markTemp = currentTemp;
delay(500);
}
lastState = currentState;
if (level != 0) {
if (currentTemp - markTemp <= -2) {
level = level - 1;
markTemp = currentTemp;
}
if (currentTemp - markTemp >= 2) {
level = level + 1;
markTemp = currentTemp;
}
}
level = motor(level);
}
return 0;
}
Spiegazione del codice
int read_ADC(int channel)
{
if (channel < 0 || channel > 7) return -1;
unsigned char buffer[3];
buffer[0] = 1; // Bit di avvio
buffer[1] = (8 + channel) << 4; // Modalità single-ended e canale
buffer[2] = 0;
wiringPiSPIDataRW(SPI_CHANNEL, buffer, 3);
int result = ((buffer[1] & 3) << 8) | buffer[2];
return result;
}
Questa funzione legge l’ingresso analogico dal MCP3008 sul canale specificato. Invia un comando SPI di 3 byte e restituisce un valore digitale a 10 bit compreso tra 0 e 1023.
int temperture()
{
int analogVal = read_ADC(0);
double Vr = 3.3 * analogVal / 1023.0; // Usa 3.3V come Vref per MCP3008
double Rt = 10000.0 * Vr / (3.3 - Vr);
double temp = 1 / (((log(Rt / 10000.0)) / 3950.0) + (1 / (273.15 + 25.0)));
double cel = temp - 273.15;
double Fah = cel * 1.8 + 32;
printf("Celsius: %.2f C Fahrenheit: %.2f F\n", cel, Fah);
return (int)cel;
}
La funzione temperture() legge il segnale analogico del termistore tramite MCP3008, calcola tensione e resistenza, quindi converte in gradi Celsius e Fahrenheit utilizzando la formula del termistore (approssimazione Steinhart–Hart).
int motor(int level)
{
if (level == 0) {
digitalWrite(MotorEnable, LOW);
return 0;
}
if (level >= 4) {
level = 4;
}
digitalWrite(MotorEnable, HIGH);
softPwmWrite(MotorPin1, level * 25);
return level;
}
La funzione motor() controlla la velocità del ventilatore tramite PWM.
Il livello varia da 0 a 4, dove 0 spegne il ventilatore e ciascun livello aumenta il duty cycle del 25%.
void setup()
{
if (wiringPiSetup() == -1) {
printf("setup wiringPi fallito!\n");
return;
}
if (wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED) == -1) {
printf("setup SPI fallito!\n");
return;
}
softPwmCreate(MotorPin1, 0, 100);
softPwmCreate(MotorPin2, 0, 100);
pinMode(MotorEnable, OUTPUT);
pinMode(BtnPin, INPUT);
}
La funzione setup() inizializza WiringPi, configura SPI, imposta PWM e i pin GPIO necessari per il controllo del motore e la lettura del pulsante.
int main(void)
{
setup();
int currentState, lastState = 0;
int level = 0;
int currentTemp, markTemp = 0;
while (1) {
currentState = digitalRead(BtnPin);
currentTemp = temperture();
if (currentTemp <= 0) continue;
if (currentState == 1 && lastState == 0) {
level = (level + 1) % 5;
markTemp = currentTemp;
delay(500);
}
lastState = currentState;
if (level != 0) {
if (currentTemp - markTemp <= -2) {
level = level - 1;
markTemp = currentTemp;
}
if (currentTemp - markTemp >= 2) {
level = level + 1;
markTemp = currentTemp;
}
}
level = motor(level);
}
return 0;
}
La funzione main() contiene il ciclo del programma:
Controlla continuamente lo stato del pulsante e legge la temperatura corrente.
Alla pressione del pulsante, il livello della ventola aumenta (cicli 0–4) e salva la temperatura.
Se la temperatura varia di ±2°C, la velocità della ventola viene regolata automaticamente.
Chiama
motor(level)per aggiornare l’uscita PWM in base al livello corrente.