Se sei già registrato           oppure    

Orario: 25/04/2024 21:54:35  

 

Energia Alternativa ed Energia Fai Da Te > Arduino

VISUALIZZA L'ALBUM

Pagine: (5)   [1]   2   3   4   5    (Ultimo Msg)


Termostato con isteresi regolabile
FinePagina

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 26/06/2017 23:40:56

Semplice progettino di termometro con isteresi regolabile.
La temperatura di centro soglia è regolabile con i tastini + e - mentre l'isteresi, date le mie scarse capacità è regolabile solo in fase di programmazione nelle righe 80 e 85.
Se qualcuno è in grado di perfezionarlo con tastini per regolare l'isteresi e scriverla sul display sarebbe il massimo.


#include <LiquidCrystal.h>
#define on 6                                   // led verde o relay NA
#define off 7                                 // led rosso o relay NC
#define tempP 9                               // pulsante temperatura + resistenza da 2200 a massa
#define tempM 8                               // pulsante temperatura - resistenza da 2200 a massa
#define LM35 A1                               // piedino centrale sensore temp. LM35 
 
float vref = 1.1;                            // ADC 1,1V
int tempSoglia = 25;                         //soglia default all'accensione
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);       // lcd LiquidCrystal D2=D7 D3=D6 D4=D5 D5=D4 D11=E D12=RS VDD=+5 VO=centrale potenziometro A=+3V K,VSS,RW=massa 
 
void setup()
{
 analogReference(INTERNAL);                  // ADC interno 1,1V 
 analogRead(LM35); 
 pinMode(on,OUTPUT);
 pinMode(off,OUTPUT);
 pinMode(tempP,INPUT);
 pinMode(tempM,INPUT);
 
 lcd.begin(20,4);                            //lcd 20 colonne 4 righe
 lcd.setCursor(5,0);
 lcd.print("Termostato");
 lcd.setCursor(6,1);
 lcd.print("Digitale");
 lcd.setCursor(8,3);
 lcd.print("Start");
 
 delay(3000);
}
 
void loop()
{
 float temp = readTemp(); 
 LCD(temp);               
 
 if(digitalRead(tempM) == LOW){ tempSoglia--; } 
 if(digitalRead(tempP) == LOW){ tempSoglia++; } 
}
 

float readTemp()
{
 float temp = 0.0;           
 int val = 1; 
 int nread = 5; 
 float somma = 0.0; 
 
 for (int i=0; i<nread; i++)
 {
 val = analogRead(LM35); 
 temp = (86.0 * vref * val)/1024.0;  
 somma += temp; 
 }
 return ( somma / nread ); 
}
 
 
void LCD( float temp )
{
 lcd.clear(); 
 lcd.setCursor(0,0); 
 lcd.print("Temperatura  ");
 lcd.print(temp,1); 
 //lcd.print(' '); 
 lcd.print((char)223); 
 //lcd.print('C');
 
 lcd.setCursor(0,2); 
 lcd.print("Centro Soglia ");
 //lcd.print(' '); 
 lcd.print(tempSoglia); 
 lcd.print((char)223); 
 
 
 if(temp < tempSoglia-0.3)               //soglia inferiore -
 {
 digitalWrite(on, HIGH);
 digitalWrite(off, LOW);
 }
 if(temp > tempSoglia+0.3)              //soglia superiore +
 {
 digitalWrite(on, LOW);
 digitalWrite(off, HIGH);
 }
 delay(2000); 
 }




Immagine Allegata: Termostato.jpg
 
ForumEA/R/Termostato.jpg


Scarica allegato

Termostato_con_isteresi_variabile.ino ( Numero download: 370 )



Modificato da BellaEli - 27/06/2017, 01:29:20


---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 27/06/2017 02:01:15

Vecchio Volpone...


#include <LiquidCrystal.h>
#define on 6                                  // Led Verde o Relay NA
#define off 7                                 // Led Rosso o Relay NC
#define tempP 9                               // Pulsante Temperatura "+", Resistenza da 2.200 a massa
#define tempM 8                               // Pulsante Temperatura "-", Resistenza da 2.200 a massa
#define isterP 10                             // Pulsante Isterisi "+", Resistenza da 2.200 a massa
#define isterM 13                             // Pulsante Isterisi "-", Resistenza da 2.200 a massa
#define LM35 A1                               // Piedino centrale sensore temp. LM35

float vref = 1.1;                             // ADC 1,1V
float isteresi = 0.3;                         // Isteresi del termostato
float tempSoglia = 25.0;                      // Soglia default all'accensione
unsigned long T_Ultima_Lettura, T_Attuale;    // Variabili per le pause senza blocco dei processi
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);        // LCD LiquidCrystal D2=D7 D3=D6 D4=D5 D5=D4 D11=E D12=RS VDD=+5 VO=centrale potenziometro A=+3V K,VSS,RW=massa


