Doppio LOOP

Salve. ho creato un termostato con arudino per la mia caldaia. mi piace come sistema domani gli prendo una mille fori e lo faccio standalone in scatola.
unica pecca volevo fagli fare la lettura della temperatura in tempi piu ritardati tipo 10-20 secondi… pero qui ce il problmema…c’è il set-up della temperatura che funziona con 2 tasti…UP–DOWN… e quando premo UP il valore impostato mi viene visualizzato dopo i 20 secondi… visto che ho messo il delay prima della lettura della temperatura… come potrei separare tale funzione con tempi diversi? la lettura che me la faccia dai 10 secondi in su… il resto refresh display e altro 1-2 secondi
per rendervi l’idea ecco lo skech:

#include <LiquidCrystal.h>
//LCD SetUp
#define RS  12
#define EN  11
#define D7  5  
#define D6  4
#define D5  3
#define D4  2
#define off 7
#define on  6
#define tempP  9
#define tempM  8


#define LM35_pin 2

float vref = 1.1;                       
float tempC;
int tempSoglia = 20;
int reading;

LiquidCrystal lcd( RS, EN, D7, D6, D5, D4 );

void setup() 
{
  lcd.begin( 4, 20 );           
  lcd.setCursor( 0, 0 );
  pinMode(13, OUTPUT);
  
  
  analogReference( INTERNAL ); 
  analogRead( LM35_pin );      
  
   
  pinMode(off, OUTPUT);
  pinMode(on, OUTPUT);
   
  pinMode(tempP, INPUT);
  pinMode(tempM, INPUT);
   
  pinMode(13, OUTPUT);
  
  delay(200);
 //test
  lcd.setCursor( 0, 0 );     
  lcd.print( "......:WELCOME:.....");
  lcd.setCursor( 0, 1 );     
  lcd.print( "........:TEST:......");
  lcd.setCursor( 0, 2 );   
  lcd.print( "........:TEST:......");
  
  
  delay(1000);
  digitalWrite(on, HIGH);
  digitalWrite(off, LOW);
  digitalWrite(13, HIGH);
  lcd.setCursor( 0, 3 );
  lcd.print( "....RUN......RUN....");
  
  delay(1500);
  
  digitalWrite(off, HIGH);
  digitalWrite(on, LOW);
  digitalWrite(13, LOW);
  lcd.setCursor( 0, 3 );
  lcd.print( "....OFF......OFF....");
  
  delay(2000);
  lcd.clear();
  digitalWrite(off, LOW);
  digitalWrite(on, LOW);
  digitalWrite(13, LOW);
    
  delay(1000);
}

void loop()
{
  
  float temp = readTemp(); 
  sendTempToLCD( temp );   
   
  if(digitalRead(tempM) == HIGH){ tempSoglia--; }
  if(digitalRead(tempP) == HIGH){ tempSoglia++; }
   
}

float readTemp()
{
  tempC = analogRead(LM35_pin);       
tempC = (5.0 * tempC * 100)/1024.0; 
reading = analogRead(LM35_pin);
tempC = reading / 10.0; 
}

void sendTempToLCD( float temp )
{
  lcd.clear();               
  lcd.setCursor( 0, 0 );    
  lcd.print( "......:WELCOME:.....");
  lcd.setCursor( 0, 1 );     
  lcd.print( "Temp READ:");
  lcd.setCursor( 11, 1 );     
  lcd.print( temp );         
  lcd.print( ' ' );          
  lcd.print( (char) 223 );   
  lcd.print( 'C' );
  lcd.setCursor( 0, 2 );
  lcd.print( "Temp SET: ");
  lcd.print( ' ' );            
  lcd.print(tempSoglia);
  lcd.print( ".00 " );          
  lcd.print( (char) 223 );   
  lcd.print( 'C' );

  if(temp <= tempSoglia){
    digitalWrite(on, HIGH);
    digitalWrite(off, LOW);
    delay(500);
    lcd.setCursor( 0, 3 );
    lcd.print( "....RUN......RUN....");
    digitalWrite(13, HIGH);
  }else{
    digitalWrite(off, HIGH);
    digitalWrite(on, LOW);
    delay(500);
    digitalWrite(13, LOW);
    lcd.setCursor( 0, 3 );
    lcd.print( "....OFF......OFF....");
  }
   
    delay(500);
   
}

