Integrare un pulsante ad un sensore ds18b20 collegato ad un display lcd

Salve a tutti,
sono nuovo di questo forum quindi scusatemi per gli errori che probabilmente sto facendo. Da circa un mese ho iniziato a gestire Arduino e sto cercando passo passo di sviluppare piccoli progetti. Mettendo assieme più cose sono arrivato a comporre un display lcd collegato ad un sensore di temperatura ds18b20 che a seconda della temperatura restituisce dopo un secondo e mezzo frasi diverse.

// LCD Thermostat
// www.hacktronics.com

#include <OneWire.h>
#include <LiquidCrystal.h>

// Connections:
// rs (LCD pin 4) to Arduino pin 12
// rw (LCD pin 5) to Arduino pin 11
// enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int backLight = 13;    // pin 13 will control the backlight

OneWire  ds(8);        // ds18b20 pin #2 (middle pin) to Arduino pin 8

byte i;
byte present = 0;
byte data[12];
byte addr[8];
  
int HighByte, LowByte, SignBit, Whole, Fract, TReading, Tc_100, FWhole;
const int buttonPin = 7; 
int buttonState = 0;
void setup(void) {
  pinMode(buttonPin,INPUT);
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  lcd.begin(2,16);              // rows, columns.  use 2,16 for a 2x16 LCD, etc.
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(0,0);           // set cursor to column 0, row 0
  
    if ( !ds.search(addr)) {
      lcd.clear(); lcd.print("No more addrs");
      delay(1000);
      ds.reset_search();
      return;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      lcd.clear(); lcd.print("CRC not valid!");
      delay(1000);
      return;
  }
}

