Sketch Erweiterung NodeMCU mit Arduino 1.8.13 in Verbindung mit Blynk

Hallo Leute,

hab da so ein Problem. Vorweg möchte ich noch anmerken ich kennen mich mit Programmierungen nicht richtig aus.

Also: Ich habe eine NodeMCU Amica an dem zwei DS18B20 Temperaturfühler dran hängen.
Diese schicken die Daten an Blynk und somit auf mein Handy - soweit so gut.

Die Idee war nun, dass Blynk mich benachrichtigt wenn die Temp2 höher als die Temp1 ist.
Das habe ich mit folgenden Code geschaft:

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2//D4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
BlynkTimer timer;

char auth[] = "XXX";

char ssid[] = "xx";
char pass[] = "xx";

float  temp1 = 0;
float  temp2 = 0;


void setup()
{
  
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  sensors.begin();
// Setup a function to be called every second  
  timer.setInterval(3400L, sendTemps);
  delay(500);
}

void sendTemps()
{
  sensors.requestTemperatures(); //Call all sensors on one wire to start calculating the temperature readings

  temp1=sensors.getTempCByIndex(0);
 sensors.requestTemperatures();
 temp1 = sensors.getTempCByIndex(0);
 Serial.println(String("Sıcaklik=")+temp1+ String(" C"));
 Blynk.virtualWrite(V1, temp1);

delay(500);

sensors.requestTemperatures(); //Call all sensors on one wire to start calculating the temperature readings

  temp2=sensors.getTempCByIndex(1);
 sensors.requestTemperatures();
 temp2 = sensors.getTempCByIndex(1);
Serial.println(String("Sıcaklik=")+temp2+ String(" C"));
 Blynk.virtualWrite(V2, temp2);


 if(temp2 > temp1){
    Blynk.notify("Pumpe an");
  }
}
void loop()
{
  Blynk.run();
  timer.run();
  delay(500);
}

Jetzt zum Problem: Bei jedem Durchlauf bekomme ich nun eine Benachrichtigung (ca. alle 2 Sek.). Es soll aber nur eine Meldung kommen wenn Temp2 den wert von temp1 übersteigt.
Hat da jemand eine Idee?

In Excel mit Vba hätte ich es so gelöst:
Sub iMeldung()

' Zulauf Pool
If Cells(2, 2) < Cells(2, 1) Then
Range("C1").Value = 0
End If

' Pool Zulauf
If Cells(2, 1) < Cells(2, 2) And Range("c1").Value = 0 Then
MsgBox "Pumpe start", vbOKOnly
Range("C1").Value = 1
End If

End Sub

Habe schon versucht es ins Arduino rein zu bekommen, aber es kommen immer Fehlermeldungen.
Denke ich bräuchte eine Globale Variable, leider kommt beim Prüfen dann immer der Fehler: exit status 1
'OneWire oneWire' previously declared here
Hier der Code dazu:

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2//D4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
BlynkTimer timer;

char auth[] = "xx";


char ssid[] = "xx";
char pass[] = "xx";

float  temp1 = 0;
float  temp2 = 0;
byte w = 0;


void setup()
{
  
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  sensors.begin();
// Setup a function to be called every second  
  timer.setInterval(3400L, sendTemps);
  delay(500);
}

void sendTemps()
{
  sensors.requestTemperatures(); //Call all sensors on one wire to start calculating the temperature readings

  temp1=sensors.getTempCByIndex(0);
 sensors.requestTemperatures();
 temp1 = sensors.getTempCByIndex(0);
 Serial.println(String("Sıcaklik=")+temp1+ String(" C"));
 Blynk.virtualWrite(V1, temp1);

delay(500);

sensors.requestTemperatures(); //Call all sensors on one wire to start calculating the temperature readings

  temp2=sensors.getTempCByIndex(1);
 sensors.requestTemperatures();
 temp2 = sensors.getTempCByIndex(1);
Serial.println(String("Sıcaklik=")+temp2+ String(" C"));
 Blynk.virtualWrite(V2, temp2);

if (temp2 < temp1){
  w = 0;
}


 if(temp2 > temp1 && w==0){
    Blynk.notify("Pumpe an");
    w = 1;
  }
}
void loop()
{
  Blynk.run();
  timer.run();
  delay(500);
}

Vielleicht kann mir einer hierbei weiter helfen. Ist leider schwerer als gedacht
Danke euch im Voraus

Nur ne Idee, ist halt nen Klassiker.


