Lm35 + LCD + Menù. Semplice termostato.

Prima corsa con arduino.

/*
||
|| @file 	LM35+LCD.ino 
|| @version	0.5
|| @author	Nardello Matteo
|| @contact	nrdmtt@gmail.com
||
|| @description
|| | Simple thermometer based on LM35 and a 16x2 LCD with Min/Max functionality 
|| #
||
*/

///////////////////////////////////// LIBRERIE ///////////////////////////////////
#include <LiquidCrystal.h>
#include <TimedAction.h>
#include <Bounce.h>

///////////////////////////////////// DEFINES ///////////////////////////////////
#define Btn_Enter 8                                                               //Pin a cui e' collegato il pulsante
#define Backlight 9                                                               //Pin usato per regolare la retroilluminazione

/////////////////////////////////// TIMEOUTS //////////////////////////////////
TimedAction TO_BlackLight = TimedAction(10000, backlight);
TimedAction TO_ReturnHome = TimedAction(50000, mainpage);
TimedAction TO_Dati = TimedAction (200, dati);
TimedAction TO_Print = TimedAction (2000, Print);

/////////////////////////////////// DEBOUNCE ////////////////////////////////////
Bounce B_Btn_Enter= Bounce(Btn_Enter, 300);                                        //Debounce pulsante enter

/////////////////////////////////// VARIABILI ///////////////////////////////////
int reading = 0, page = 0;                                                        // Variabile lettura pin
float V = 0, T = 0, Tmed = 0, Vmed = 0, Min = 80, Max = 0, Ite = 0;               // Temperatura e voltaggio rilevati
float Mis[2] = {0 , 0};                                                           // Array letture Temp - Volt 

byte cerchio[8] = {B01100, B10010, B10010, B01100, B00000, B00000, B00000, B00000};

///////////////////////////////// DISPLAY /////////////////////////////////////
// LiquidCrystal display with:
// rs on pin 2
// enable on pin 3
// d4, d5, d6, d7 on pins 4, 5, 6, 7

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

////////////////////////////// FUNZIONI PAGINE //////////////////////////////////
void mainpage()                                                                   //Funzione per la gestione della pagina principale
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("  Temperatura:");
  lcd.setCursor(5, 1);
  lcd.print(Tmed);
  lcd.setCursor(10, 1);
  lcd.write((uint8_t)0);
  page = 0;
}

void firstpage()                                                                   //Funzione per la gestione della pagina Tmax
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temperatura  Max");
  lcd.setCursor(5, 1);
  lcd.print(Max);
  lcd.setCursor(10, 1);
  lcd.write((uint8_t)0);
}

void secondpage()                                                                   //Funzione per la gestione della pagina Tmin
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temperatura  Min");
  lcd.setCursor(5, 1);
  lcd.print(Min);
  lcd.setCursor(10, 1);
  lcd.write((uint8_t)0);
}

//////////////////////////// FUNZIONI TEMPERATRA ///////////////////////////////
void dati()                                                                      //Funzione che salva in un array la somma di temperatura e tensoni misurate (misurate ogni 200 ms)
{
  TO_Dati.reset();
  
  reading = analogRead(0);
  V = (reading * 5.0) / 1024;
  T = V * 100;
  Mis[0] = Mis[0] + T;
  Mis[1] = Mis[1] + V;
  
  Ite++;
}

void MAX()                                                                        //Funzione che calcola la temperatura massima
{
  if(Tmed > Max)
  {
    Max = Tmed;
  }
}

void MIN()                                                                        //Funzione che calcola la temperatura minima
{
  if(Tmed < Min)
  {
    Min = Tmed;
  }
}

void Print()
{
  Serial.print(page);
  Serial.print(" --- ");
}

///////////////////////////// FUNZIONI PROGRAMMA ///////////////////////////////
void OnBTn1()                                                                    //Funzione gestione pressione bottone
{ 
    switch(page)
    {   
      case 1:
        firstpage();
        break;
        
      case 2:
        secondpage();
        break;
        
      case 3:
        mainpage();
        page=0;
        break; 
    }
}