void setup()
{
  analogReference(INTERNAL);                  // ADC interno 1,1V
  analogRead(LM35);
  pinMode(on, OUTPUT);
  pinMode(off, OUTPUT);
  pinMode(tempP, INPUT);
  pinMode(tempM, INPUT);

  lcd.begin(20, 4);                           // LCD 20 Colonne, 4 Righe
  lcd.setCursor(5, 0);
  lcd.print("Termostato");
  lcd.setCursor(6, 1);
  lcd.print("Digitale");
  lcd.setCursor(8, 4);
  lcd.print("Start");

  delay(3000);
}


void loop()
{
  float temp;

  T_Attuale = millis();
  if (T_Attuale - T_Ultima_Lettura > 1000)    // Attendo 1 secondo
  {
    temp = readTemp();                        // Leggo la temperatura
    attivaRele(temp);                         // Setto i relè
    T_Ultima_Lettura = T_Attuale;
  }
  
  LCD(temp);                                  // Scrivo sull'LCD

  if(digitalRead(tempM) == LOW)               // Modifica Temperatura Centro Soglia
  {
    tempSoglia--;
    delay(200);
  }
  if(digitalRead(tempP) == LOW)
  {
    tempSoglia++;
    delay(200);
  }

  
  if(digitalRead(isterM) == LOW && isteresi > 0.1)        // Modifica Isteresi (da +/- 0,1 a +/- 5 °C)
  {
    isteresi = isteresi - 0.1;
    delay(200);
  }
  
  if(digitalRead(isterP) == LOW && isteresi < 5.0)
  {
    isteresi = isteresi + 0.1;
    delay(200);
  }

}



float readTemp()                              // Leggo la temperatura facendo la media di 10 letture
{
  float temp;
  float somma = 0.0;
  int i, val;
  int nread = 10;
 
  for (i = 0; i < nread; i++)
  {
    val = analogRead(LM35);
    temp = (86.0 * vref * (float)val) / 1024.0;
    somma += temp;
    delay(10);
  }
  return (somma / (float)nread);
}


void LCD(float temp)                          // Scrivo i valori sull'LCD
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temperat.: ");
  lcd.print(temp, 1);
  lcd.print(' ');
  lcd.print((char)223);
  lcd.print('C');

  lcd.setCursor(0,2);
  lcd.print("Centro Soglia: ");
  lcd.print(tempSoglia);
  lcd.print((char)223);
  lcd.print('C');

  lcd.setCursor(0,3);
  lcd.print("Isteresi: ");
  lcd.print(isteresi);
  lcd.print(' ');
  lcd.print((char)223);
  lcd.print('C');
}


void attivaRele(float temp)                        // Imposto i relè
{
  if(temp < tempSoglia - isteresi)            // Soglia Inferiore -
  {
    digitalWrite(on, HIGH);
    digitalWrite(off, LOW);
  }
  if(temp > tempSoglia + isteresi)            // Soglia Superiore +
  {
    digitalWrite(on, LOW);
    digitalWrite(off, HIGH);
  }
}


Ovviamente è solo scritto col PC, è da debbuggare e sicuro ci sarà qualche piccolo errorino... domani se ne parla !

Elix



Modificato da BellaEli - 27/06/2017, 02:32:13


---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 27/06/2017 09:19:13

Ci sono 3 punti su cui ho dubbi.

1) I pulsanti devono essere collegati tra pin e massa quindi la R va tra pin e Vcc;

2) Il centro soglia non ha limiti,ovvero è settabile tra - 32.000 e + 32.000 circa, che limiti mettiamo ? 0..99 ???

3) Ora i pulsanti risponderanno bene, saranno reattivi e sarà semplice impostare le soglie ma il display lampeggerà continuamente per l'lcd.clear(): per risolvere questo problema devo fare qualche prova pratica...

Ma il termostato a cosa ti serve ???



---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 27/06/2017 09:52:30

CITAZIONE (BellaEli, 27/06/2017 09:19:13 ) Discussione.php?214676&1#MSG2

Ci sono 3 punti su cui ho dubbi.

1) I pulsanti devono essere collegati tra pin e massa quindi la R va tra pin e Vcc;


Si

CITAZIONE (BellaEli, 27/06/2017 09:19:13 ) Discussione.php?214676&1#MSG2


2) Il centro soglia non ha limiti,ovvero è settabile tra - 32.000 e + 32.000 circa, che limiti mettiamo ? 0..99 ???


Io non metterei limiti alla fantasia l'LM35 fa -55° +150°

CITAZIONE (BellaEli, 27/06/2017 09:19:13 ) Discussione.php?214676&1#MSG2