void sendTemps()
{
  static bool sendMerker=false;
  sensors.requestTemperatures(); //Call all sensors on one wire to start calculating the temperature readings

  temp1 = sensors.getTempCByIndex(0);
  sensors.requestTemperatures();
  temp1 = sensors.getTempCByIndex(0);
  Serial.println(String("Sıcaklik=") + temp1 + String(" C"));
  Blynk.virtualWrite(V1, temp1);

  delay(500);

  sensors.requestTemperatures(); //Call all sensors on one wire to start calculating the temperature readings

  temp2 = sensors.getTempCByIndex(1);
  sensors.requestTemperatures();
  temp2 = sensors.getTempCByIndex(1);
  Serial.println(String("Sıcaklik=") + temp2 + String(" C"));
  Blynk.virtualWrite(V2, temp2);


  if (temp2 > temp1) {
    if (sendMerker == false)
    {
    Blynk.notify("Pumpe an");
    sendMerker=true;
    }
  }
  else
  {
    sendMerker=false;
  }
}
1 Like

Perfekt!
Vielen Dank

Naja, nicht ganz.
Ich würde das anders lösen. Du hast im Moment:

  • keine Hysterese, damit würde ein "schaukeln" zwischen den Werten je eine Meldung auslösen
  • keine zeitliche Beschränkung in Bezug auf die mögliche Anzahl an Messages
  • noch ein delay() drin...

Da ist noch ganz viel Potential :wink:
Aber danke für die Rückmeldung, das es funktioniert.

Danke für die Hinweise. Allgemein bin ich heilfroh das es überhaupt iwie funktioniert. Aber natürlich hast du wahrscheinlich (sehr) recht, deshalb:

Zu Punkt 1: Auch wenn ich persönlich noch nicht soweit bin, ist das wohl korrekt. Hm, vielliecht kann man das lösen wenn Temp1+x macht? ODer gibt es dazu eine Profilösung?

Zu Punkt2: Da erschließt sich mir der Voteil noch nicht. Wenn temp2 höher ist muss ja eine Meldung. Egal wie oft das passiert pro Zeiteinheit. Ja, mein Handy wird mich zumüllen mit Meldungen.

Zu Punkt3: Die Delay() streue ich immer mal mit ein, in der Hoffung der Prozessor hat so ein schöneres Leben. Habe schon gehört dass das nicht sehr Professionell sein soll, habe aber bisher auch keine negatven auswirkungen gemmerkt. Welches delay() stört dich und warum?

Da du mir einen sehr komponenten Eindruck machst habe ich jetzt noch zwei weitere Anliegen :slight_smile: :

  1. Der Wert temp1 soll um x höher (WIe bereits in Punkt1 erwähnt). Zum testen hätte ich jetzt einfach mal +2 gemacht
  2. Und eine meldung wenn der wert temp2<temp1 ist (pumpe aus) wäre noch gut.

habe es so versucht, aber natürlich kam wieder eine Fehlermeldung (Ich sollte VBA bleiben):

void sendTemps()
{
  static bool sendMerker=false;
  static bool sendMerker2=false;
  
  sensors.requestTemperatures(); //Call all sensors on one wire to start calculating the temperature readings

  temp1 = sensors.getTempCByIndex(0);
  sensors.requestTemperatures();
  temp1 = sensors.getTempCByIndex(0);
  Serial.println(String("Sıcaklik=") + temp1 + String(" C"));
  Blynk.virtualWrite(V1, temp1);

  delay(500);

  sensors.requestTemperatures(); //Call all sensors on one wire to start calculating the temperature readings

  temp2 = sensors.getTempCByIndex(1);
  sensors.requestTemperatures();
  temp2 = sensors.getTempCByIndex(1);
  Serial.println(String("Sıcaklik=") + temp2 + String(" C"));
  Blynk.virtualWrite(V2, temp2);


  if (temp2 > temp1+2) {
    if (sendMerker == false)
    {
    Blynk.notify("Pumpe an");
    sendMerker=true;
    }
  }
  else
  {
    sendMerker=false;
  }


    if (temp2 < temp1) {
    if (sendMerker2 == false)
    {
    Blynk.notify("Pumpe aus");
    sendMerker2=true;
    }
  }
  else
  {
    sendMerker2=false;
  }
}

Für jede Antwort bedanke ich mich im Voraus.
Gute Nacht

Oh, las das keinen hören ...

Was ist eine Profilösung?
Also das mit dem hoch und runter rechnen ist schon passend.
Dabei gibt es aber auch unterschiedliche Varianten.
Es kommt drauf an, was Du haben willst.
Wenn Du jetzt einen Unterschied von 2K haben willst, dann kannst das aufaddieren, bzw. nach unten hin abziehen.

Das ändert aber das Verhalten des senden nicht.
Wenn T1 18 und T2 20, wird gesendet - wird der Wert unterschritten, wird der Merker zurückgesetzt.
Also musst versuchen, den Merker "verzögert" zu ändern.

Ok. Den las dann so ...

Mich stört jedes delay().
Auch stört mich das auslesen der Sensoren wie Du es machst.
Je nach Auflösung geht Dir bei jedem

sensors.requestTemperatures();

bis zu 750 ms den Bach runter.
Das stört den Aufruf von Blynk.run und das timer.run
Also muss das Blockadefrei gemacht werden.

Ich hab mal was zusammengebaut.

void loop()
{
  static unsigned long lastMillis = 0;
  const unsigned long waitTime = 1000; // Zeit in ms
  Blynk.run();
  timer.run();
  getTemps();
  if (millis() - lastMillis >= waitTime)
  {
    setPump();
    sendTemps();
    lastMillis=millis();
  }
}


void getTemps()
{
  static unsigned long lastMillis = 0;
  const unsigned long waitTime = 750; // je nach Auflösung der Sensoren
  if (millis() - lastMillis > waitTime)
  {
    temp1 = sensors.getTempCByIndex(0);
    temp2 = sensors.getTempCByIndex(1);
    sensors.requestTemperatures();
    lastMillis = millis();
  }
}

void setPump()
{
  static bool sendMerker = false;
  const float hysterese = 2.0;

  if (temp2 > temp1 + hysterese)
  {
    if (sendMerker == false)
    {
      Serial.print(F("Pumpe an bei T1: "));
      Serial.print(temp1);
      Serial.print(F(" T2: "));
      Serial.println(temp2);
      Blynk.notify("Pumpe an");
      sendMerker = true;
    }
  }
  else if (temp2 < temp1 - hysterese)
  {
    if (sendMerker == false)
    {
      Serial.print(F("Pumpe aus bei T1: "));
      Serial.print(temp1);
      Serial.print(F(" T2: "));
      Serial.println(temp2);
      Blynk.notify("Pumpe aus");
      sendMerker = true;
    }
  }
  // [edit] hier stand ein || drin - das ist falsch, muss natürlich && sein
  else if (temp2 > temp1 + hysterese / 2 && temp2 < temp1 - hysterese / 2)
  {
Serial.println(F("Setze Merker zurück"));
    sendMerker = false;
  }
}

void sendTemps()
{
  Serial.println(String("Sıcaklik=") + temp1 + String(" C"));
  Blynk.virtualWrite(V1, temp1);

  Serial.println(String("Sıcaklik=") + temp2 + String(" C"));
  Blynk.virtualWrite(V2, temp2);
}

Kurze Erklärung:
Erstmal in einzelne Funktionen aufgeteilt, damit das übersichtlich wird.
Die Funktionen setPump und setTemps wird jetzt nur alle 1Sekunde aufgerufen.

In der Funktion getTemps werden erst die Sensoren ausgelesen, dann wird ein neuer Zyklus gestartet und erst wenn die Zeit abgelaufen ist, werden die Sensoren wieder gelesen usw. In der Zwischenzeit kann also alles andere passieren....

Im setPump habe ich jetzt Deine 2.0K genommen und als Auf- bzw. Abschlag eingerechnet.
Und für das zurücksetzen des Merkers wird die Hälfte des Auf-/Abschlages genommen, damit Du nicht bei jeder 0,01K Änderung ne Meldung bekommst.

Probier es aus - ich hab das "blind" gemacht - da ich keinen ESp habe....

Hat er definitiv nicht. Der arbeitet eine Instruktion nach der anderen ab - welche, das ist ihm egal. Bei delay() macht er halt was anderes (nämlich Zeitgeber holen und vergleichen) als wenn er sinnvollen Code abarbeiten darf.
Du machst Dir aber damit das Leben deutlich weniger schön - auch wenn es auf den ersten Blick anders aussehen mag.

Das hab ich nicht geschrieben :wink:

Mahlzeit,
und wieder schnelle Antworten - vielen Dank dafür.

Zu den Delay: Ok, habe ich verstanden - hört sich logisch an. Eine Frage: Ist das waitTime generell besser?

Jetzt zum eigentlichen Gegenstand:
Habe den Code auf dem ESP geladen - Problem: Es kommen keine Meldungen mehr an (Nur einmal, nachdem er Saft bekommt)

Code:

