Leggere temperatura ed umidità su lcd, con accensione Led, comandata da pulsanti

Buona sera ragazzi,
sono un principiante assoluto, quindi se ho fatto qualche errore grossolano mi scuso in anticipo, sono andato avanti dai ricordi del liceo di c++.

La mia idea sarebbe di usare il display Lcd 16x2 con arduino UNO per visualizzare dei dati di temperatura ed umidità, ricevuti dal sensore dht11, e di umidità del terreno ricevuti da un igrometro. In aggiunta a questo, avrei 3 Led, uno verde, uno rosso, uno giallo, che si accendono quando i valori sono in una determinata soglia.
Ho pensato di mettere 3 bottoni a pressione , ciascuno associato a una determinata misurazione, in modo tale da visualizzare uni parametro alla volta sull'lcd, e di conseguenza accendere il Led in base al valore di suddetto parametro.

Ho però riscontrato un problema che non riesco a risolvere:in qualche modo la misurazione del dht mi va in conflitto con il codice per i bottoni, quindi non funzionano, mentre il bottone associato all'igrometro, e quindi anche i led, sotto quelle condizioni vanno senza problemi.

Non credo sia un problema di montaggio, infatti separatamente i vari componenti vanno senza problemi, quindi chiederei consiglio a voi molto più esperti :slight_smile:
ecco il codice

//includo librerie:
#include <LiquidCrystal.h>
#include <dht_nonblocking.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11

//collegamenti ai pin:
int btemp = 5;          //pin bottone temperatura
int bum = 4;            //pin bottone umidità
int bumter = 3;        //pin bottone umidità terreno
int pinSensore = A0;
int valoreOutput;


//led
const int ledV = 13; //segna se il valore è basso
const int ledR = 1; // segna se il valore è alto
const int ledG = 6; //segna se il valore è medio

// connessione display (pin)
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

//sensore temperatura e umidità:
static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );

// righe per il sensore dht, prese direttamente dal tutorial di arduino sul dht11

static bool measure_environment( float *temperature, float *humidity )
{
  static unsigned long measurement_timestamp = millis( );

  /* Measure once every four seconds. */
  if( millis( ) - measurement_timestamp > 3000ul )
  {
    if( dht_sensor.measure( temperature, humidity ) == true )
    {
      measurement_timestamp = millis( );
      return( true );
    }
  }

  return( false );
}


void setup()
{
float temperature;
float humidity;


 lcd.begin(16, 2);
pinMode(btemp,INPUT_PULLUP);
pinMode(bum, INPUT_PULLUP);
pinMode(bumter, INPUT_PULLUP);
lcd.print("Menu");

//led
pinMode(ledV, OUTPUT );
pinMode(ledR, OUTPUT);
pinMode(ledG, OUTPUT );

}

void loop()
{

float temperature;
float humidity;

//bottone per temperatura
if (digitalRead(btemp) == LOW)
{
  if( measure_environment( &temperature, &humidity ) == true ) //anche lei presa dal tutorial

  {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("temperatura");
lcd.setCursor(0,2);
lcd.print(temperature);

//accendo led per temperatura
 if ( temperature<25 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, HIGH);
  }

  if ( temperature>25 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledG, HIGH);
  }
  
  if ( temperature>28 ){
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledR, HIGH);
  }
  }
}

//bottone per umidità
if (digitalRead(bum) == LOW)
{
  if( measure_environment( &temperature, &humidity ) == true )
  {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("umidita'");
lcd.setCursor(0,2);
lcd.print(humidity);

//accendo i led in base ai valori
  if ( humidity<=70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, HIGH);
  }

  if ( humidity>70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledG, HIGH);
  }
  
  if ( humidity>90 ){
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledR, HIGH);
  }
  }
}

//bottone per umidità terra 
if (digitalRead(bumter) == LOW)
{
valoreOutput=analogRead(pinSensore);
valoreOutput=map(valoreOutput, 1023, 275, 0, 100);

lcd.clear();
lcd.setCursor(0,0);
lcd.print("umidita'terra");
lcd.setCursor(0,2);
lcd.print(valoreOutput);
lcd.print("%");
lcd.setCursor(0, 3);

//accendo i led in base ai valori
  if ( valoreOutput<=70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, HIGH);
  }

  if ( valoreOutput>70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledG, HIGH);
  }
  
  if ( valoreOutput>90 ){
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledR, HIGH);
  }



}


}

il mio dubbio è, visto che l'igrometro va senza problemi, io abbia usato male queste righe di codice,

// righe per il sensore dht, prese direttamente dal tutorial di arduino sul dht11

static bool measure_environment( float *temperature, float *humidity )
{
  static unsigned long measurement_timestamp = millis( );

  /* Measure once every four seconds. */
  if( millis( ) - measurement_timestamp > 3000ul )
  {
    if( dht_sensor.measure( temperature, humidity ) == true )
    {
      measurement_timestamp = millis( );
      return( true );
    }
  }

  return( false );
}

e di conseguenza questo if

if( measure_environment( &temperature, &humidity ) == true )