3) Ora i pulsanti risponderanno bene, saranno reattivi e sarà semplice impostare le soglie ma il display lampeggerà continuamente per l'lcd.clear(): per risolvere questo problema devo fare qualche prova pratica...



Il punto che non riesco a sistemare è il delay riga 90, tempo fra una lettura a l'altra, che obbliga anche i tastini, cioè per cambiare bisogna tenerli premuti per il tempo impostato.

CITAZIONE (BellaEli, 27/06/2017 09:19:13 ) Discussione.php?214676&1#MSG2


Ma il termostato a cosa ti serve ???


Serve ad ogni uso, perché in commercio si trovano termostati ma hanno l'isteresi fissa e a volte è poco o a volte è troppo.



Modificato da Claudio - 27/06/2017, 09:58:43


---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 27/06/2017 09:59:20


CITAZIONE

...Io non metterei limiti...

Come no ??? Non ha senso, vanno messi, immagina di acquistare un'autovettura e di trovare il contachilometri che va da -32.000 a +32.000 cosa penseresti ?
Questo: "Ma che cagata hanno fatto ???" !!!
Io credo che 0..99 sia un buon range... anche perchè non tutti gli LM35 superano i 100 °C, quindi...

Mi cambi il messaggio mentre scrivo...
-55 + 150 in teoria potrebbe anche andar bene ma occorre tener conto che non tutti gli LM35 hanno quel range, solo quelli con una specifica lettera dopo il 35 e, in ogni caso, per farlo funzionare su temperature negative è necessario un circuito di condizionamento con alimentazione duale oltre l'offset per spostare le tensioni negative sopra 0 Volt e permettere all'ADC di funzionare, inoltre occorre modificare il riferimento dell'ADC... insomma si tratterebbe proprio di stravolgere tutto lo schema e il codice del termostato...
Secondo me al massimo ci possiamo spingere tra 0...110 °C, anche se ho i miei dubbi che lo schema adottato dia delle letture precise ai limiti del range...
Se dovessi ottimizzare farei 10..90 !

CITAZIONE
Il punto che non riesco a sistemare è il delay riga 90, tempo fra una lettura a l'altra, che obbliga anche i tastini, cioè per cambiare bisogna tenerli premuti per il tempo impostato.

No, no, questa cosa è già sistemata nel nuovo codice che ho postato, se lo carichi e fai una prova a volo ti renderai subito conto...
Solo che il display sembrerà lampeggiare...



Modificato da BellaEli - 27/06/2017, 10:12:38


---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 27/06/2017 10:20:42

Scusa per il cambio in corsa.

Grazie Elix ci guardo appena rientro.

Cambio gomme moto.



---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 27/06/2017 10:37:24

Pensavo ad un altro dettaglio: nonostante la bassa isteresi impostabile (solo 0,1 ºC) il centro soglia ha step di 1 ºC: che dici lo spostiamo a 0,1 ???



---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 27/06/2017 16:23:00

Ma no un decimo di grado sarebbe troppo fine, a meno che venga usato per misurare acido per sviluppo fotografico, ma anche lì per comodità si va a gradi non a decimi.

Funziona sia regolazione soglia che isteresi ma continua a lampeggiare la prima riga.

http://www.energialternativa.info/Public/NewForum/ForumEA/R/elix-1.mp4



Modificato da BellaEli - 27/06/2017, 16:32:01


---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 27/06/2017 16:57:33

Si, si... era indispensabile testare il software, è quasi impossibile che funzioni a primo colpo senza debug !!!

Ho implementato parecchie migliorie, ora è un signor termostato:

http://www.energialternativa.info/public/newforum/ForumEA/R/Dsc_0011.jpg




Elenco delle caratteristiche:

- Range Temperatura Rilevabile: 0,0...110,0 °C, Risoluzione: 0,1 °C;
- Range Temperatura Impostabile: 10,0...90,0 °C, Risoluzione: 0,1 °C;
- Range Isteresi Impostabile: 0,1...25,0 °C, Risoluzione: 0,1 °C

Visualizzazione della temperatura letta, impostata, isteresi e stato relè oltre ad una piccola animazione che ci permette di capire se il termostato sta funzionando.

Le soglie impostate (Temperatura e Isteresi) vengono salvate nella Eprom del micro quindi se si resetta, se va via la corrente o se si spegne il termostato alla riaccensione vengono ripristinate le precedenti soglie.

La lettura dell'LM35 viene effettuata mediante una media di 10 letture intervallate da una pausa di 10 mS, quindi ogni singola lettura dura circa 100 mS, riducendo al minimo errori di lettura e stabilizzando il valore di temperatura letta.

Le letture vengono effettuate ogni 500 mS, quindi, al superamento di una soglia, il tempo di intervento massimo del termostato è di circa 600 mS.

