checkBound sensori multipli DHT

Salve,
ho trovato in rete questa codice molto carino con la funzione checkBound

bool checkBound(float newValue, float prevValue, float maxDiff) {
  return !isnan(newValue) &&
         (newValue < prevValue - maxDiff || newValue > prevValue + maxDiff);
}
long lastMsg = 0;
float temp = 0.0;
float hum = 0.0;
float diff = 1.0;
void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  long now = millis();
  if (now - lastMsg > 1000) {
    lastMsg = now;
    float newTemp = hdc.readTemperature();
    float newHum = hdc.readHumidity();
    if (checkBound(newTemp, temp, diff)) {
      temp = newTemp;
      Serial.print("New temperature:");
      Serial.println(String(temp).c_str());
      client.publish(temperature_topic, String(temp).c_str(), true);
    }
    if (checkBound(newHum, hum, diff)) {
      hum = newHum;
      Serial.print("New humidity:");
      Serial.println(String(hum).c_str());
      client.publish(humidity_topic, String(hum).c_str(), true);
    }
  }
}

Ora il mio problema è adattarla a più sensori.
Consigli?
Devo riscriverla e dichirare tante variabili newTemp(1 ...x) tante volte quanti sono i miei sensori o c'è un modo più elegante?

Adesso dove metti i valori di ogni sensore?
Basta che prendi quelle variabili e le passi di volta in volta alla funzione.

fratt:
Adesso dove metti i valori di ogni sensore?
Basta che prendi quelle variabili e le passi di volta in volta alla funzione.

Attualmente le memorizzo così con una funzione:

void Read_Temp()
{
  // Leggo le temperature dei DHT
  if (millis() - t_temp > 2000) // Attendo 2 secondi
  {
    t_temp = millis();
    sensors.requestTemperatures(); // Send the command to get temperatures
    // Lettura sensori DHT21 e DHT22
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    h1 = dht1.readHumidity();
    t1 = dht1.readTemperature();
    h2 = dht2.readHumidity();
    t2 = dht2.readTemperature();
    h3 = dht3.readHumidity();
    t3 = dht3.readTemperature();
    h4 = dht4.readHumidity();
    t4 = dht4.readTemperature();
    h5 = dht5.readHumidity();
    t5 = dht5.readTemperature();
    h6 = dht6.readHumidity();
    t6 = dht6.readTemperature();
    h7 = dht7.readHumidity();
    t7 = dht7.readTemperature();
  }
  //Print_Temp();
}

per poi utilizzarla secondo le mie necessità tipo così:

void SendMQTT()
{
  // INVIO I DATI AL BROKER MQTT HOME ASSISTANT
  // se si ha un modulo RTC si può creare una stringa con l'orario di pubblicazione dei dati che viene trasmessa al server mqtt

  if (millis() - t_mqtt > 5000) // Attendo 5 secondi
  {
    t_mqtt = millis();
    /* char orario1[6];
      String orario = String(format(now.hour())).c_str();
      orario.concat(':');
      orario.concat(String(format(now.minute())).c_str());
      orario.toCharArray(orario1, 6);
    */

    Read_Temp();
    mqttClient.loop();
    mqttClient.subscribe("Arduino Temperatura");

    // DHT
    mqttClient.publish("ArduMotica/teperature/Sala", String(t1).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/humidity/Sala", String(h1).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/teperature/Esterna Sala", String(t2).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/humidity/Esterna Sala", String(h2).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/teperature/Esterna Cucina", String(t3).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/humidity/Esterna Cucina", String(h3).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/teperature/Federico", String(t4).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/humidity/Federico", String(h4).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/teperature/Camera Matrimoniale", String(t5).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/humidity/Camera Matrimoniale", String(h5).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/teperature/Francesca", String(t6).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/humidity/Francesca", String(h6).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/teperature/Soffitta", String(t7).c_str());
    delay(100);
    mqttClient.publish("ArduMotica/humidity/Soffitta", String(h7).c_str());
    delay(100);

    // Dallas DS18B20
    printTemperature(insideThermometer);
    if (isnan(tempDALLAS)) {
      Serial.println(F("Errore di lettura DS18B20 CONGELATORE sul pin D33"));
    }
    else {
      mqttClient.publish("ArduMotica/teperature/Congelatore", String(tempDALLAS).c_str());
      delay(100);

    }

    // Contatore KwH
    if (isnan(totPowerValue))
    {
      Serial.println(F("\n Failed to read from KwH Counter_Sensor on pin D19 \n"));
    }
    else
    {
      mqttClient.publish("ArduMotica/consumi/Potenza Impegnata", String(totPowerValue).c_str());
      delay(100);

    }

    // Potenziometro tenda
    StampaApertura();
    if (isnan(Apertura))
    {
      Serial.println(F("\n Failed to read from Trimmer_Sensor on pin A0 \n"));
      delay(100);

    }
    else
    {
      mqttClient.publish("ArduMotica/stati/Tenda", String(Apertura).c_str());
    }


    /*
      delay(100);
      mqttClient.publish("sensorOrario", orario1);
    */
    //delay(5000); // sostituito con millis
  }
}
checkBound(t1, temp, diff));
checkBound(t2, temp, diff));
checkBound(t3, temp, diff));
// ecc