void backlight()                                                                  //Funzione che disattila la retroilluminzazione
{
  digitalWrite(Backlight, LOW);
}

///////////////////////////// SETUP -- LOOP ///////////////////////////////
void setup()
{
  //SERIAL SetUp
  Serial.begin(9600);
  
  //LCD SetUp
  lcd.begin(16, 2);
  lcd.createChar(0, cerchio);
  lcd.setCursor(0,0);
  lcd.print("    WELCOME");

  //PINS SetUp
  pinMode(Backlight, OUTPUT);
  pinMode(Btn_Enter, INPUT);
  digitalWrite(Backlight, HIGH);
}


void loop ()
{
  TO_Dati.check();
  TO_BlackLight.check();
  
  if(Ite == 10 )      // Ogni dieci misure ne faccio la media, calcola Max-Min e lo stampo sull'LCD
  {
    Tmed = Mis[0] / 10;
    Vmed = Mis[1] / 10;
     
    MIN();
    MAX();
     
    if (page == 0)
    {
      mainpage();
    }
      
    Mis[0]=Mis[1]=0;
    Ite=0;
  }
  
  if(B_Btn_Enter.update() && B_Btn_Enter.read() == HIGH) // Controllo se ho premuto il bottone
  {
    TO_BlackLight.reset();
    TO_ReturnHome.reset();
    
    digitalWrite(Backlight, HIGH);
    
    page++;
    
    OnBTn1();
    
    Print();
  }
  
  if (page != 0)  // Se non sono sulla home, controllo il timeout per tornarci
  {
    TO_ReturnHome.check();
  }
}

Essendo la mia prima esperienza, mi piacerebbe sentire alcuni pareri e consigli per migliorare il tutto.
Grazie :wink:

classi, array, buona identazione e commenti...

non male per la prima prova. Mi piacerebbe vere il codice della classe TimedAction

p.s. non ho letto il copdice riga per riga, mi fido :)

Piccolu update

/*
||
|| @file 	4_buttons
|| @version	1.1
|| @author	Nardello Matteo
|| @contact	nrdmtt@gmail.com
||
|| @description
|| |Termomentro a 4 pulsanti. Tramite menu è possibile 
|| visualizzare la temperatura minima e massima
|| rilevata, da quando il nodo è acceso. 
|| Nella versione 1.1 è stata aggiunta la possibilità 
|| di indicare tramite led se la temperatura è salita 
|| oltre una certa soglia impostata.
|| Riferimento a 3.3 volt per avere una maggiore accuratezza.
*/

///////////////////////////////////// LIBRERIE ///////////////////////////////////
#include <LiquidCrystal.h>
#include <TimedAction.h>
#include <Bounce.h>

///////////////////////////////////// DEFINES ///////////////////////////////////
#define SensorPin 0                                                               //Pin usato per rilevare la tensione del sensore

#define Backlight 8                                                               //Pin usato per regolare la retroilluminazione

#define BtnEnter 9                                                                //Pin a cui e' collegato il pulsante Enter
#define BtnPiu 10                                                                 //Pin a cui e' collegato il pulsante Più
#define BtnMeno 11                                                                //Pin a cui e' collegato il pulsante Meno
#define BtnEsc 12                                                                 //Pin a cui e' collegato il pulsante Esc

#define LRosso 13                                                                 //Pin a cui e' collegato il led di stato (T < 21)

/////////////////////////////////// DEBOUNCE ////////////////////////////////////
Bounce B_Btn_Esc = Bounce(BtnEsc, 175);                                           //Debounce pulsante Esc
Bounce B_Btn_Piu = Bounce(BtnPiu, 175);                                           //Debounce pulsante Più
Bounce B_Btn_Meno = Bounce(BtnMeno, 175);                                         //Debounce pulsante Meno
Bounce B_Btn_Enter = Bounce(BtnEnter, 175);                                       //Debounce pulsante Enter

/////////////////////////////////// TIMEOUTS //////////////////////////////////
TimedAction TO_BlackLight = TimedAction(10000, backlight);
TimedAction TO_ReturnHome = TimedAction(50000, mainpage);
TimedAction TO_Dati = TimedAction (200, dati);
TimedAction TO_Blink = TimedAction(650, Blink);