Il codice è scritto per rendere semplice la variazione delle soglie, ovvero non ci sono strane attese tra la pressione del tasto e la modifica del dato.

E' stata curata, inoltre, la stabilità della visualizzazione delle scritte sul display.

Per i pulsanti ho utilizzato l'inizializzazione INPUT_PULLUP, ovvero non serve la resistenza da 2.200 OHM verso VCC.

Questo il codice:


#include <LiquidCrystal.h>                                      // Per display normale
#include <LiquidCrystal_I2C.h>                                  // Per display I2C
#include <EEPROM.h>                                             // Per memorizzare le soglie nella EPROM di Arduino
#define on 6                                                    // Led Verde o Relay NA
#define off 7                                                   // Led Rosso o Relay NC
#define tempP 9                                                 // Pulsante Temperatura "+"
#define tempM 8                                                 // Pulsante Temperatura "-"
#define isterP 10                                               // Pulsante Isterisi "+"
#define isterM 13                                               // Pulsante Isterisi "-"
#define LM35 A1                                                 // Piedino centrale sensore temp. LM35

int i;                                                          // variabile per cicli for
int nread = 10;                                                 // Numero di letture effettuate dall'ADC
int power;                                                      // Variabile per lampeggio puntino di running del termostato
int rele = 0;                                                   // Variabile di stato dei relè: 0 = OFF, 1 = ON
int byte0, byte1;                                               // Variabili usate per scrivere/leggere nella Eprom
float vref = 1.1;                                               // ADC 1,1V
int isteresi;                                                   // Isteresi del termostato: lavoro con int (moltiplicati per 10) per evitare errori di arrotondamenti sui float
int tempSoglia;                                                 // Temperatura di Soglia: lavoro con int (moltiplicati per 10) per evitare errori di arrotondamenti sui float
float tempLetta;
unsigned long T_Ultima_Lettura, T_Attuale;                      // Variabili per le pause senza blocco dei processi
byte newChar[8] = { B00100, B00100, B11111, B00100,             // Carattere personalizzato ±
                    B00100, B00000, B11111, B00000 }; 
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);                          // LCD LiquidCrystal D2=D7 - D3=D6 - D4=D5 - D5=D4 - D11=E - D12=RS - VDD=+5 - VO=centrale potenziometro - A=+3V K, VSS, RW=massa
LiquidCrystal_I2C lcd(0x27, 16, 4);                             // Per display I2C



void setup()
{
  pinMode(on, OUTPUT);                                          // Inizializzo i Pin
  pinMode(off, OUTPUT);
  pinMode(tempP, INPUT_PULLUP);
  pinMode(tempM, INPUT_PULLUP);
  pinMode(isterP, INPUT_PULLUP);
  pinMode(isterM, INPUT_PULLUP);
  analogReference(INTERNAL);                                    // Setto il riferimento per l'ADC al valore interno di 1,1V
  tempLetta = (100.0 * vref * (float)analogRead(LM35)) / 1024.0; // Leggo la Temperatura


  // Leggo la Temperatura Impostata nella Eprom
  byte0 = EEPROM.read(0);
  byte1 = EEPROM.read(1);
  tempSoglia = (byte1<<8) | byte0;                                // Somma logica del valore di Byte1 spostato a sinistra di 8 bit e di Byte0
  if (tempSoglia < 100 || tempSoglia > 900) tempSoglia = 250;


  // Leggo l'Isteresi Impostata nella Eprom (Ho lasciato 2 Byte nel caso si volesse settare un'steresi maggiore di 25,5 °C)
  byte0 = EEPROM.read(2);
  byte1 = EEPROM.read(3);
  isteresi = (byte1<<8) | byte0;                                // Somma logica del valore di Byte1 spostato a sinistra di 8 bit e di Byte0
  if (isteresi < 1 || isteresi > 250) isteresi = 3;


  // Per display LCD 20 Colonne, 4 Righe, I2C
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  lcd.createChar(0, newChar); 



  // Per display LCD 20 Colonne, 4 Righe, normale
  // lcd.begin(20, 4);


  // Schermata di avvio del termostato
  lcd.setCursor(5, 0);
  lcd.print("Termostato");
  lcd.setCursor(6, 1);
  lcd.print("Digitale");
  lcd.setCursor(5, 3);
  lcd.print("Start");
  delay(500);
  for (i = 0; i < 5; i++)
  {
    lcd.print(".");
    delay(500);
  }


  // Setto le scritte statiche
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("T. Letta:    ");
  lcd.print(tempLetta, 1);
  lcd.print(" ");
  lcd.print((char)223);
  lcd.print("C");

  lcd.setCursor(0,1);
  lcd.print("Rele':");
  
  lcd.setCursor(0,2);
  lcd.print("T. Impost.:  ");
  lcd.print((float)tempSoglia/10, 1);
  lcd.print(' ');
  lcd.print((char)223);
  lcd.print('C');

  lcd.setCursor(0,3);
  lcd.print("Isteresi  ");
  lcd.write(0);
  lcd.print(":  ");
  lcd.print((float)isteresi/10, 1);
  lcd.print(' ');
  lcd.print((char)223);
  lcd.print('C');
}



