Blynk 2.0, start timer

Add this function to you code…

BLYNK_CONNECTED()
{
  Blynk.syncVirtual(V1);
  Blynk.syncVirtual(V2);
  Blynk.syncVirtual(V5);  
}

If the problem still persists then show us the full serial monitor results. I need to know if any of the serial print statements are printing when V4 is pressed.

Pete.

Hi Pete,
now everything works as it should. Thank you very much.
What does this function do, or what was the problem before?
ericsson

When the device first connects to Blynk (or when it re-connects after dropping the connection) it requests that the Blynk server sends-out the latest values for each of the virtual pins that are listed.
When these values are sent by the server, the corresponding BLYNK_WRITE(vPin) functions are triggered.

When you boot-up your board, the values for these variables are:

double hyst = 2;
int temp = 0;
int timerZeit; // initialised as 0 because no explicit value is declared.

If you open your Blynk app and change the values of V2 and V5 before changing the value of the V4 widget then temp and timerZeit will no longer be zero, and things will work as expected. However, if you open the app and change the value of V4 it will try to set a timeout timer with a duration of zero milliseconds, because timerZeit = 0
This appears to be causing your divide by zero error…

Guru Meditation Error: Core 1 panic’ed (IntegerDivideByZero). Exception was unhandled.

Pete.

okay great! Thanks a lot for the help. This was really fun and the project works.

1 Like

Hi,
I have another question.
When I have pressed the button in blynk(V4) and the timer is running, the LED(pin13) no longer switches on even though the set temperature has not been reached. Where is the bug, do you have an idea?
Thanks in advance

#define BLYNK_TEMPLATE_ID "TMPLvmzlelxk"
#define BLYNK_DEVICE_NAME "Autoklav3"
#define BLYNK_FIRMWARE_VERSION        "0.1.0"
#define BLYNK_PRINT Serial

#include <max6675.h>
#include <Wire.h>
#include <U8x8lib.h>
#include <U8g2lib.h>
#include "BlynkEdgent.h"                                            //Bibliothek für die Verbindung mit der Blynk App über WLAN

U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);   // Display 128x64 ausgewählt in Bibliothek

int ktcSO = 19;                                                     // ktcSO deklariert und auf PIN 19 initialisiert
int ktcCS = 5;                                                      // ktcCS deklariert und auf PIN 5 initialisiert
int ktcCLK = 18;                                                    // ktcCLK deklariert und auf PIN 18 initialisiert

int LED = 13;                                                       // LED deklariert und PIN 13 initialisiert
double solltemp = 121;                                              // solltemp deklariert und mit 26 initialisiert
double hyst = 2;                                                    // Hystherese deklariert
int temp = 0;                                                       // mit 0 initialisiert, da kein expliziter Wert deklariert wurde. 
int timerZeit = 0;                                                  // mit 0 initialisiert, da kein expliziter Wert deklariert wurde.


bool timer_flag;                                                    // Flag Variable als boolschen Wert um Schleife zu kontrollieren

BlynkTimer timer;

WidgetLED led1(V3);
WidgetLED ledTimer(V6);




MAX6675 ktc(ktcCLK, ktcCS, ktcSO);                                  // Initialisierung Sensor MAX6675 für Temperatur Sensor Typ K


BLYNK_WRITE(V1)                                                     // Schreibt virtuellen PIN 3 in Blynk
{
  solltemp = param.asDouble();                                      // Sollwert = Parameter als Double (für Slider)
}

BLYNK_WRITE(V2)
{
  hyst = param.asDouble();                                          // Hystherese = Parameter als Double (für Slider)
}

BLYNK_WRITE(V5) {
  timerZeit = param.asInt() * 60000;                                // Timer, einstellbar über Slider in Blynk 60.000 Millisekunden = 1 Minute 
}

BLYNK_WRITE(V7)                                                     // Reset des Conrollers über Taster in Blynk APP
{
if (param.asInt()==1) {
delay(100);
ESP.restart();
  } 
}

