Pilotaggio ventola 12v PC

Ciao a tutti.
Premesso che sono alle mie prime prove con arduino quindi abbiate pazienza :sweat_smile: :sweat_smile:
Dovrei creare la ventilazione per la cabina DIY della mia stampante.
La velocità della ventola dovrebbe essere controllata da arduino in base alla temperatura.
Ho questo sketch:

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
float temp; // set temp as a whole number
int tempPin = A0; //arduino pin used for temperature sensor
int tempMin = 23;  // the temperature to start the buzzer
int tempMax = 25;   // temperature full speed
int fan = 3;       // the pin where fan is connected
int fanSpeed = 0; // fan speed variable
void setup() { 
 pinMode(fan, OUTPUT); // declaring fan pin 6 as output
 pinMode(tempPin, INPUT); // declaring tempPin A0 as input
 lcd.begin(16, 2); // LCD intialize  
 lcd.clear(); // clears lcd
 lcd.print("Fan Speed:"); // prints "Fan Speed" 75-255 PWM
 lcd.setCursor(0,1); // Sets cursor for next line
 lcd.print("Temp:"); // Prints "Temperature" below "Fan Speed"
 Serial.begin(9600); // begins the serial monitor
}
void loop() {
  temp = analogRead(tempPin);
  float voltage = float(5000.0d/1024.0d)*(float)temp;
  float temp = voltage/10.0d; // formula for degrees celcius 
  Serial.println(temp); // prints temp in serial monitor
  lcd.setCursor(12,1); // 12 character to the right on the first column
  lcd.print(temp); // prints the number on the 12 character
  delay(1000);        // delay in between reads for stability
  if(temp < tempMin) {   // if temp is lower than minimum temp
  fanSpeed = 0;      // fan is not spinning
  digitalWrite(fan, LOW); // pin 6 output is low 
   }     
     if((temp >= tempMin) && (temp <= tempMax))  //if temperature is higher than the minimmum range
   { 
    fanSpeed = map(temp, tempMin, tempMax, 75, 255); // the actual speed of fan
    analogWrite(fan, fanSpeed);  // spin the fan at the fanSpeed speed  
    Serial.println(fanSpeed); // prints fan speed in serial monitor
    lcd.setCursor(12,0); // sets cursor
    lcd.print(fanSpeed); // prints 
    lcd.print("  "); // fixes an error of random number display
   } 
   }

Tutto funziona come dovrebbe tranne che quando si raggiunge la temperatura Max la ventola non parte mai a piena velocità resta a valore 168 su 255 e sono erogati 8v invece di 12v.

Qualcuno saprebbe darmi qualche suggerimento su come migliorare lo sketch, ho ache provato con un altro sketch a specificare valore velocità 255 e funziona, in questo caso alla ventola arrivano 12v.