Impara ad eliminare la delay() (… che è una istruzione “bloccante”) ed al suo posto introduci l’utilizzo della millis() (… che ti permette di mettere in piedi una logica NON bloccante).

Studiati come fare QUI, poi QUI ed infine un esempio QUI.

Inizia con qualche cosa di semplice, per capire bene come fare e poi, appresa bene la tecnica, applica il tutto al tuo programma :wink:

Guglielmo

Cosa é attacato al pin 13?
Ciao Uwe

uwefed:
Cosa é attacato al pin 13?

Mmm … il LED di Arduino ? ? ? :grin: :grin: :grin:

Guglielmo

Forse dovresti imparare le basi di programmazione. Nel Tuo Sketch ci sono un po di cose insensate.

analogRead( LM35_pin );   
...
tempC = analogRead(LM35_pin);       
tempC = (5.0 * tempC * 100)/1024.0; 
reading = analogRead(LM35_pin);
tempC = reading / 10.0; 
...

Il comutare le uscite nel setup() lo interpreto come test dello Sketch che sparirá nella versione finale.

Ciao Uwe

:slight_smile: grazie. Ora mi metto a studiarle.
Al pin 13 ce ataccata la base di un transitor NPN che mi pilota il relè della caldaia. uso il 13 per vedere l'inidicatore led di arduino che sta funzionando

uwefed:
Forse dovresti imparare le basi di programmazione. Nel Tuo Sketch ci sono un po di cose insensate.

analogRead( LM35_pin );   

...
tempC = analogRead(LM35_pin);     
tempC = (5.0 * tempC * 100)/1024.0;
reading = analogRead(LM35_pin);
tempC = reading / 10.0;
...




Il comutare le uscite nel setup() lo interpreto come test dello Sketch che sparirá nella versione finale.

Ciao Uwe

non capisco... mi pui fare una versione finale dello Sketch e poi ti dico cosa ho interpretato io

mitidj2008:
:slight_smile: grazie. Ora mi metto a studiarle.
Al pin 13 ce ataccata la base di un transitor NPN che mi pilota il relè della caldaia. uso il 13 per vedere l'inidicatore led di arduino che sta funzionando

Sul pin 13 c'é attacato un LED che viene acceso durante l'acensione del Arduino dal Bootloader. È meglio che usi un altro pin per il relé.
Ciao Uwe

E qui e strano che da quando è uscito IDE 1.0 non lo fa più arduino sta cosa del led ed e molto più veloce nel avvio. come se non ci fosse il boot loader

Quando colleghi a scheda spenta l'Arduino al computer il bootloader non viene eseguito ma parte direttamente lo sketch presente in memoria. Solo se resetti la scheda, senza scollegarla dall'alimentazione, parte il bootloader.

insomma alla fine non mi e stato detto nulla sulla domanda del TOPIC :slight_smile:
Come faccio un doppio(o più) loop con tempi diversi?

Ti ho risposto QUI … hai studiato i link che ti ho dato ? ? ?

Perché se ti aspetti che scriviamo noi il programma … non credo che risolverai … :roll_eyes:

Guglielmo

mitidj2008:
insomma alla fine non mi e stato detto nulla sulla domanda del TOPIC :slight_smile:
Come faccio un doppio(o più) loop con tempi diversi?

Guglielmo Ti ha dato la soluzione nella prima risposta.
Ciao Uwe

mitidj2008:
...mi viene visualizzato dopo i 20 secondi...