void loop()
{
  float temp;

  T_Attuale = millis();
  if (T_Attuale - T_Ultima_Lettura > 500)                      // Attendo 1 secondo
  {
    readTemp();                                                 // Leggo la temperatura
    attivaRele();                                               // Setto i relè
    LCD(0);                                                     // Aggiorno i valori sull'LCD
    T_Ultima_Lettura = T_Attuale;
  }

  // Modifica Temperatura Centro Soglia da 10 a 90 °C
  if(digitalRead(tempM) == LOW && tempSoglia > 100)
  {
    tempSoglia--;
    LCD(1);                                                     // Scrivo sull'LCD
    
    // Salvo il valore nella Eprom
    byte0 = tempSoglia & 255;                                   // Con un prodotto logico per 255 ottengo gli 8 bit meno significativi
    byte1 = (tempSoglia >> 8) & 255;                            // Con uno spostamento a sinistra ed il prodotto logico ottengo gli 8 bit più significativi
    EEPROM.write(0, byte0);
    EEPROM.write(1, byte1);

    delay(150);
  }
  if(digitalRead(tempP) == LOW && tempSoglia < 900)
  {
    tempSoglia++;
    LCD(1);                                                     // Scrivo sull'LCD
    
    // Salvo il valore nella Eprom
    byte0 = tempSoglia & 255;                                   // Con un prodotto logico per 255 ottengo gli 8 bit meno significativi
    byte1 = (tempSoglia >> 8) & 255;                            // Con uno spostamento a sinistra ed il prodotto logico ottengo gli 8 bit più significativi
    EEPROM.write(0, byte0);
    EEPROM.write(1, byte1);

    delay(150);
  }

  // Modifica Isteresi (da +/- 0,1 a +/- 25 °C)
  if(digitalRead(isterM) == LOW && isteresi > 1)
  {
    isteresi--;
    LCD(2);                                                     // Scrivo sull'LCD
    
    // Salvo il valore nella Eprom
    byte0 = isteresi & 255;                                     // Con un prodotto logico per 255 ottengo gli 8 bit meno significativi
    byte1 = (isteresi >> 8) & 255;                              // Con uno spostamento a sinistra ed il prodotto logico ottengo gli 8 bit più significativi
    EEPROM.write(2, byte0);
    EEPROM.write(3, byte1);

    delay(150);
  }
  
  if(digitalRead(isterP) == LOW && isteresi < 250)
  {
    isteresi++;
    LCD(2);                                                     // Scrivo sull'LCD
    
    // Salvo il valore nella Eprom
    byte0 = isteresi & 255;                                     // Con un prodotto logico per 255 ottengo gli 8 bit meno significativi
    byte1 = (isteresi >> 8) & 255;                              // Con uno spostamento a sinistra ed il prodotto logico ottengo gli 8 bit più significativi
    EEPROM.write(2, byte0);
    EEPROM.write(3, byte1);

    delay(150);
  }

}



void readTemp()                                                 // Leggo la temperatura facendo la media di 10 letture
{
  float temp;
  float somma = 0.0;
  int i, val;
 
  for (i = 0; i < nread; i++)
  {
    temp = (100.0 * vref * (float)analogRead(LM35)) / 1024.0;
    somma += temp;
    delay(10);
  }
  tempLetta = somma / (float)nread;
}


void LCD(int valore)                                            // Scrivo i valori sull'LCD
{
  switch (valore) {
    case 1:
      lcd.setCursor(13,2);
      lcd.print((float)tempSoglia/10, 1);
      break;

    case 2:
      lcd.setCursor(13,3);
      if (isteresi < 100) lcd.print(" ");
      lcd.print((float)isteresi/10, 1);
    break;

    case 3:
      lcd.setCursor(7,1);
      if (rele == 0) lcd.print("OFF");
      else lcd.print("ON ");
    break;

    default:
      lcd.setCursor(12,0);
      if (tempLetta < 10.0) lcd.print("  ");
      else if (tempLetta < 100.0) lcd.print(" ");
      lcd.print(tempLetta, 1);

      switch (power)
      {
      case 0:
        lcd.setCursor(14,1);
        lcd.print("- ----");
        power = 1;
        break;
      case 1:
        lcd.setCursor(15,1);
        lcd.print("- ");
        power = 2;
        break;
      case 2:
        lcd.setCursor(16,1);
        lcd.print("- ");
        power = 3;
        break;
      case 3:
        lcd.setCursor(17,1);
        lcd.print("- ");
        power = 4;
        break;
      case 4:
        lcd.setCursor(17,1);
        lcd.print(" -");
        power = 5;
        break;
      case 5:
        lcd.setCursor(16,1);
        lcd.print(" -");
        power = 6;
        break;
      case 6:
        lcd.setCursor(15,1);
        lcd.print(" -");
        power = 1;
        break;
      }
    break;
  }
}