/////////////////////////////////// VARIABILI ///////////////////////////////////
byte freccia[8] = {B00100, B00110, B11111, B11111, B00110, B00100, B00000, B00000};
byte cerchio[8] = {B01100, B10010, B10010, B01100, B00000, B00000, B00000, B00000};

boolean isprinted = HIGH, onMenu = LOW;

int selezione[2]  = {0, 0}                                                        // Variabile gestione indici cursore
int page = 0, Item = 0;                                                           // Variabili gestione pagine
int reading = 0;                                                                  // Variabile lettura pin
float V = 0, T = 0, Tmed = 0, Vmed = 0, Min = 80, Max = 0, Ite = 0;               // Temperatura e voltaggio rilevati
float Mis[2] = {0 , 0};                                                           // Array letture Temp - Volt 


///////////////////////////////// DISPLAY /////////////////////////////////////
// LiquidCrystal display with:
// rs on pin 2
// enable on pin 3
// d4, d5, d6, d7 on pins 4, 5, 6, 7

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

//////////////////////////// FUNZIONI TEMPERATRA ///////////////////////////////
void dati()                                                                      //Funzione che salva in un array la somma delle temperature e tensoni misurate (misurate ogni 200 ms)
{
  TO_Dati.reset();
  
  reading = analogRead(SensorPin);
  V = (reading * 3.3) / 1024;
  T = V * 100;
  Mis[0] = Mis[0] + T;
  Mis[1] = Mis[1] + V;
  
  Ite++;
}

void MAX()                                                                        //Funzione che calcola la temperatura massima
{
  if(Tmed > Max)
  {
    Max = Tmed;
  }
}

void MIN()                                                                        //Funzione che calcola la temperatura minima
{
  if(Tmed < Min)
  {
    Min = Tmed;
  }
}

void LED(int led, float t)                                                        //Funzione che accende un led se la temp è inferiore a 21°C
{
  if(t < 21)
  {
    digitalWrite(led, HIGH);
  }
  else digitalWrite(led, LOW);
}

////////////////////////////// FUNZIONI PAGINE //////////////////////////////////
void mainpage()
{
  Item = page = 0;
  onMenu = LOW;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("  Temperature:");
  lcd.setCursor(5, 1);
  lcd.print(Tmed);
  lcd.setCursor(10, 1);
  lcd.write((uint8_t)1);
}

void Tmax()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("     T-Max");
  lcd.setCursor(5, 1);
  lcd.print(Max);
  lcd.setCursor(10, 1);
  lcd.write((uint8_t)1);
}

void Tmin()
{
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("     T-Min");
  lcd.setCursor(5, 1);
  lcd.print(Min);
  lcd.setCursor(10, 1);
  lcd.write((uint8_t)1);
}

void Menu()
{
  page = 1;
  lcd.clear();
  lcd.setCursor(1,0);
  lcd.write("T-Max");
  lcd.setCursor(10,0);
  lcd.write("T-Min");
  lcd.setCursor(1,1);
  lcd.write("Esc"); 
}

////////////////////////////// FUNZIONI TIMEOUTS //////////////////////////////////
void Blink()
{
  if(page == 1)
  {
    if(isprinted == HIGH)
    {
      isprinted = LOW;
      lcd.setCursor(selezione[0], selezione[1]);
      lcd.print(" ");
    }
    
    else
    {
      isprinted = HIGH;
      lcd.setCursor(selezione[0], selezione[1]);
      lcd.write((uint8_t)0);
    }
    
    //Serial.print(isprinted);
    TO_Blink.reset();
  }
}

void backlight()                                                                  //Funzione che disattila la retroilluminzazione
{
  digitalWrite(Backlight, LOW);
}

///////////////////////// FUNZIONI GESTIONE PULSANTI //////////////////////////////
void onButton()
{
  digitalWrite(Backlight, HIGH);
  TO_BlackLight.reset();
  TO_ReturnHome.reset();
  Menu();
}

void Enter()
{
  page = 2;
  onMenu = LOW;
  switch(Item)
    {
      case 0:
        Tmax();
        break;
        
      case 1:
        Tmin();
        break;
        
      case 2:
        mainpage();
        break;
    }
}