BLYNK_CONNECTED()                                                   // fordert den Blynk-Server an, die neuesten Werte für jeden der aufgelisteten virtuellen Pins zu senden.
                                                                    // Wenn diese Werte vom Server gesendet werden, werden die entsprechenden BLYNK_WRITE(vPin)-Funktionen ausgelöst
{
  Blynk.syncVirtual(V1);                                            // Solltemperatur, Slider in Blynk
  Blynk.syncVirtual(V2);                                            // Hystherese, Slider in Blynk
  Blynk.syncVirtual(V5);                                            // Timer Zeiteinstellung, Slider in Blynk
}

BLYNK_WRITE(V4)
{
  int pinValue = param.asInt();
  if (pinValue == 1) {
    Serial.print("\nTaste in Blynk wurde gedrückt");
    ledTimer.on();
    timer_flag = true;
    timer.setTimeout(timerZeit, []()
    {
      Serial.print("\nTimer läuft");
      digitalWrite(LED, LOW);
      led1.off();
      ledTimer.off();
      Serial.print("\nTimer ist abgelaufen - ausschalten");
      timer_flag = true;
    });
  }
  else{
    digitalWrite(LED, HIGH);
    led1.on();
    ledTimer.off();
  }
}

void setup()
{
  Serial.begin(9600);                                               // Serielle Schnittstelle, serieller Monitor, Baudrate 9600
  Serial.println("\nMax6675 test");
  pinMode(LED, OUTPUT);                                             // deklariert LED als Output
  timer.setInterval(1000L, sensorDataSend);                         // Timer jede Sekunde werden die Daten gelesen
  
  

  u8x8.begin();
  //Der Bildschirm hat ein Raster aus Bildpunkten
  //Pixel oder Bildpunkt: Ein Kästchen des Rasters

  u8x8.setFont(u8x8_font_7x14_1x2_f);
  // u8x8 Library mit der man sehr einfach Texte darstellen kann, Schriftgröße nur 8x8 Pixel, kaum Schriftarten
  // => wenig Ressourcen
  // bei u8x8 arbeitet man mit Zeilen und Spalten
  // bei u8g2 arbeitet man mit Pixeln

  u8x8.drawString(0, 1, "   Autoklav 3  ");                          // 0. Zeichen von links in der 1. Spalte von oben wird geschrieben
  u8x8.drawString(0, 3, "Temp:");
  u8x8.drawString(0, 5, "Soll:");
  u8x8.drawString(11, 3, " °C");                                     // 11. Zeichen von links in der 3. Spalte von oben wird geschrieben
  u8x8.drawString(12, 5, "°C");
  u8x8.drawString(12, 5, " ");
  u8x8.setCursor(7, 1);

  BlynkEdgent.begin();                                               // Kommunikation mit der Blynk 2.0 App
}




void sensorDataSend() {                                              // Timer: jede Sekunde wird der Sensor ausglesen und ausgegeben
                                                                     // hält den void-loop sauber damit die Blynk Cloud nicht mit Daten überlastet wird

  temp = ktc.readCelsius();
  Blynk.virtualWrite(V0, temp);                                      // Schreibt die gemessene Werte auf die virtuellen PINs in der Blynk APP
  Blynk.virtualWrite(V1, solltemp);
  Blynk.virtualWrite(V2, hyst);
 


  if (timer_flag == false) {                                          // flag als variable
    Serial.print("\nflag ist aus");
    if (ktc.readCelsius() > solltemp)
    {
      digitalWrite(LED, LOW);
      led1.off();
      Serial.print("\nTemperatur ist höher als Soll - ausschalten");
    }
    else if (ktc.readCelsius() <= solltemp - hyst)                    // wenn gemessene Temperatur <= Solltemperatur - Hystherese über Slider in Blynk
    {
      digitalWrite(LED, HIGH);                           // dann LED bzw. Relais an
      led1.on();
      Serial.print("\nTemperatur ist niedriger als Soll - anschalten");
    }
  }

  Serial.print("\nTemperatur = ");                                    // Ausgabe im seriellen Monitor
  Serial.print(ktc.readCelsius());
  Serial.println(" °C");

  u8x8.setCursor(8, 3);                                               // Stellt den Cursor zum schreiben an das 9. Zeichen von links und die 3. Spalte von oben
  if (ktc.readCelsius() < 100) u8x8.drawString(12, 3, " ");           // schreibt eine Leerzeile an angegebene Stelle, wenn der Wert unter 100 ist und die erste Ziffer zu löschen
  u8x8.print(ktc.readCelsius(), 1);                                   // schreibt an der oben genannten Stelle den Messwert (eine Nachkommastelle: ,1)
  u8x8.setCursor(8, 5);
  if (solltemp < 100) u8x8.drawString(12, 5, " ");
  u8x8.print(solltemp, 1);
  if (solltemp <= 0 || solltemp < 10) u8x8.drawString(11, 5, " ");  
}