void attivaRele()                                                         // Imposto i relè
{
  if(tempLetta < (float)tempSoglia/10 - (float)isteresi/10)               // Soglia Inferiore -
  {
    digitalWrite(on, HIGH);
    digitalWrite(off, LOW);
    rele = 0;
    LCD(3);
  }
  if(tempLetta > (float)tempSoglia/10 + (float)isteresi/10)               // Soglia Superiore +
  {
    digitalWrite(on, LOW);
    digitalWrite(off, HIGH);
    rele = 1;
    LCD(3);
  }
}



Io ho lavorato sul display 20x4 I2C, per l'altro display occorre modificare qualche linea per inizializzare l'altro display, ho solamente commentato le righe che non mi servivano.

Prr qualsiasi dubbio sono qui !

Elix



---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 27/06/2017 17:10:21

Wellaaa anche lo stato del relay!!!!

Lo provo subito!!!



---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 27/06/2017 17:28:51

Perfetto ho fermato le righe per l'uso del display I2C e ho abilitato quelle per il normale, domanda quindi può funzionare anche con il display Oled?? ora provo.



---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 27/06/2017 17:46:23

No, verrebbe tutto troppo piccolo, ultima versione perfetta, grande.
Faccine/Smileys_0006.gif



---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 27/06/2017 18:30:34

Ma io non ho capito una cosa: ti sai muovere all'interno del codice ? Cioè sai fare piccole modifiche tipo modificare i pin, soglie, etc. ?
Ti è semplice collegare relè, pulsanti, display al codice scritto ?

Altra domanda, perchè nella formula di conversione dell'LM35 c'era questo calcolo:

(86.0 * 1,1 * analogRead(LM35)) / 1024.0

anzichè questo:

(100.0 * 1,1 * analogRead(LM35)) / 1024.0

???

Ciè è come se quella formula l'hai presa da un codice dove l'uscita dell'LM35 veniva mandata ad un partitore che riduceva la tensione di uscita allྒ % ...

Potrei ipotizzare che qualcuno, volendo arrivare fino a 150 °C, abbia messo un partitore sull'uscita dell'LM35 ma in quel caso lྒ sarebbe dovuto essere 73,3, ovvero a 150 °C il partitore avrebbe dovuto tirar fuori una tensione del 73,3 %, ovvero 1,1 Volt che l'ADC avrebbe letto correttamente senza problemi...

Con 86.0 potrei pensare che a bastavano circa 128 °C ...

Boh, comunque è venuto fuori davvero un bel termostato !

Elix



---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

BellaEli

Avatar
GigaWatt


Gruppo:MODERATORE
Messaggi:3286

Stato:



Inviato il: 27/06/2017 18:41:08

Piccola correzione:


#include <LiquidCrystal.h>                                      // Per display normale
#include <LiquidCrystal_I2C.h>                                  // Per display I2C
#include <EEPROM.h>                                             // Per memorizzare le soglie nella EPROM di Arduino
#define on 6                                                    // Led Verde o Relay NA
#define off 7                                                   // Led Rosso o Relay NC
#define tempP 9                                                 // Pulsante Temperatura "+"
#define tempM 8                                                 // Pulsante Temperatura "-"
#define isterP 10                                               // Pulsante Isterisi "+"
#define isterM 13                                               // Pulsante Isterisi "-"
#define LM35 A1                                                 // Piedino centrale sensore temp. LM35

int i;                                                          // variabile per cicli for
int nread = 10;                                                 // Numero di letture effettuate dall'ADC
int power;                                                      // Variabile per lampeggio puntino di running del termostato
int rele = 0;                                                   // Variabile di stato dei relè: 0 = OFF, 1 = ON
int byte0, byte1;                                               // Variabili usate per scrivere/leggere nella Eprom
float vref = 1.1;                                               // ADC 1,1V
int isteresi;                                                   // Isteresi del termostato: lavoro con int (moltiplicati per 10) per evitare errori di arrotondamenti sui float
int tempSoglia;                                                 // Temperatura di Soglia: lavoro con int (moltiplicati per 10) per evitare errori di arrotondamenti sui float
float tempLetta;
unsigned long T_Ultima_Lettura, T_Attuale;                      // Variabili per le pause senza blocco dei processi
byte newChar[8] = { B00100, B00100, B11111, B00100,             // Carattere personalizzato ±
                    B00100, B00000, B11111, B00000 }; 
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);                          // LCD LiquidCrystal D2=D7 - D3=D6 - D4=D5 - D5=D4 - D11=E - D12=RS - VDD=+5 - VO=centrale potenziometro - A=+3V K, VSS, RW=massa
LiquidCrystal_I2C lcd(0x27, 16, 4);                             // Per display I2C