Buongiorno e benvenuto :slight_smile: ,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del regolamento di detta sezione (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione … possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO …

… poi, in conformità al suddetto regolamento, punto 7, devi editare il tuo post qui sopra (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo.

Infine … leggi attentamnete il punto 17.2 del REGOLAMENTO e procedi anche alla corretta formattazione del codice. Grazie.

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sar√† fatta la presentazione nell‚Äôapposito thread e sistemato il codice come da regolamento, nessuno ti potr√† rispondere, quindi ti consiglio di fare il tutto al pi√Ļ presto. :wink:

MI scuso per le mie mancanze :cold_sweat: :cold_sweat: e spero che ora sia tutto a posto.

Come hai collegato la ventola? Metti uno schema con componenti.

Scusa, mi ero perso che leggevi l’output ed era coerente con i V letti.

L’unica cosa che mi viene in mente è che non c’è la condizione
if((temp >= tempMax)

Hai la condizione t< 23, t compreso tra 23 e 25, ma non c’è la conidizione t>25.

Mi viene da pensare che sia colpa del:
delay(1000);

Che ti blocca la lettura e magari in quel secondo la t sale oltre i 25 e allora il loop non fa letteralmente nulla sulla velocità della ventola.

ps: invece di un delay per avere pi√Ļ ‚Äústabilit√†‚ÄĚ, cosa che in realt√† non da, pensa ad una media mobile sulla lettura e ad un‚Äôisteresi sull‚Äôuscita.

pps: la temperatura letta e stampata a schermo, è ragionevole?

Inoltre c'è qualche confusione sui tipi di dati e sulla visibilità delle variabili

Per lo OP

Ma compila? Non ne sarei sicuro

Nel caso non compilasse avremmo spiegato l'arcano

OK, controllato al PC
compila, ci ha messo un'eternità, forse ho qualche problema al PC, forse erano in corso aggiornamenti, ma compila

quindi rimane da capire il problema, che non è, come pensavo io, nella doppia dichiarazione di una variabile float, una globale e una locale, oltretutto fatta "dopo" aver appena usato l'altra....

pessima programmazione, e pessima indentazione, anzi: proprio sbagliata dato che rientri la riga if( di pi√Ļ del corpo della if stessa, eddai, guarda quello che scrivi...

ma comunque il problema non è li

è nell'uso di float per....

e qui, dato che per principio non aiuto chi non indenta il codice, non andrò avanti

però....
se si desse uno sguardo al reference di quello che si usa....

EDIT,
naturalmente DauySleeper ha ragione, ma quello è un altro problema

curiosità:

ma da chi lo hai copiato, il programma?

chi sia sia, in futuro ignoralo, ha fatto la pinmode di un pin analogico....
evita di seguirlo in futuro, ci guadagni

Buona sera e intanto grazie per le risposte.
In allegato schema di collegamento ventola.

daysleeper:
pps: la temperatura letta e stampata a schermo, è ragionevole?

Si di solito è giusta ho già controllato solo ogni tanto ha qualche sbalzo dove sale di qaulche decine di gradi per qualche scondo poi torna normale.

Standardoil:
pessima programmazione, e pessima indentazione, anzi: proprio sbagliata dato che rientri la riga if( di pi√Ļ del corpo della if stessa, eddai, guarda quello che scrivi...

Mi scuso per la forma del del codice che ho caricato...prometto che mi ipergnero per curarla di pi√Ļ :roll_eyes:

Comunque domani farò qualche test poi riferisco.

Standard, a che cosa dovrebbero servire i suffissi "d"? Da che cosa sono rimasti?...
float(5000.0d/1024.0d);

Ah! E' la formula (? ? ?) per i gradi CELCIUS! :ROTFL:

Giusta domanda

Li avevo preso come il suffisso per Double, ma double è il default, non ha suffisso

Forse una estensione gcc?

Comunque il problema è li vicino...

Qui c’è un infinito loop matematico:

  float voltage=float(5000.0d/1024.0d)*(float)temp;
  float temp=voltage/10.0d; // formula for degrees celcius

Domanda per lo OP

Sicuro del consumo della ventola

Non vorrei che il transistor fosse un po’ al limite
Hai misurato a pieno giri?

Ah, e poi, non lo metti un diodo sul motore a proteggere il transistor?

Datman:
Qui c'è un infinito loop matematico:

No, temevo anch'io

Ma invece sembra essere possibile dichiarare una variabile locale dello stesso nome di una globale, anche "dopo" aver usato la globale

√ą una pippa cognitiva, implica non aver capito lo 'scope' delle variabili, ma incredibilmente funziona

Qualche giorno fa c'era uno che faceva la stessa cosa, addirittura con una classe (servo per l'esattezza)
Compilava, anche se poi il servo era inizializzati in una locale e aveva l'interrupt associato ad una globale, quindi non andava

Almeno con gcc, compilato sotto linux, impostazioni di default dello IDE di Arduino quello che fa lo OP, qui, va, incredibile ma va

In altre combinazioni non saprei

E’ vero, sono locali. Però è una complicazione inutile.
Forse così funziona, ma adesso vado a dormire.
Buona notte!

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
#define FAN 3      // the pin where fan is connected
#define SENSOR A0  //arduino pin used for temperature sensor
#define PAUSA 1000 /// Pausa fra una lettura e la successiva.

#define T_MIN 23  // the temperature to start the buzzer
#define T_MAX 25   // temperature full speed

float temp; // set temp as a whole number
byte fanSpeed=0; // fan speed variable
unsigned long t_lettura=0;

void setup()
  {
  pinMode(FAN, OUTPUT);
  pinMode(SENSOR, INPUT);
  lcd.begin(16, 2); // LCD intialize  
  lcd.print("Fan Speed:"); // prints "Fan Speed" 75-255 PWM
  lcd.setCursor(0,1); lcd.print("Temp:");
  Serial.begin(9600); // begins the serial monitor
  legge_e_pilota();
  }

void loop()
  {
  if(millis()-t_lettura>=PAUSA) {t_lettura+=PAUSA; legge_e_pilota();}
  }


void legge_e_pilota()
  {
  analogRead(SENSOR); // Prima lettura, scartata, per migliorare la precisione.
  temp=analogRead(SENSOR)/1024.0*500; // *5000 (5V) /10 (10mV/K)
  Serial.println(temp);
  lcd.setCursor(12,1); lcd.print(temp);
  
  if(temp<T_MIN) // if temp is lower than minimum temp
    {   
    fanSpeed=0;      // fan is not spinning
    }     
  else if(temp<=T_MAX)  //if temperature is higher than the minimmum range
    {
    fanSpeed = map(temp, T_MIN, T_MAX, 75, 255); // the actual speed of fan
    Serial.println(fanSpeed); // prints fan speed in serial monitor
    lcd.setCursor(12,0); lcd.print(fanSpeed); lcd.print("  ");
    }
  else fanSpeed=255;
  analogWrite(FAN, fanSpeed);  // spin the fan at the fanSpeed speed  
  }

Purtroppo no

Non funzionerà nemmeno così

Molto pi√Ļ in ordine

Ma ha lo stesso problema dell'originale

Ci sono le impostazioni del PWM e dell'analog in che non servono, ma possono rimanere senza problemi.

Infatti il problema non è li

Vorrei spiegarmi:

Non sto giocando a "io lo so ma non lo dico"
Che sarebbe un gioco da bambini dell'asilo

Semplicemente sto aspettando che lo OP indenti il codice

Fa parte delle mie regole, in firma:
Non indenti->non ti aiuto

Standardoil:
Domanda per lo OP

Sicuro del consumo della ventola

Non vorrei che il transistor fosse un po' al limite
Hai misurato a pieno giri?

Ah, e poi, non lo metti un diodo sul motore a proteggere il transistor?

Ciao, ho misurato alla massime velocita 30mA, invece sono 80mA a velocità intermedie.

Per il diodo intendi collegato in parallelo alla ventola così?

arduino-temperature-fan-speed-control.png

arduino-temperature-fan-speed-control.png

#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
float temp; // set temp as a whole number
int tempPin = A0; //arduino pin used for temperature sensor
int tempMin = 23;  // the temperature to start the buzzer
int tempMax = 25;   // temperature full speed
int fan = 3;       // the pin where fan is connected
int fanSpeed = 0; // fan speed variable


void setup() {

  pinMode(fan, OUTPUT); // declaring fan pin 6 as output
  pinMode(tempPin, INPUT); // declaring tempPin A0 as input
  lcd.begin(16, 2); // LCD intialize
  lcd.clear(); // clears lcd
  lcd.print("Fan Speed:"); // prints "Fan Speed" 75-255 PWM
  lcd.setCursor(0, 1); // Sets cursor for next line
  lcd.print("Temp:"); // Prints "Temperature" below "Fan Speed"
  Serial.begin(9600); // begins the serial monitor
}


void loop() {
  temp = analogRead(tempPin);
  float voltage = float(5000.0d / 1024.0d) * (float)temp;
  float temp = voltage / 10.0d; // formula for degrees celcius
  Serial.println(temp); // prints temp in serial monitor
  lcd.setCursor(12, 1); // 12 character to the right on the first column
  lcd.print(temp); // prints the number on the 12 character
  delay(1000);        // delay in between reads for stability
  if (temp < tempMin) {  // if temp is lower than minimum temp
    fanSpeed = 0;      // fan is not spinning
    digitalWrite(fan, LOW); // pin 6 output is low
  }

  if ((temp >= tempMin) && (temp <= tempMax)) //if temperature is higher than the minimmum range
  {
    fanSpeed = map(temp, tempMin, tempMax, 75, 255); // the actual speed of fan
    analogWrite(fan, fanSpeed);  // spin the fan at the fanSpeed speed
    Serial.println(fanSpeed); // prints fan speed in serial monitor
    lcd.setCursor(12, 0); // sets cursor
    lcd.print(fanSpeed); // prints
    lcd.print("  "); // fixes an error of random number display
  }
}

Spero che così sia giusto :wink:

Datman:
E’ vero, sono locali. Però è una complicazione inutile.
Forse così funziona, ma adesso vado a dormire.
Buona notte!

#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
#define FAN 3      // the pin where fan is connected
#define SENSOR A0  //arduino pin used for temperature sensor
#define PAUSA 1000 /// Pausa fra una lettura e la successiva.

#define T_MIN 23  // the temperature to start the buzzer
#define T_MAX 25   // temperature full speed

float temp; // set temp as a whole number
byte fanSpeed=0; // fan speed variable
unsigned long t_lettura=0;

void setup()
 {
 pinMode(FAN, OUTPUT);
 pinMode(SENSOR, INPUT);
 lcd.begin(16, 2); // LCD intialize  
¬†lcd.print(‚ÄúFan Speed:‚ÄĚ); // prints ‚ÄúFan Speed‚ÄĚ 75-255 PWM
¬†lcd.setCursor(0,1); lcd.print(‚ÄúTemp:‚ÄĚ);
 Serial.begin(9600); // begins the serial monitor
 legge_e_pilota();
 }

void loop()
 {
 if(millis()-t_lettura>=PAUSA) {t_lettura+=PAUSA; legge_e_pilota();}
 }

void legge_e_pilota()
 {
 analogRead(SENSOR); // Prima lettura, scartata, per migliorare la precisione.
 temp=analogRead(SENSOR)/1024.0*500; // *5000 (5V) /10 (10mV/K)
 Serial.println(temp);
 lcd.setCursor(12,1); lcd.print(temp);
 
 if(temp<T_MIN) // if temp is lower than minimum temp
   {  
   fanSpeed=0;      // fan is not spinning
   }    
 else if(temp<=T_MAX)  //if temperature is higher than the minimmum range
   {
   fanSpeed = map(temp, T_MIN, T_MAX, 75, 255); // the actual speed of fan
   Serial.println(fanSpeed); // prints fan speed in serial monitor
   lcd.setCursor(12,0); lcd.print(fanSpeed); lcd.print("  ");
   }
 else fanSpeed=255;
 analogWrite(FAN, fanSpeed);  // spin the fan at the fanSpeed speed  
 }

Ho provato il tuo sketch e sembra di si!!!
Ora gira al MAX solo che mi servirebbe un range di temperatura pi√Ļ ampio per poter provare meglio‚Ķcos√¨ ho l‚Äôimperssione che usi solo MIN e MAX.
Comunque intanto grazie veramente :smiley: :smiley: