Messfrequenz vom DHT11 über Touchdisplay ändern

Hallo ihr lieben,

folgendes Problem:

Ich möchte mit meinem Nextion Display über ein Tastenfeld einem Wert eingeben den ich dann in meinem Arduinocode weiter verwende(in meinem Beispiel als Messfrequenz).

Soweit so klar hoffe ich.

Also ich gebe den Wert (z.b. 1000) in meinem Display ein und drücke auf den "Senden" Button, dann gibt der mir den Wert auch auf dem Seriellen wie auch Physischen Monitor an. Nur leider misst der DHT jetzt nur 1x auf Tastendruck und nicht wie gewünscht aller 1000ms.

was übersehe ich?

long unsigned int start;

#include <SoftwareSerial.h>
#include "DHT.h"
#define pin 2
#define typ DHT11

String endChar = String(char(0xff)) + String(char(0xff)) + String(char(0xff));
String ReceivedData = "";

int long unsigned Data0;
union {
  char charByte[8];
  long valLong;
} value;

SoftwareSerial nextion(12, 13); // RX, TX
DHT dht (pin, typ);

void setup() {
  Serial.begin(9600);
  nextion.begin(9600);
  dht.begin();
}

void loop() {
  if (nextion.available()) {
    ReceivedData += char(nextion.read());
    if (ReceivedData.length() > 8) ReceivedData = "";
  }

  if (ReceivedData.length() == 8) {
    //Serial.println(ReceivedData);
    value.charByte[0] = char(ReceivedData[0]);
    value.charByte[1] = char(ReceivedData[1]);
    value.charByte[2] = char(ReceivedData[2]);
    value.charByte[3] = char(ReceivedData[3]);
    value.charByte[4] = char(ReceivedData[4]);
    value.charByte[5] = char(ReceivedData[5]);
    value.charByte[6] = char(ReceivedData[6]);
    value.charByte[7] = char(ReceivedData[7]);
    value.charByte[8] = char(ReceivedData[8]);
    Data0 = value.valLong;

    Serial.println(Data0);   //gibt im seriellen Monitor den eingetragenen wert vom display ein

    ReceivedData = "";
    nextion.print("n1.val="); 
    nextion.print(Data0);
    nextion.write(0xFF);
    nextion.write(0xFF);
    nextion.write(0xFF);

    Messen(Data0);
  }



}
void Messen(int Messfrequenz) {

  long unsigned int intervall = Messfrequenz;

  if (millis() - start >= intervall)                                             
  {

    float t = dht.readTemperature();                                              // auslesen Temperatur "t"
    float h = dht.readHumidity();                                                 //auslesen Luftfeuchtigkeit "h"
    //***********************************************************************************************************************
    //*                                                 Serielle Ausgabe                                                        *
    //***********************************************************************************************************************

    if (isnan(t) || isnan(h))                                                     //wenn DHT11 nicht angeschlossen
    {
      Serial.println("Sensor kann nicht ausgelesen werden");
      return;
    }

    Serial.print("Temp: ");                                                       //Scheibt Temperaturwert
    Serial.print(t);
    Serial.print("°C \n");

    Serial.print("Feuchtigkeit: ");                                               //Schreibt Luftfeuchtigkeitswert
    Serial.print(h);
    Serial.println("%");

    start = millis();                                                             
  }
}

Lass dir doch mal im seriellen Monitor anzeigen, welchen Wert die Variable "Messfrequenz" hat.

genau den Wert den ich auch auf dem Touchpad eingegeben habe. Ich glaube irgendetwas haut mit der Schleife nicht hin. Denn selbst wenn ich den Wert in der ide eingebe (also anstatt Data0 z.b. 1000) gibt er nur 1x den Wert aus.
Aber mit delay möchte ich auch nicht arbeiten.

ok ich hätte richtiglesen sollen...

Serial.print("Messfrequenz"); meist du sicher..

Serial.print("Feuchtigkeit: ");                                               //Schreibt Luftfeuchtigkeitswert
    Serial.print(h);
    Serial.println("%");
    Serial.print(Messfrequenz);

gibt das aus:

17:05:09.795 -> 1000
17:05:09.795 -> Temp: 29.00°C
17:05:09.842 -> Feuchtigkeit: 51.00%
17:05:09.842 -> 1000

Das liegt an der millis-Funktion.
Bau es mal so ein:

void Messen(unsigned int Messfrequenz) {

  unsigned long currentMillis = millis();
  if (currentMillis - start >= Messfrequenz)   
    start = currentMillis;

danach weiter wie bisher.

wenn ich das richtig sehe, misst du nur, nachdem du valide daten vom Nextion erhalten hast (also z.B. 1000 eingegeben hast),.. wenn du "Messen(Data0);" aus der geschweiften Klammer rausholst, sollte das doch im gewünschten zeitlichen Messabstand ausgeführt werden?

hab beides ausprobiert. Beide male rennt der serielle monitor ohne "Delay" durch.

ich dachte mir das vielleicht hier das Problem liegt:

if (ReceivedData.length() == 8) {                         //<--- eine 1000 ist ja nur 4 bit in ASCII lang. 
    //Serial.println(ReceivedData);
    value.charByte[0] = char(ReceivedData[0]);
    value.charByte[1] = char(ReceivedData[1]);
    value.charByte[2] = char(ReceivedData[2]);
    value.charByte[3] = char(ReceivedData[3]);
    value.charByte[4] = char(ReceivedData[4]);
    value.charByte[5] = char(ReceivedData[5]);
    value.charByte[6] = char(ReceivedData[6]);
    value.charByte[7] = char(ReceivedData[7]);
    value.charByte[8] = char(ReceivedData[8]);
    Data0 = value.valLong;

aber wenn ich == durch <= ersetze hab ich auch keinen "Delay" mehr

Verstehe ich nicht. Was hast du probiert ?
Zeige bitte den aktuellen Sketch. Wie sollen wie so wissen, was du machst.

Versuch doch erst mal ob die Daten vom Nexton nutzbar sind.

void Messen(int Messfrequenz) {
 Serial.println(Messfrequenz); // Zeigt den tatsächlichen Parameter an
  long unsigned int intervall = Messfrequenz;
  intervall=2000; // stellt versuchweise mal 2s ein um das grundsätzlich mal zu testen

  if (millis() - start >= intervall)

der Rest wie im Sketch vom Eingangspost

Heinz

Lt. Post #4, ja.

long unsigned int start;

#include <SoftwareSerial.h>
#include "DHT.h"
#define pin 2
#define typ DHT11

//String endChar = String(char(0xff)) + String(char(0xff)) + String(char(0xff));
String ReceivedData = "";

int long unsigned Data0;
union {
  char charByte[8];
  long valLong;
} value;

SoftwareSerial nextion(12, 13); // RX, TX
DHT dht (pin, typ);

void setup() {
  Serial.begin(9600);
  nextion.begin(9600);
  dht.begin();
}

void loop() {
  if (nextion.available()) {
    ReceivedData += char(nextion.read());
    if (ReceivedData.length() > 8) ReceivedData = "";
  }

  if (ReceivedData.length() == 4) {
    //Serial.println(ReceivedData);
    value.charByte[0] = char(ReceivedData[0]);
    value.charByte[1] = char(ReceivedData[1]);
    value.charByte[2] = char(ReceivedData[2]);
    value.charByte[3] = char(ReceivedData[3]);
    value.charByte[4] = char(ReceivedData[4]);
    /*value.charByte[5] = char(ReceivedData[5]);
    value.charByte[6] = char(ReceivedData[6]);
    value.charByte[7] = char(ReceivedData[7]);
    value.charByte[8] = char(ReceivedData[8]);*/
    Data0 = value.valLong;

    Serial.println(Data0);   //gibt im seriellen Monitor den eingetragenen wert vom display ein

    ReceivedData = "";
    nextion.print("n1.val="); 
    nextion.print(Data0);
    nextion.write(0xFF);
    nextion.write(0xFF);
    nextion.write(0xFF);

    Messen(Data0);
  }



}
void Messen(unsigned int Messfrequenz) {

  unsigned long currentMillis = millis();
  if (currentMillis - start >= Messfrequenz)   
    start = currentMillis;                                             
  {

    float t = dht.readTemperature();                                              // auslesen Temperatur "t"
    float h = dht.readHumidity();                                                 //auslesen Luftfeuchtigkeit "h"
    //***********************************************************************************************************************
    //*                                                 Serielle Ausgabe                                                        *
    //***********************************************************************************************************************

    if (isnan(t) || isnan(h))                                                     //wenn DHT11 nicht angeschlossen
    {
      Serial.println("Sensor kann nicht ausgelesen werden");
      return;
    }

    Serial.print("Temp: ");                                                       //Scheibt Temperatur wert
    Serial.print(t);
    Serial.print("°C \n");

    Serial.print("Feuchtigkeit: ");                                               //Schreibt Luftfeuchtigkeitswert
    Serial.print(h);
    Serial.println("%");
    Serial.print(Messfrequenz);
    start = millis();                                                             
  }
}

Serieller monitor:

1000
18:09:59.828 -> Temp: 31.20°C
18:09:59.875 -> Feuchtigkeit: 48.00%
18:09:59.875 -> 1000

Hast Recht in #4 gibts die Ausgabe schon in #1 war sie nicht drin. :wink:
Gruß Heinz

Du musst am Ende der Funktion "messen" auch das "start = millis()" löschen.

Hallo
die geschweifte Klammer ist an der falschen Stelle. Die gehört hinter die erste Zeile

Da hast du Recht. Das war von mir ein Kopierfehler.
Sorry...

long unsigned int start;

#include <SoftwareSerial.h>
#include "DHT.h"
#define pin 2
#define typ DHT11

String endChar = String(char(0xff)) + String(char(0xff)) + String(char(0xff));
String ReceivedData = "";

int long unsigned Data0;
union {
  char charByte[8];
  long valLong;
} value;

SoftwareSerial nextion(12, 13); // RX, TX
DHT dht (pin, typ);

void setup() {
  Serial.begin(9600);
  nextion.begin(9600);
  dht.begin();
}

void loop() {
  if (nextion.available()) {
    ReceivedData += char(nextion.read());
    if (ReceivedData.length() > 4) ReceivedData = "";
  }

  if (ReceivedData.length() == 4) {
    Serial.println(ReceivedData); //geändert
    value.charByte[0] = char(ReceivedData[0]);
    value.charByte[1] = char(ReceivedData[1]);
    value.charByte[2] = char(ReceivedData[2]);
    value.charByte[3] = char(ReceivedData[3]);
    value.charByte[4] = char(ReceivedData[4]);
    /*value.charByte[5] = char(ReceivedData[5]);
    value.charByte[6] = char(ReceivedData[6]);
    value.charByte[7] = char(ReceivedData[7]);
    value.charByte[8] = char(ReceivedData[8]);*/
    Data0 = value.valLong;

    Serial.println(Data0);   //gibt im seriellen Monitor den eingetragenen wert vom display ein

    ReceivedData = "";
    nextion.print("n1.val="); 
    nextion.print(Data0);
    nextion.write(0xFF);
    nextion.write(0xFF);
    nextion.write(0xFF);

    Messen(1000);
  }



}
void Messen(unsigned int Messfrequenz) {

  unsigned long currentMillis = millis();{ //geändert
  if (currentMillis - start >= Messfrequenz)   
    start = currentMillis;                                             
  

    float t = dht.readTemperature();                                              // auslesen Temperatur "t"
    float h = dht.readHumidity();                                                 //auslesen Luftfeuchtigkeit "h"
    //***********************************************************************************************************************
    //*                                                 Serielle Ausgabe                                                        *
    //***********************************************************************************************************************

    if (isnan(t) || isnan(h))                                                     //wenn DHT11 nicht angeschlossen
    {
      Serial.println("Sensor kann nicht ausgelesen werden");
      return;
    }

    Serial.print("Temp: ");                                                       //Scheibt Temperatur wert
    Serial.print(t);
    Serial.print("°C \n");

    Serial.print("Feuchtigkeit: ");                                               //Schreibt Luftfeuchtigkeitswert
    Serial.print(h);
    Serial.println("%");
    Serial.print(Messfrequenz);
               //gelöscht                                                 
  }
}


Serieller Monitor

⸮ dann ein veireck (lässt sich nicht kopieren bzw wir als leerzeichen kopiert)
18:25:24.062 -> 1000
18:25:24.109 -> Temp: 31.50°C
18:25:24.109 -> Feuchtigkeit: 47.00%
18:25:24.109 -> 1000

ich glaub ich kann das alles so wie es ist in die Tonne treten und fang noch mal neu an.
so viel ist es ja nicht.

Was hast Du denn jetzt gemacht ?
Der Funktionsaufruf Messen(1000) muss aus dem if... raus hinter die schließende Klammer

Heinz
Nachtrag
mir ist auch nicht klar wie die eingegeben Zeichen in die Variable
value.valLong kommen sollen ? Oder hab ich was übersehen ?

Hab ich gemacht. Jetzt sieht der serielle Monitor so aus:

19:04:36.027 -> Feuchtigkeit: 46.00%
19:04:36.027 -> 1000Temp: 31.30°C
19:04:36.074 -> Feuchtigkeit: 46.00%
19:04:36.074 -> 1000Temp: 31.30°C
19:04:36.074 -> Feuchtigkeit: 46.00%
19:04:36.121 -> 1000Temp: 31.30°C
19:04:36.121 -> Feuchtigkeit: 46.00%
19:04:36.168 -> 1000Temp: 31.30°C
19:04:36.168 -> Feuchtigkeit: 46.00%
19:04:36.215 -> 1000Temp: 31.30°C
19:04:36.215 -> Feuchtigkeit: 46.00%
19:04:36.262 -> 1000Temp: 31.30°C
19:04:36.262 -> Feuchtigkeit: 46.00%
19:04:36.309 -> 1000Temp: 31.30°C
19:04:36.309 -> Feuchtigkeit: 46.00%
19:04:36.356 -> 1000Temp: 31.30°C
19:04:36.356 -> Feuchtigkeit: 46.00%
19:04:36.402 -> 1000⸮

ich fang noch mal neu an. vielleicht kann ich das alles etwas einfacher machen.

Darf man hier links posten? denn den Code hab ich mir ja nicht selbst ausgedacht. nur etwas verändert.

Ja, darf man.
Nicht nur den Link, auch eine kurze Erklärung.

Hier erstmal der Link

Da ich, wie Ihr sicher schon gemerkt habt nicht so sicher mit programmieren bin, habe ich nochmal von vorn angefangen und alles nach meinem Verständnis kommentiert.
Hier habe ich aber erstmal nur den DHT11 behandelt. Also ohne Display

#include "DHT.h"                                                          // fügt DHT Bibliothek ein
#define DHTPIN 2                                                          // PIN2 am Arduino ist der Datenpin am DHT11
#define DHTTYPE DHT11                                                     // legt fest welcher DHT Sensor angeschlossen ist
unsigned long altmillis_Dht, neumillis_Dht, intervall_Dht = 2000;         // sagt das altmillis_Dht, neumillis_Dht, intervall_Dht in einem Bereich zwischen 0 und 4,294,967,295 liegen kann !! intervall_Dht habt aber den festen wert 2000

DHT dht(DHTPIN, DHTTYPE);                                                 // DHT wird in Code jetzt mit dht und weist die vorher definierten Parameter fest

void setup() {                                                            // alles bis (*1) läuft nur beim ersten Start EINMMALIG durch
  Serial.begin(9600);                                                     // legt die Bautrate fest (muss gleich zum Seriellen Monitor sein)
  Serial.println("DHT11 Testprogramm\n");                                 // gibt den Text DHT11 Testprogramm  aus
  dht.begin();                                                            // startet den dht11 Sensor
  altmillis_Dht = 0;                                                      // altmillis_Dht wird auf den Wert 0 gesetzt
}                                                                         //(*1)
void loop() {                                                             // Dieser Loop soll nur in weitere Loops weiterleiten
  Dht_auslesen();                                                         // springt zum loop der den Dht11 ausliest
}                                                                         // ende des "weiterleiten" loop




void Dht_auslesen() {                                                     //loop der den Dht11 ausliest



  neumillis_Dht = millis();                                               // Beispiel loop_1: neumills_Dht = 4000    |    Beispiel loop_2 (es sind 10 Sekunden vergangen):  neumills_Dht = 14000
  if ( (neumillis_Dht - altmillis_Dht) >= intervall_Dht) {                // wenn 4000 - 0 größer oder glech 2000    |    wenn 14000 - 4000(=6000) größer oder glech 2000
    altmillis_Dht = neumillis_Dht;                                        // dann setze 0 auf 4000                   |    dann setze 4000 auf 14000
                                                                          // und führe den den code bis (*2) aus     |    und führe den den code bis (*2) aus


    float h = dht.readHumidity();                                         //Dht11 liest Luftfeuchtigkeitswert(h)
    float t = dht.readTemperature();                                      //Dht11 liest Temperaturwert(t)

    if (isnan(h) || isnan(t)) {                                           //(*3)wenn (h) und/oder (t) nicht gelesen werden können (z.b. kaben an PIN2 ab)
      Serial.println("Fehler beim auslesen des Sensors!");                //dann schreibe "Fehler beim auslesen des Sensors!"
      return;                                                             // und springe zm Anfang(*3) ansonsten einfach weiter
    }
    Serial.print("Luftfeuchtigkeit: ");
    Serial.print(h);                                                      // Ausgeben der Luftfeuchtigkeit
    Serial.print("%\n");                                                  // Neue Zeile(\n) im Seriellen Monitor
    Serial.print("Temperatur: ");
    Serial.print(t);                                                      // Ausgeben der Temperatur
    Serial.write('°');                                                    // Schreiben das ° Zeichen
    Serial.print("C\n\n");                                                // lässt eine Zeile Platz
  }                                                                       //*2
}

meine Frage wäre jetzt:

kann man den Wert von intervall_Dht = 2000 ganz oben über externe Eingabe (in meinem fall der Nextion) ändern?

ich denke nicht da sich die Zeile nicht in einem Loop befindet oder?