void setup()
{
  pinMode(on, OUTPUT);                                          // Inizializzo i Pin
  pinMode(off, OUTPUT);
  pinMode(tempP, INPUT_PULLUP);
  pinMode(tempM, INPUT_PULLUP);
  pinMode(isterP, INPUT_PULLUP);
  pinMode(isterM, INPUT_PULLUP);
  analogReference(INTERNAL);                                    // Setto il riferimento per l'ADC al valore interno di 1,1V
  tempLetta = (100.0 * vref * (float)analogRead(LM35)) / 1024.0; // Leggo la Temperatura


  // Leggo la Temperatura Impostata nella Eprom
  byte0 = EEPROM.read(0);
  byte1 = EEPROM.read(1);
  tempSoglia = (byte1<<8) | byte0;                                // Somma logica del valore di Byte1 spostato a sinistra di 8 bit e di Byte0
  if (tempSoglia < 100 || tempSoglia > 900) tempSoglia = 250;


  // Leggo l'Isteresi Impostata nella Eprom (Ho lasciato 2 Byte nel caso si volesse settare un'steresi maggiore di 25,5 °C)
  byte0 = EEPROM.read(2);
  byte1 = EEPROM.read(3);
  isteresi = (byte1<<8) | byte0;                                // Somma logica del valore di Byte1 spostato a sinistra di 8 bit e di Byte0
  if (isteresi < 1 || isteresi > 250) isteresi = 3;


  // Per display LCD 20 Colonne, 4 Righe, I2C
  lcd.begin();
  lcd.backlight();
  lcd.clear();
  lcd.createChar(0, newChar); 



  // Per display LCD 20 Colonne, 4 Righe, normale
  // lcd.begin(20, 4);


  // Schermata di avvio del termostato
  lcd.setCursor(5, 0);
  lcd.print("Termostato");
  lcd.setCursor(6, 1);
  lcd.print("Digitale");
  lcd.setCursor(5, 3);
  lcd.print("Start");
  delay(500);
  for (i = 0; i < 5; i++)
  {
    lcd.print(".");
    delay(500);
  }


  // Setto le scritte statiche
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("T. Letta:    ");
  lcd.print(tempLetta, 1);
  lcd.setCursor(18,0);
  lcd.print((char)223);
  lcd.print("C");

  lcd.setCursor(0,1);
  lcd.print("Rele':");
  
  lcd.setCursor(0,2);
  lcd.print("T. Impost.:  ");
  lcd.print((float)tempSoglia/10, 1);
  lcd.print(' ');
  lcd.print((char)223);
  lcd.print('C');

  lcd.setCursor(0,3);
  lcd.print("Isteresi  ");
  lcd.write(0);
  lcd.print(":  ");
  lcd.print((float)isteresi/10, 1);
  lcd.print(' ');
  lcd.print((char)223);
  lcd.print('C');
}



void loop()
{
  float temp;

  T_Attuale = millis();
  if (T_Attuale - T_Ultima_Lettura > 500)                      // Attendo 1 secondo
  {
    readTemp();                                                 // Leggo la temperatura
    attivaRele();                                               // Setto i relè
    LCD(0);                                                     // Aggiorno i valori sull'LCD
    T_Ultima_Lettura = T_Attuale;
  }

  // Modifica Temperatura Centro Soglia da 10 a 90 °C
  if(digitalRead(tempM) == LOW && tempSoglia > 100)
  {
    tempSoglia--;
    LCD(1);                                                     // Scrivo sull'LCD
    
    // Salvo il valore nella Eprom
    byte0 = tempSoglia & 255;                                   // Con un prodotto logico per 255 ottengo gli 8 bit meno significativi
    byte1 = (tempSoglia >> 8) & 255;                            // Con uno spostamento a sinistra ed il prodotto logico ottengo gli 8 bit più significativi
    EEPROM.write(0, byte0);
    EEPROM.write(1, byte1);

    delay(150);
  }
  if(digitalRead(tempP) == LOW && tempSoglia < 900)
  {
    tempSoglia++;
    LCD(1);                                                     // Scrivo sull'LCD
    
    // Salvo il valore nella Eprom
    byte0 = tempSoglia & 255;                                   // Con un prodotto logico per 255 ottengo gli 8 bit meno significativi
    byte1 = (tempSoglia >> 8) & 255;                            // Con uno spostamento a sinistra ed il prodotto logico ottengo gli 8 bit più significativi
    EEPROM.write(0, byte0);
    EEPROM.write(1, byte1);

    delay(150);
  }

  // Modifica Isteresi (da +/- 0,1 a +/- 25 °C)
  if(digitalRead(isterM) == LOW && isteresi > 1)
  {
    isteresi--;
    LCD(2);                                                     // Scrivo sull'LCD
    
    // Salvo il valore nella Eprom
    byte0 = isteresi & 255;                                     // Con un prodotto logico per 255 ottengo gli 8 bit meno significativi
    byte1 = (isteresi >> 8) & 255;                              // Con uno spostamento a sinistra ed il prodotto logico ottengo gli 8 bit più significativi
    EEPROM.write(2, byte0);
    EEPROM.write(3, byte1);

    delay(150);
  }
  
  if(digitalRead(isterP) == LOW && isteresi < 250)
  {
    isteresi++;
    LCD(2);                                                     // Scrivo sull'LCD
    
    // Salvo il valore nella Eprom
    byte0 = isteresi & 255;                                     // Con un prodotto logico per 255 ottengo gli 8 bit meno significativi
    byte1 = (isteresi >> 8) & 255;                              // Con uno spostamento a sinistra ed il prodotto logico ottengo gli 8 bit più significativi
    EEPROM.write(2, byte0);
    EEPROM.write(3, byte1);

    delay(150);
  }

}