void loop() {

  BlynkEdgent.run();                                                  // Handshake mit dem Blynk Server
  timer.run();                                                        // startet den Timer (sensorDataSend)
}

Looks like it’s an issue with your timer_flag variable. Shouldn’t you be setting it to false when the timeout timer has ended, instead of to true?

Pete.

When I do this an the timer is running, the LED(pin13) is permanently on.

When you do what?

Pete.

When I set the timer_flag variable to false when the timeout timer has ended.

And what are your serial print messages in sensorDataSend showing you when this occurs?

What exactly is the purpose of the physical LED attached to pin 13 ?

Pete.

The LED is only for control, so I can see if the relais is on or off which is also put on pin 13.

And the answer to the rest of the question?

Pete.

The serial print messages are only the meassured temperature.

What EXACTLY are you seeing in your serial monitor?

Pete.

flag ist aus
Temperatur ist niedriger als Soll - anschalten
Temperatur = 27.75 °C

Taste in Blynk wurde gedrückt
Temperatur = 28.00 °C

Temperatur = 27.75 °C

Temperatur = 28.00 °C

Temperatur = 29.00 °C

Temperatur = 33.00 °C //LED should actually switch off here

Temperatur = 33.50 °C

Timer läuft
Timer ist abgelaufen - ausschalten
flag ist aus
Temperatur ist niedriger als Soll - anschalten
Temperatur = 27.50 °C

flag ist aus
Temperatur ist niedriger als Soll - anschalten
Temperatur = 27.75 °C

I don’t know how else to show it

So clearly neither of these if statements are evaluating as true…

I’d start by changing your sensorDataSend function so that you take a temperature reading at the beginning of the function and save the result to a variable. Then, use this variable throughout the rest of your function so that there is no chance of obtaining differing readings at different points in your function.

Then, add serial print statements immediately after you’ve taken a reading to show the status of the timer_flag, solltemp and hyst variable values.
You could also add a serial print statement to show the result of the soiltemp - hyst calculation.
Do all of this BEFORE any of your if statements.

Pete.

Read through this section of code, and look at the comments that I’ve added. All of these commend have this at the begining: <<<<<<<<<