`#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 2//D4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
BlynkTimer timer;

char auth[] = "xx";

char ssid[] = "x";
char pass[] = "x";


float  temp1 = 0;
float  temp2 = 0;

void setup()
{
  
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  sensors.begin();
// Setup a function to be called every second  
  timer.setInterval(3400L, sendTemps);
  delay(500);
}

//von my_xy_projekt (https://forum.arduino.cc/t/sketch-erweiterung-nodemcu-mit-arduino-1-8-13-in-verbindung-mit-blynk/865536) :

void loop()
{
  static unsigned long lastMillis = 0;
  const unsigned long waitTime = 1000; // Zeit in ms
  Blynk.run();
  timer.run();
  getTemps();
  if (millis() - lastMillis >= waitTime)
  {
    setPump();
    sendTemps();
    lastMillis=millis();
  }
}


void getTemps()
{
  static unsigned long lastMillis = 0;
  const unsigned long waitTime = 750; // je nach Auflösung der Sensoren
  if (millis() - lastMillis > waitTime)
  {
    temp1 = sensors.getTempCByIndex(0);
    temp2 = sensors.getTempCByIndex(1);
    sensors.requestTemperatures();
    lastMillis = millis();
  }
}

void setPump()
{
  static bool sendMerker = false;
  const float hysterese = 2.0;

  if (temp2 > temp1 + hysterese)
  {
    if (sendMerker == false)
    {
      Serial.print(F("Pumpe an bei T1: "));
      Serial.print(temp1);
      Serial.print(F(" T2: "));
      Serial.println(temp2);
      Blynk.notify("Pumpe an");
      sendMerker = true;
    }
  }
  else if (temp2 < temp1 - hysterese)
  {
    if (sendMerker == false)
    {
      Serial.print(F("Pumpe aus bei T1: "));
      Serial.print(temp1);
      Serial.print(F(" T2: "));
      Serial.println(temp2);
      Blynk.notify("Pumpe aus");
      sendMerker = true;
    }
  }
  // [edit] hier stand ein || drin - das ist falsch, muss natürlich && sein
  else if (temp2 > temp1 + hysterese / 2 && temp2 < temp1 - hysterese / 2)
  {
Serial.println(F("Setze Merker zurück"));
    sendMerker = false;
  }
}

void sendTemps()
{
  Serial.println(String("Sıcaklik=") + temp1 + String(" C"));
  Blynk.virtualWrite(V1, temp1);

  Serial.println(String("Sıcaklik=") + temp2 + String(" C"));
  Blynk.virtualWrite(V2, temp2);
}
// Ende Code https://forum.arduino.cc/t/sketch-erweiterung-nodemcu-mit-arduino-1-8-13-in-verbindung-mit-blynk/865536
  void loop2()
{
  Blynk.run();
  timer.run();
  delay(500);
}`

Nee, hast Du nicht.
Ich weiß jetzt nicht mehr, ob ich aus Deinem Zitat oder aus dem Original zitiert habe.
Ersteres wäre möglich, dann bitte ich, diese Nachlässigkeit zu entschuldigen!

:slight_smile: :slight_smile: :slight_smile:
(Was das wieder für ne Kacke - Drei Smileys senden geht nicht ohne Text)

Ich schau drauf...
Mooment:

`#define BLYNK_PRINT Serial

Da ist nen Zeichen zuviel

Mein erster Versuch war doch richtig.
Also wieder zurück - aus den && ein || machen.
Ich hab die Zeile noch verändert:

  else if ((temp2 > temp1 + hysterese / 2 || temp2 < temp1 - hysterese / 2) && sendMerker==true)

Dann kommt sowas raus:

12:44:28.487 -> Sıcaklik=24.69 C
12:44:28.487 -> Sıcaklik=26.31 C
12:44:29.813 -> Sıcaklik=24.75 C
12:44:29.813 -> Sıcaklik=26.63 C
12:44:31.138 -> Pumpe an bei T1: 24.81 T2: 26.87
12:44:31.138 -> Sıcaklik=24.81 C
12:44:31.138 -> Sıcaklik=26.88 C
12:44:32.465 -> Sıcaklik=24.88 C
12:44:32.465 -> Sıcaklik=27.06 C
12:44:33.757 -> Sıcaklik=24.94 C
12:44:33.757 -> Sıcaklik=27.25 C
12:44:35.084 -> Sıcaklik=25.00 C
12:44:35.084 -> Sıcaklik=27.06 C
12:44:36.411 -> Setze Merker zurück
12:44:36.411 -> Sıcaklik=25.00 C
12:44:36.411 -> Sıcaklik=26.75 C
12:44:37.739 -> Sıcaklik=25.00 C
12:44:37.739 -> Sıcaklik=26.56 C

Super, funktioniert.
Vielen Dank!

Dann kann der Sommer kommen :slight_smile:

Na dann.. Allles Gute!