void getTemp() {
  int foo, bar;
  
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);

  for ( i = 0; i < 9; i++) {
    data[i] = ds.read();
  }
  
  LowByte = data[0];
  HighByte = data[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  
  if (SignBit) {
    TReading = -TReading;
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25
  Whole = Tc_100 / 100;          // separate off the whole and fractional portions
  Fract = Tc_100 % 100;
  if (Fract > 49) {
    if (SignBit) {
      --Whole;
    } else {
      ++Whole;
    }
  }

  if (SignBit) {
    bar = -1;
  } else {
    bar = 1;
  }
 
  
}

void printTemp(void) {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temperatura e':");
  lcd.setCursor(0,1);   
  
  if (SignBit) {  
     lcd.print("-");
  }
  lcd.print(Whole);
  lcd.print(" C  ");
}

void loop(void) {
  getTemp();
  printTemp();
  delay(5000);
  lcd.clear();
  if (Whole <= 16) {
  lcd.setCursor(0,0);
  lcd.print("Fa davvero!");
  lcd.setCursor(0,1);
  lcd.print("Fredderrimo!");
  delay(1500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Brrr!!,");
  delay(5000);

  }
  if (Whole == 17) {
  lcd.setCursor(0,0);
  lcd.print("Brrr!!,");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Fa freddo,");
  lcd.setCursor(0,1);
  lcd.print("ma si resiste!");
  delay(5000);
  }
  
  if (Whole == 18) {
  lcd.setCursor(0,0);
  lcd.print("Questa e',");
  lcd.setCursor(0,1);
  lcd.print("assolutamente,");
  delay(1500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("La temperatura,");
  lcd.setCursor(0,1);
  lcd.print("ideale!");
  delay(5000);
  }
    
  if (Whole == 19) {
  lcd.setCursor(0,0);
  lcd.print("Si puo' pensare");
  lcd.setCursor(0,1);
  lcd.print("di spegnere");
  delay(1500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("i termosifoni");
  lcd.setCursor(0,1);
  lcd.print("adesso!");
  delay(5000);
  }

  if (Whole > 20){ 
  lcd.setCursor(0,0);
  lcd.print("Fa troppo caldo");
  delay(1500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Meglio spegnere");
  lcd.setCursor(0,1);
  lcd.print("i termosifoni!");
  delay(5000);
}
}

(A casa mio padre tiene il riscaldamento spesso spento o pressoché al minimo, era anche un modo per sfottere la sua politica di farci usare il maglione in casa tutto l'inverno...)
Ovviamente avendo copiato la parte relativa al funzionamento del sensore "paro-paro", ho capito che funzioni svolgono getTemp() e printTemp() ma alcuni passaggi interni non li capisco.
Chiaramente è tutto fili svolazzanti, ma in un futuro mi piacerebbe ridurlo di dimensioni e magari inserirlo in un contenitore comprando, se opportuna, una versione di Arduino o simili più piccola.
Il sistema l'ho provato e funziona però avrei due domande:

  1. Per il codice che ho trovato e memorizzato nello sketch, il sensore mi restituisce sempre valori interi non decimali (il sensore credo abbia un range di oscillazione di +/-0,5°) Non è possibile ottenere misurazioni più precise? dovrei orientarmi su un altro sensore?
  2. Essendo un loop il display e il sensore restituiscono valori per tutto il tempo che sono accesi, mi piacerebbe invece impostare un pulsante in modo da ottenere la temperatura su schermo con relativi commenti quando questo viene premuto. (In un futuro poco più prossimo sostituirei questo con un sensore PIR per farlo accendere ogni volta che qualcuno ci passa vicino). Non riesco a integrare gli sketch dei pulsanti con questo, cosa mi suggerite di fare?
    Vi ringrazio per l'attenzione e la passione che mettete in questo forum
    Benedetto

Dunque sono riuscito a inserire un pulsante (dopo un po' di pull-up di cui non sono proprio avvezzo...).
Ho cambiato il codice e ho messo questo:

// LCD Thermostat
// www.hacktronics.com

#include <OneWire.h>
#include <LiquidCrystal.h>

// Connections:
// rs (LCD pin 4) to Arduino pin 12
// rw (LCD pin 5) to Arduino pin 11
// enable (LCD pin 6) to Arduino pin 10
// LCD pin 15 to Arduino pin 13
// LCD pins d4, d5, d6, d7 to Arduino pins 5, 4, 3, 2
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
int backLight = 13;    // pin 13 will control the backlight

OneWire  ds(8);        // ds18b20 pin #2 (middle pin) to Arduino pin 8

byte i;
byte present = 0;
byte data[12];
byte addr[8];
  
int HighByte, LowByte, SignBit, Whole, Fract, TReading, Tc_100, FWhole;
const int bottone = 7; 
int Valore = 0;
void setup(void) {
  pinMode(bottone,INPUT);
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH); // turn backlight on. Replace 'HIGH' with 'LOW' to turn it off.
  lcd.begin(2,16);              // rows, columns.  use 2,16 for a 2x16 LCD, etc.
  lcd.clear();                  // start with a blank screen
  lcd.setCursor(0,0);           // set cursor to column 0, row 0
  
    if ( !ds.search(addr)) {
      lcd.clear(); lcd.print("No more addrs");
      delay(1000);
      ds.reset_search();
      return;
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {
      lcd.clear(); lcd.print("CRC not valid!");
      delay(1000);
      return;
  }
}

void getTemp() {
  int foo, bar;
  
  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);

  for ( i = 0; i < 9; i++) {
    data[i] = ds.read();
  }
  
  LowByte = data[0];
  HighByte = data[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  
  if (SignBit) {
    TReading = -TReading;
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25
  Whole = Tc_100 / 100;          // separate off the whole and fractional portions
  Fract = Tc_100 % 100;
  if (Fract > 49) {
    if (SignBit) {
      --Whole;
    } else {
      ++Whole;
    }
  }

  if (SignBit) {
    bar = -1;
  } else {
    bar = 1;
  }
 
  
}

void printTemp(void) {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Temperatura e':");
  lcd.setCursor(0,1);   
  
  if (SignBit) {  
     lcd.print("-");
  }
  lcd.print(Whole);
  lcd.print(" C  ");
}

void loop(void) {
  getTemp();
  
  Valore = digitalRead(bottone); 
  if (Valore == HIGH){
    printTemp();
    delay(1000);
    lcd.clear();
      if (Whole <= 16) {
      lcd.setCursor(0,0);
      lcd.print("Fa davvero!");
      lcd.setCursor(0,1);
      lcd.print("Fredderrimo!");
      delay(1500);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Brrr!!,");
      delay(2000);
      lcd.clear();
      }  

      if (Whole == 17) {
      lcd.setCursor(0,0);
      lcd.print("Brrr!!,");
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Fa freddo,");
      lcd.setCursor(0,1);
      lcd.print("ma si resiste!");
      delay(2000);
      lcd.clear();
      }
    
      if (Whole == 18) {
      lcd.setCursor(0,0);
      lcd.print("Questa e',");
      lcd.setCursor(0,1);
      lcd.print("assolutamente,");
      delay(1500);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("La temperatura,");
      lcd.setCursor(0,1);
      lcd.print("ideale!");
      delay(2000);
      lcd.clear();
      }
      
      if (Whole == 19) {
      lcd.setCursor(0,0);
      lcd.print("Si puo' pensare");
      lcd.setCursor(0,1);
      lcd.print("di spegnere");
      delay(1500);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("i termosifoni");
      lcd.setCursor(0,1);
      lcd.print("adesso!");
      delay(2000);
      lcd.clear();
      }
  
      if (Whole >= 20){ 
      lcd.setCursor(0,0);
      lcd.print("Fa troppo caldo");
      delay(1500);
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Meglio spegnere");
      lcd.setCursor(0,1);
      lcd.print("i termosifoni!");
      delay(2000);
      lcd.clear();
      }
  }
 else {
      }
delay(1000);
}

Effettivamente quando premo rileva le temperatura e poi restituisce le frasi relative senza avere sempre lo schermo acceso, però:

  1. Secondo voi va bene o ho fatto una "vaccata"?
  2. l'lcd ha la retroilluminazione molto molto fiacca, io gli ho messo una resistenza da 2,2 kohms, mi pare che alcuni non la mettano neppure ma mi sembra che lcd collegato direttamente sia un po' troppo luminoso (ndr: è un banalissimo 2x16 a cristalli liquidi.). Dovrei sostituirla?

.... be se funziona non è una vaccata...
imho però usi troppi delay: per ora non ti danno fastidio ma durante questi delay non puoi fare null'altro. Nei prossimi programmi questo approccio ti darà dei fastidi: prova a vedere la tecnica del blink without delay.
La tua temperatura (whole) è intera... e per questo non vedi i decimali... c'è un posto dove il tuo programma prende la temperatura scritta in Tc_100 e la separa in parte decimale e frazionaria e gli calcola in segno.

Per l'lcd di solito 2k sono tantini effettivamente... prova a calarla.