void sensorDataSend() {                                              // Timer: jede Sekunde wird der Sensor ausglesen und ausgegeben
                                                                     // hält den void-loop sauber damit die Blynk Cloud nicht mit Daten überlastet wird

  temp = ktc.readCelsius(); <<<<<<<<< Reading 1 , saved as temp
  Blynk.virtualWrite(V0, temp);                                      // Schreibt die gemessene Werte auf die virtuellen PINs in der Blynk APP
  Blynk.virtualWrite(V1, solltemp);
  Blynk.virtualWrite(V2, hyst);
 


  if (timer_flag == false) {                                          // flag als variable
    Serial.print("\nflag ist aus");
    if (ktc.readCelsius() > solltemp) <<<<<<<<< temp value not used, a second reading is taken
    {
      digitalWrite(LED, LOW);
      led1.off();
      Serial.print("\nTemperatur ist höher als Soll - ausschalten");
    }
    else if (ktc.readCelsius() <= solltemp - hyst)  <<<<<<<<< temp value not used, a third reading is taken
    {
      digitalWrite(LED, HIGH);                           // dann LED bzw. Relais an
      led1.on();
      Serial.print("\nTemperatur ist niedriger als Soll - anschalten");
    }
  }

  Serial.print("\nTemperatur = ");                                    // Ausgabe im seriellen Monitor
  Serial.print(ktc.readCelsius()); <<<<<<<<< temp value not used, a fourth reading is taken
  Serial.println(" °C");

  u8x8.setCursor(8, 3);                                               // Stellt den Cursor zum schreiben an das 9. Zeichen von links und die 3. Spalte von oben
  if (ktc.readCelsius() < 100) u8x8.drawString(12, 3, " "); <<<<<<<<< temp value not used, a fifth reading is taken
  u8x8.print(ktc.readCelsius(), 1); <<<<<<<<< temp value not used, a sixth reading is taken
  u8x8.setCursor(8, 5);
  if (solltemp < 100) u8x8.drawString(12, 5, " ");
  u8x8.print(solltemp, 1);
  if (solltemp <= 0 || solltemp < 10) u8x8.drawString(11, 5, " ");  
}

As you can see, you are taking up to 6 readings from your sensor during the execution of this function.
You are sending one of these to Blynk, printing another to your serial monitor and apparently sending another to an LCD display. The other readings are being used to drive the logic used within your if statements.

First of all, it’s bad practice to take multiple sensor readings like this, and secondly, how do you know that your sensor is returning the dame values each time?
If you’re looking at the results that are printed in the serial monitor and wondering why the logical if tests are doing at range things then you really want to know if the logical tests are actually basing their decisions on the same data that you are using.
You are already capturing the temperature value at the beginning of the function, why aren’t you using this value in the rest of your function?

Pete.

1 Like

yes of course, you are absolutely right. :see_no_evil:

When I push the switch in blynk(V4)…

BLYNK_WRITE(V4)
{
  int pinValue = param.asInt();
  if (pinValue == 1) {
    Serial.print("\nTaste in Blynk wurde gedrückt");
    ledTimer.on();
    timer_flag = true;
    timer.setTimeout(timerZeit, []()
    {
      Serial.print("\nTimer läuft");
      digitalWrite(LED, LOW);
      led1.off();
      ledTimer.off();
      Serial.print("\nTimer ist abgelaufen - ausschalten");
      timer_flag = false;
    });
  }
  else {
    digitalWrite(LED, HIGH);
    led1.on();
    ledTimer.off();
  }
}

should this function continue to work normally as if i had not pressed the switch in blynk:

if (timer_flag == false) {                                          // flag als variable
    Serial.print("\nflag ist aus");
    if (ktc.readCelsius() > solltemp)
    {
      digitalWrite(LED, LOW);
      led1.off();
      Serial.print("\nRelais/LED ist aus");
      Serial.print("\nTemperatur ist höher als Soll - ausschalten");
    }
    else if (ktc.readCelsius() <= solltemp - hyst)                    // wenn gemessene Temperatur <= Solltemperatur - Hystherese über Slider in Blynk
    {
      digitalWrite(LED, HIGH);                                        // dann LED bzw. Relais an
      led1.on();
      Serial.print("\nRelais/LED ist an");
      Serial.print("\nTemperatur ist niedriger als Soll - anschalten");
    }
  }

It depends what you mean by “Work normally”.

You are setting timer_flag to false in BLYNK_WRITE(V4) for the duration of the t6imeout timer.
This means that the first if test will evaluate as false.

the else if test will then be evaluated and if that evaluates as true then the code that follows will execute.
I take it that you didn’t like my earlier suggestion?

Pete.