Da dove ti viene questo calcolo di 20 secondi ???
Nella setup() hai 4 delay per un totale di 4700 ovvero 4,7 secondi.
Ma anche usando millis(), se vuoi fare una "presentazione" con una serie di maschere iniziali, in quella fase mica l'utente può agire sui tasti. E' come se accendendo un dvd player, mentre si stà presentando la maschera di benvenuto vuoi già usare il telecomando ?!? Oppure non ho capito il tuo problema.

P.S. 2 consigli,

  1. cambia le define dei pin in const byte, esempio
    invece di #define tempP 9 const byte tempP=9;
  2. dai dei nomi più significativi, ci ho messo mezz'ora a capire che tempP e tempM sono dei button.
    Anche on, off non sono molto "qualificativi".

Si. Grazie le ho lette. avendo allungato la cosa del pin 13 mi era sfuggita la risposta di Guglielmo
IGOR: e in fase di test ora… gli on, off sono il led rosso e verde che mi indica il funzionamento della caldaia. e nel setup avevo fatto così unito di TEST che mi accendeva il led rosso e il verde e comandava il rele. poi passa al programma vero e proprio. alla fine lo anche cancellato…

in fine poi ho trovato un tutorial con la funzione “looper” che e simile ai millis.

#include <LiquidCrystal.h>

#define LEDoff 7
#define LEDon  6
#define tempP  9
#define tempM  8

#include "looper.h"

looper LCDD1; //create a new istance of the class leOS
looper TEMPP1; //create a new istance of the class leOS
looper RELAYY1; //create a new istance of the class leOS

#define LM35_pin 2

float vref = 1.1;                       
float tempC;
int tempV = 20;
int reading;

LiquidCrystal lcd( 12, 11, 5, 4, 3, 2 );

void setup() 
{
  lcd.begin( 4, 20 );           
  lcd.setCursor( 0, 0 );
  pinMode(13, OUTPUT);
          
  pinMode(LEDoff, OUTPUT);
  pinMode(LEDon, OUTPUT);
   
  pinMode(tempP, INPUT);
  pinMode(tempM, INPUT);
  
 
  lcd.clear();
  digitalWrite(LEDoff, LOW);
  digitalWrite(LEDon, LOW);
  digitalWrite(13, LOW);
    
  delay(200);
  
  analogReference( INTERNAL ); 
  analogRead( LM35_pin );
  
  LCDD1.addJob(LCD1, 500);
  TEMPP1.addJob(TEMP1, 3000);
  RELAYY1.addJob(RELAY1, 5000);
  
}
void loop()
{
  LCDD1.scheduler();
  TEMPP1.scheduler();
  RELAYY1.scheduler();
}

void TEMP1()
{ 
  
tempC = analogRead(LM35_pin);       
tempC = (5.0 * tempC * 100)/1024.0; 
reading = analogRead(LM35_pin);
tempC = reading / 10.0; 

}

void RELAY1()
{

 if(tempC <= tempV){
    digitalWrite(LEDon, HIGH);
    digitalWrite(LEDoff, LOW);
    lcd.setCursor( 0, 3 );
    lcd.print( ".....ON.....FIRE....");
    digitalWrite(13, HIGH);
  }else{
    digitalWrite(LEDoff, HIGH);
    digitalWrite(LEDon, LOW);
    digitalWrite(13, LOW);
    lcd.setCursor( 0, 3 );
    lcd.print( "....OFF......OFF....");
  }
}

void LCD1()
{
  
  if(digitalRead(tempM) == HIGH){ tempV--;}
  if(digitalRead(tempP) == HIGH){ tempV++;}
             
  lcd.setCursor( 0, 0 );    
  lcd.print( "......:WELCOME:.....");
  lcd.setCursor( 0, 1 );     
  lcd.print( "Temp READ:");
  lcd.setCursor( 11, 1 );     
  lcd.print( tempC );         
  lcd.print( ' ' );          
  lcd.print( (char) 223 );   
  lcd.print( 'C' );
  lcd.setCursor( 0, 2 );
  lcd.print( "Temp SET: ");
  lcd.print( ' ' );            
  lcd.print(tempV);
  lcd.print( ".00 " );          
  lcd.print( (char) 223 );   
  lcd.print( 'C' );   
   
}