void readTemp()                                                 // Leggo la temperatura facendo la media di 10 letture
{
  float temp;
  float somma = 0.0;
  int i, val;
 
  for (i = 0; i < nread; i++)
  {
    temp = (100.0 * vref * (float)analogRead(LM35)) / 1024.0;
    somma += temp;
    delay(10);
  }
  tempLetta = somma / (float)nread;
}


void LCD(int valore)                                            // Scrivo i valori sull'LCD
{
  switch (valore) {
    case 1:
      lcd.setCursor(13,2);
      lcd.print((float)tempSoglia/10, 1);
      break;

    case 2:
      lcd.setCursor(13,3);
      if (isteresi < 100) lcd.print(" ");
      lcd.print((float)isteresi/10, 1);
    break;

    case 3:
      lcd.setCursor(7,1);
      if (rele == 0) lcd.print("OFF");
      else lcd.print("ON ");
    break;

    default:
      lcd.setCursor(12,0);
      if (tempLetta < 10.0) lcd.print("  ");
      else if (tempLetta < 100.0) lcd.print(" ");
      lcd.print(tempLetta, 1);

      switch (power)
      {
      case 0:
        lcd.setCursor(14,1);
        lcd.print("- ----");
        power = 1;
        break;
      case 1:
        lcd.setCursor(15,1);
        lcd.print("- ");
        power = 2;
        break;
      case 2:
        lcd.setCursor(16,1);
        lcd.print("- ");
        power = 3;
        break;
      case 3:
        lcd.setCursor(17,1);
        lcd.print("- ");
        power = 4;
        break;
      case 4:
        lcd.setCursor(17,1);
        lcd.print(" -");
        power = 5;
        break;
      case 5:
        lcd.setCursor(16,1);
        lcd.print(" -");
        power = 6;
        break;
      case 6:
        lcd.setCursor(15,1);
        lcd.print(" -");
        power = 1;
        break;
      }
    break;
  }
}


void attivaRele()                                                         // Imposto i relè
{
  if(tempLetta < (float)tempSoglia/10 - (float)isteresi/10)               // Soglia Inferiore -
  {
    digitalWrite(on, HIGH);
    digitalWrite(off, LOW);
    rele = 0;
    LCD(3);
  }
  if(tempLetta > (float)tempSoglia/10 + (float)isteresi/10)               // Soglia Superiore +
  {
    digitalWrite(on, LOW);
    digitalWrite(off, HIGH);
    rele = 1;
    LCD(3);
  }
}



---------------
C'è un limite al fai da te ???
Si, ma lo stabiliamo noi !!!

 

Claudio

Avatar
PetaWatt


Gruppo:MODERATORE
Messaggi:15097

Stato:



Inviato il: 27/06/2017 19:22:09

Avevo messo 86 per tararlo con la temperatura che segnava un termometro in casa, e ho visto che mettendo 86 segnavano pari temperatura.

Elix io vado per tentativi, ne so proprio poco, sto impegnando al massimo quei 4 neuroni ancora collegati fra loro, gli altri non rispondono più.



---------------
Inverter Sofar Solar HYD6000-EP, 5250W pannelli, 14kWh lifepo4.

 
 InizioPagina
 

Pagine: (5)   [1]   2   3   4   5    (Ultimo Msg)

Versione Mobile!

Home page       TOP100-SOLAR      Home page forum