pPiù che altro queste righe nel tutorial sono spiegate come righe utili per vedere se si ha una nuova misurazione, e quindi nel caso positivo scriverla a display. Ho provato anche ad eliminarle, mandando direttamente in output le variabili temperature e humidity, ma con scarsi risultati.

Mi scuso per il post molto lungo, ma ho cercato di spiegare al meglio possibile la situazione.
Grazie in anticipo a chi mi potrà aiutare!!

Copiare pezzi di codice senza capirli non è una buona prassi e porta quasi sempre a pessimi risultati.

La funzione che hai individuato e postato per prima cosa non ti serve e poi restituisce sempre false.
Le istruzioni di una funzione vengono eseguite in successione e arrivati alla fine la funzione termina,
adesso nella funzione prendiamo il valore di millis() e successivamente confrontiamo che siano passati 3 secondi, ma il confronto è quasi istantaneo per cui risulta sempre falso che siano passati 3 secondi, quindi la funzione non legge i valori, non restituisce true ma false.

Adesso a te serve solo leggere il valore del sensore, elimina la funzione, prendi solo il codice di lettura del sensore che lo metterai nel codice pulsante.

//includo librerie:
#include <LiquidCrystal.h>
#include <dht_nonblocking.h>
#define DHT_SENSOR_TYPE DHT_TYPE_11

//collegamenti ai pin:
int btemp = 5;          //pin bottone temperatura
int bum = 4;            //pin bottone umidità
int bumter = 3;        //pin bottone umidità terreno
int pinSensore = A0;
int valoreOutput;


//led
const int ledV = 13; //segna se il valore è basso
const int ledR = 1; // segna se il valore è alto
const int ledG = 6; //segna se il valore è medio

// connessione display (pin)
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

//sensore temperatura e umidità:
static const int DHT_SENSOR_PIN = 2;
DHT_nonblocking dht_sensor( DHT_SENSOR_PIN, DHT_SENSOR_TYPE );




void setup()
{


 lcd.begin(16, 2);
pinMode(btemp,INPUT_PULLUP);
pinMode(bum, INPUT_PULLUP);
pinMode(bumter, INPUT_PULLUP);
lcd.print("Menu");

//led
pinMode(ledV, OUTPUT );
pinMode(ledR, OUTPUT);
pinMode(ledG, OUTPUT );

}

void loop()
{

float temperature;
float humidity;

//bottone per temperatura
if (digitalRead(btemp) == LOW)
{
  if( dht_sensor.measure( &temperature, &humidity ) == true ) //anche lei presa dal tutorial

  {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("temperatura");
lcd.setCursor(0,2);
lcd.print(temperature);

//accendo led per temperatura
 if ( temperature<25 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, HIGH);
  }

  if ( temperature>25 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledG, HIGH);
  }
 
  if ( temperature>28 ){
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledR, HIGH);
  }
  }
}

//bottone per umidità
if (digitalRead(bum) == LOW)
{
  if( dht_sensor.measure( &temperature, &humidity ) == true )
  {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("umidita'");
lcd.setCursor(0,2);
lcd.print(humidity);

//accendo i led in base ai valori
  if ( humidity<=70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, HIGH);
  }

  if ( humidity>70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledG, HIGH);
  }
 
  if ( humidity>90 ){
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledR, HIGH);
  }
  }
}

//bottone per umidità terra
if (digitalRead(bumter) == LOW)
{
valoreOutput=analogRead(pinSensore);
valoreOutput=map(valoreOutput, 1023, 275, 0, 100);

lcd.clear();
lcd.setCursor(0,0);
lcd.print("umidita'terra");
lcd.setCursor(0,2);
lcd.print(valoreOutput);
lcd.print("%");
lcd.setCursor(0, 3);

//accendo i led in base ai valori
  if ( valoreOutput<=70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, HIGH);
  }

  if ( valoreOutput>70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledG, HIGH);
  }
 
  if ( valoreOutput>90 ){
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledR, HIGH);
  }



}


}

Prova a mettere globali le due variabili temperature e humidity

torn24:
Copiare pezzi di codice senza capirli non è una buona prassi e porta quasi sempre a pessimi risultati ...

Eh più che altro, basandomi sui tutorial pensavo fosse “ obbligatorio “ mettere quella verifica, ora vedo se senza cambia qualcosa, grazie per ora

>biada: Quando si quota un post, NON è necessario riportarlo (inutilmente) tutto; bastano poche righe per far capire di cosa si parla ed a cosa ci si riferisce, inoltre, se si risponde al post immediatamente precedente, normalmente NON è necessario alcun "quote" dato che è sottinteso. :slight_smile:

Gli utenti da device "mobile" (piccoli schermi) ringrazieranno per la cortesia :wink:

Guglielmo

P.S.: Ho troncato io il "quote" del tuo post qui sopra :wink:

Va bene, d’ora in poi ci starò più attento Guglielmo :slight_smile:

torn24:
Copiare pezzi di codice senza capirli non è una buona prassi e porta quasi sempre a pessimi risultati..