nid69ita:
Da dove ti viene questo calcolo di 20 secondi ???
Nella setup() hai 4 delay per un totale di 4700 ovvero 4,7 secondi.
Ma anche usando millis(), se vuoi fare una "presentazione" con una serie di maschere iniziali, in quella fase mica l'utente può agire sui tasti. E' come se accendendo un dvd player, mentre si stà presentando la maschera di benvenuto vuoi già usare il telecomando ?!? Oppure non ho capito il tuo problema.

P.S. 2 consigli,

  1. cambia le define dei pin in const byte, esempio
    invece di #define tempP 9 const byte tempP=9;
  2. dai dei nomi più significativi, ci ho messo mezz'ora a capire che tempP e tempM sono dei button.
    Anche on, off non sono molto "qualificativi".

chiedo in anticipo perdono se sfrutto il commento per chiedere un'info parzialmente OT.
Perchè non va bene dichiarare i pin con i #define ? Ho letto ovunque che è il modo migliore, perchè non occupa spazio al contrario dei vari int, const int ecc...ho sempre capito male io?

mitidj2008:
in fine poi ho trovato un tutorial con la funzione "looper" che e simile ai millis.

NO, looper NON è una funzione, è una libreria (uno schedulatore software per Arduino), scritta dal ns. mod Leo e la sua descrizione completa la trovi QUI .

Naturalmente puoi usarla (... anche se nel tuo caso è un po' eccessiva), ma in questo modo NON avrai imparato un bel niente e la prima volta che ti si riproporrà un problema in cui non puoi usare la delay() e neanche la libreria looper (che, ripeto, è uno scheduler software) sarai da capo a dodici ! :smiling_imp:

Quello che dovevi fare era STUDIARTI i link ch ti avevo dato e implementare la cosa con millis() ...
... per la qual cosa, ovviamente, occorre sforzarsi di più.

Ma ... non immagini quante volte in futuro dovrai usare millis() e allora ... :roll_eyes:

Guglielmo

giorgio90:
chiedo in anticipo perdono se sfrutto il commento per chiedere un'info parzialmente OT.
Perchè non va bene dichiarare i pin con i #define ? Ho letto ovunque che è il modo migliore, perchè non occupa spazio al contrario dei vari int, const int ecc...ho sempre capito male io?

No, meglio la const, che NON occupa memoria ma dal compilatore viene considerata come una "sostituzione", un pò come fa il precompilatore per la define. C'e' un thread italiano, nel forum relativo, a questo argomento con relativi test.
Inoltre la const ti obbliga a dichiararne il tipo, cosa che non puoi fare con define (tranne usando i vari suffissi o forzando lo zero decimale per float/double). E il non poterlo fare, a volte porta ad ambiguità.

giorgio90:
Perchè non va bene dichiarare i pin con i #define ??

Dipende da quello che devi fare con quel valore, se parliamo di pin sicuramente conviene la #define, se parliamo di un valore da utilizzare all'interno del programma, magari tramite pointer, che deve essere un ben preciso tipo dato indipendentemente dal valore assegnato, allora conviene la const.

astrobeed:
Dipende da quello che devi fare con quel valore, se parliamo di pin sicuramente conviene la #define, se parliamo di un valore da utilizzare all'interno del programma, magari tramite pointer, che deve essere un ben preciso tipo dato indipendentemente dal valore assegnato, allora conviene la const.

si io parlo esclusivamente di pin, ovviamente le altre variabili le dichiaro nella maniera più appropriata al tipo di variabile... Però leggendo ora la risposta di nid69ita vado un po' in confusione...
Nid tu ti riferisci a un caso generico o dici che è meglio usare il const anche per i pin?