void Selezione()
{
  switch(Item)
  {
    case 0:
      selezione[0]=selezione[1] = 0;
      break;
      
    case 1:
      selezione[0] = 9;
      selezione[1] = 0;
      break;
      
    case 2:
      selezione[0] = 0;
      selezione[1] = 1;
      break;
  }
}

void Buttons()
{
  if(B_Btn_Enter.update() && B_Btn_Enter.read() == HIGH) // Controllo se ho premuto il pulsante per entrare nel menù
  {
    if(page == 2)
    {
      Menu();
      onMenu = LOW;
    }
    
    onButton();
    
    if(page == 1 && onMenu == HIGH)
    {
      Enter();
    }
    
    onMenu = HIGH;
  }
    
  if(B_Btn_Piu.update() && B_Btn_Piu.read() == HIGH && onMenu == HIGH && page != 2) // Controllo se ho premuto il pulsante per selezionare l'elemento successivo
  {
    onButton();
    Item++;
    
    if(Item > 2) Item = 0;
  }
  
  if(B_Btn_Meno.update() && B_Btn_Meno.read() == HIGH && onMenu == HIGH && page != 2) // Controllo se ho premuto il pulsante per selezionare l'elemento precedente
  {
    onButton();
    Item--;
    
    if(Item < 0) Item = 2;
  }
  
  if(B_Btn_Esc.update() && B_Btn_Esc.read() == HIGH && onMenu == HIGH) // Controllo se ho premuto il pulsante per attivare la selezione
  {
    onButton();
    mainpage();
  }
  Selezione();
}

///////////////////////////// FUNZIONI PROGRAMMA ///////////////////////////////
void setup()
{
  //SERIAL SetUp
  Serial.begin(9600);
  
  //LCD SetUp
  lcd.begin(16, 2);
  lcd.createChar(0, freccia);
  lcd.createChar(1, cerchio);
  lcd.setCursor(0,0);
  lcd.print("    WELCOME");
  
  //PINS SetUp
  pinMode(Backlight, OUTPUT);
  pinMode(LRosso, OUTPUT);
  pinMode(BtnEsc, INPUT);
  pinMode(BtnPiu, INPUT);
  pinMode(BtnMeno, INPUT);
  pinMode(BtnEnter, INPUT);
  digitalWrite(Backlight, HIGH);
  analogReference(EXTERNAL);
  analogRead(SensorPin);
  
  delay(1000);
}

void loop ()
{
  TO_Dati.check();
  TO_BlackLight.check();
  
  if(Ite == 10 )      // Ogni dieci misure ne faccio la media, calcola Max-Min e lo stampo sull'LCD
  {
    Tmed = Mis[0] / 10;
    Vmed = Mis[1] / 10;
     
    MIN();
    MAX();
    LED(LRosso, Tmed);
     
    if (page == 0)
    {
      mainpage();
    }
    Mis[0]=Mis[1]=0;
    Ite=0;
  }
  
  Buttons(); 
  
  if (onMenu == HIGH)  // Se non sono sulla home, controllo il timeout per tornarci
  {
    TO_ReturnHome.check();
    TO_Blink.check(); 
  } 
}

Questa è una revisione del primo codice. In questo caso, utilizzo un semplice menù per visualizzare temp max e temp minima.
Per spostarmi nel menù uso quattro pulsanti

  • Enter/Back
  • Piu
  • Meno
  • Esc

Ho aggiunto inoltre un semplice metodo che accende il led sul pin 13 se la temperatura è inferiore ad una certa soglia.

Commenti più che ben accetti

Ciao,

anche a me piacerebbe vedere TimedAction, sempre se non è segreta :P

Se è questa, è sul playground: http://arduino.cc/playground/Code/TimedAction :disappointed_relieved:

stefanolavori: Ciao,

anche a me piacerebbe vedere TimedAction, sempre se non è segreta :P

come già postato da PaoloP, la classe la trovate sul playground. Funziona molto bene per temporizzare vari eventi, senza dover usare interrupt o delay.