Eh purtroppo non va nemmeno così, cioè a dire il vero va, ma risponde dopo una pressione random del tasto, alla prima pressione non va, se lo premo 3-5 volte di fila allora visualizza il dato desiderato. oltre a quello, non aggiorna in diretta i dati, come se la funzione non fosse in loop, per aggiornare le misurazioni devo premere il tasto :frowning:
non riesco a capire se ci sia qualche conflitto, e in caso dove possa essere, voi avete qualche idea ?

biada:

torn24:
Copiare pezzi di codice senza capirli non è una buona prassi e porta quasi sempre a pessimi risultati.

Eh purtroppo non va nemmeno così

Cioè copiando pezzi di codice?... :slight_smile: Beh, lasciamo perdere...

Leggo:
lcd.setCursor(0,2); lcd.print(temperature);
Se il display è 16x2, le righe disponibili sono solo la 0 e la 1!

Datman:
Cioè copiando pezzi di codice?... :slight_smile: Beh, lasciamo perdere...

Ripeto, non ho " copiato", ho studiato per capire singolarmente come far funzionare i singoli sensori, poi ho messo "insieme " i pezzi. Non avendo un libro sotto mano, questo è stato l'unico modo che mi è venuto in mente per capire, se ne consigli di migliori dimmi pure :slight_smile:

comunque ora dovrei aver risolto, ho usato un'altra libreria per il dht seguendo un tutorial diverso, e i bottoni vanno bene alla prima pressione.

//includo librerie

//sensore temperatura
#include <DHT.h>

#include <LiquidCrystal.h>
#include "DHT.h"
#define DHTPIN 2
// 8 è il pin di Arduino a cui collego il sensore di temperatura
#define DHTTYPE DHT11
// dht11 è il tipo di sensore che uso
DHT dht(DHTPIN, DHTTYPE);
// 8 è il pin di Arduino a cui collego il sensore di temperatura


//lcd
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

//led
const int ledV = 13; //segna se il valore è basso
const int ledR = 1; // segna se il valore è alto
const int ledG = 6; //segna se il valore è medio

//bottoni
int btemp = 5;
int bum = 4;
int bumter = 3;

//umidità terra
int pinSensore = A0;
int valoreOutput;




void setup()
{
 //variabili umidità e temperatura

//pin bottoni
pinMode(btemp, INPUT_PULLUP);
pinMode(bum, INPUT_PULLUP);
pinMode(bumter, INPUT_PULLUP);

//lcd
lcd.begin(16, 2);
lcd.print("Menu'");

//led
pinMode(ledV, OUTPUT );
pinMode(ledR, OUTPUT);
pinMode(ledG, OUTPUT );
}

void loop()
{
  //variabili per umidità e temperatura
int t = dht.readTemperature();
int h = dht.readHumidity();

//bottone per temperatura
if (digitalRead(btemp) == LOW)
{
  
lcd.clear();
lcd.setCursor(0,0);
lcd.print("temperatura");
lcd.setCursor(0,1);
lcd.print(t);

 //accendo i led in base ai valori
  if ( t<25 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, HIGH);
  }

  if ( t>25&&t<28 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledG, HIGH);
  }
  
  if ( t>28 ){
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledR, HIGH);
  }
}

//bottone per umidità
if (digitalRead(bum) == LOW)
{
 // vedo su schermo i valori
lcd.clear();
lcd.setCursor(0,0);
lcd.print("umidita'");
lcd.setCursor(0,1);
lcd.print(h);
//accendo i led in base ai valori
  if ( h<=70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, HIGH);
  }

  if ( (h>70) && (h<90) ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledG, HIGH);
  }
  
  if ( h>90 ){
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledR, HIGH);
  }

}

//bottone per umidità terra 
if (digitalRead(bumter) == LOW)
{
valoreOutput=analogRead(pinSensore);
valoreOutput=map(valoreOutput, 1024,100, 0, 100);

lcd.clear();
lcd.setCursor(0,0);
lcd.print("umidita'terra");
lcd.setCursor(0,1);
lcd.print(valoreOutput);
lcd.print("%");

//accendo i led in base ai valori
  if ( valoreOutput<=70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, HIGH);
  }

  if ( valoreOutput>70 ){
    digitalWrite(ledR, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledG, HIGH);
  }
  
  if ( valoreOutput>90 ){
    digitalWrite(ledG, LOW);
    digitalWrite(ledV, LOW);
    digitalWrite(ledR, HIGH);
  }

}


}

L'unica pecca che ancora c'è, è dovuta al fatto che continua a non aggiornare i valori delle misurazioni finchè non premo di nuovo il pulsante, ora vedo se riesco a risolvere

Devi impostarlo diversamente: nel loop, ogni secondo (if(millis()-t>999{t+=1000; ...}) se x==0 visualizzi la temperatura, altrimenti visualizzi l'umidità. Quando premi il pulsante, scrivi una sola volta temperatura o umidità e modifichi il valore di x.

Perfetto proverò così, grazie :slight_smile:

t è unsigned long globale e nel setup la imposti a 1000 per avere subito la prima lettura.