Passi le variabili t1..tn e h1..hn alla funzione.
Se ti serve in confronto col valore precedente allora devi salvarti le varie t e h prima di fare una nuova lettura.
Se non ti sconvolge troppo la logica potresti pensare agli array

int temp[7];
int temp_prec[7];
int hum[7];
int hum_prec[7];

Anche se non hai chiesto in merito, occhio che con le String usate così ti fai male per niente...
Hai un numero che converti in String per poi convertirlo in stringa classica del c...
Prova a guardare la funzione itoa
http://www.cplusplus.com/reference/cstdlib/itoa/

Grazie del consiglio.
A me in realtà servirebbe pubblicare su Mqtt solo i valori con differenza pari a 0.5 ~ 1.0 gradi per non avere mille letture di pochi decimi sui grafici.

Io pensavo di metterle in un ciclo for 1 = 1 to n...
Che ne pensi?

Se usi gli array puoi "automatizzare" con il for.
Cosa intendi con "differenza pari a 0.5 ~ 1.0 gradi"?

fratt:
Se usi gli array puoi "automatizzare" con il for.
Cosa intendi con "differenza pari a 0.5 ~ 1.0 gradi"?

Intendo dire che non vorrei inviare ad Mqtt valori con letture inferiori alla differenza di 0.5 (o 1.0 grado, devo ancora decidere la soglia) tra la lettura precedente e l'attuale, per evitare che nel grafico mi mostri centinaia di letture che discostano di pochi decimi di grado.

Per questo non basta un if tipo questo?

 if (abs(t1 - t1prec) > 1)

fratt:
Per questo non basta un if tipo questo?

 if (abs(t1 - t1prec) > 1)

Credo proprio di si, infatti è stata una delle prime soluzioni che mi sono venute in mente. Vorrei però che il controllo venisse gestito da una funzione per evitare di scriverla su ogni sensore (nell'ottica di implementarne altri) e che, si potesse gestire con un ciclo tipo "for 0 to n" appunto per evitare di stare ad usare quel controllo per ogni sensore (scusa la ripetizione del concetto :stuck_out_tongue: )

I dht te li fa dichiarare come array?
Non ho mai provato...
Se si può potresti fare qualcosa tipo

t[i]  = dht[i].readTemperature();
h[i] = dht[i].readHumidity();

fratt:
I dht te li fa dichiarare come array?
Non ho mai provato...
Se si può potresti fare qualcosa tipo

t[i]  = dht[i].readTemperature();

h[i] = dht[i].readHumidity();

Non saprei. Appena ho un minuto e la possibilità di caricare lo sketch faccio qualche prova.
Dal lavoro purtroppo non riesco. Mi manca tanto infatti la possibilità di caricare sketch senza avere fisicamente sotto le mani la board come si può fare con gli ESP... :cry:

Ero curioso e ho fatto una prova.
Il codice compila senza errori e warnings, ma non ho l'hardware a portata di mano quindi non l'ho provato.

#include "DHT.h"

#define TEMP_PIN 2
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht0(TEMP_PIN, DHTTYPE);
DHT dht1(TEMP_PIN, DHTTYPE);
DHT dht2(TEMP_PIN, DHTTYPE);

DHT* elenco[3];

void setup() {
  Serial.begin(9600);

  *elenco[0] = dht0;
  *elenco[1] = dht1;
  *elenco[2] = dht2;
  
  (*elenco[0]).begin();
  int temperatura = (*elenco[0]).readTemperature();
  int umidita = (*elenco[0]).readHumidity();

  Serial.println(temperatura);
  Serial.println(umidita);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Mi spieghi il passaggio DHT* elenco[3];? Non capisco cosa significa l'asterisco...
Aggiungo che oltre ai DHT nell'array per il controllo vorrei inserire anche alcuni Dallas DS18B20, se possibile.

>ziopippo: 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 eliminato io il "quote" dal tuo post qui sopra :wink:

OK sorry! (Senza quote) :smiling_imp:

L'asterisco è il simbolo del puntatore ...
... in pratica in quel modo fratt crea un array di puntatori ad oggetti di tipo DHT ed a ciascun puntatore assegna poi un oggetto precedentemente creato.

Ti ricordo infatti che scrivere:

DHT dht0(TEMP_PIN, DHTTYPE);

... significa creare un oggetto (dht0) di tipo DHT.

Da provare se la cosa funziona e se la forma è quella giusta :wink:

Il documento allegato protrebbe essere una buona base di partenza da cui cominciare a studiare ... :slight_smile:

Guglielmo

pointers (2).pdf (184 KB)

Perfetto grazie! E' una cosa che ignoravo. Mi studio quanto mi hai consigliato.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.