Long story short, I’ll lose control through the app of my relay controller. Code worked fine until I introduced a second timer, then code freezes up. From everything I read, it seems like my board might be losing connection to the blynk server? The solutions I found through the search feature don’t really apply to my problem from what I could understand. That’s why I’m posting… I must be missing something obvious. Maybe I can’t use the same SimpleTimer object for both functions? I’m stuck!
/*************************************************************
Blynk is a platform with iOS and Android apps to control
Arduino, Raspberry Pi and the likes over the Internet.
You can easily build graphic interfaces for all your
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: http://www.blynk.cc
Blynk community: http://community.blynk.cc
Social networks: http://www.fb.com/blynkapp
http://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This example shows how value can be pushed from Arduino to
the Blynk App.
WARNING :
For this example you'll need SimpleTimer library:
https://github.com/jfturcot/SimpleTimer
and Adafruit DHT sensor libraries:
https://github.com/adafruit/Adafruit_Sensor
https://github.com/adafruit/DHT-sensor-library
App project setup:
Value Display widget attached to V5
Value Display widget attached to V6
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "f167b6cd9573434ea26cea6542ad6c1f";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "****";
char pass[] = "***";
float tempTemp,tempTemp1,tempTemp2,tempTemp3;
float pinData22, pinData23, pinData24 = 0;
int autoOrManual, tempThreshold;
SimpleTimer timer;
bool isFirstConnect = true;
BLYNK_CONNECTED()
{
if (isFirstConnect){Blynk.syncAll();}
isFirstConnect = false;
}
BLYNK_WRITE(V22)
{
pinData22 = param.asFloat(); // pinData variable will store value that came via Bridge
}
BLYNK_WRITE(V23)
{
pinData23 = param.asFloat(); // pinData variable will store value that came via Bridge
}
BLYNK_WRITE(V24)
{
pinData24 = param.asFloat(); // pinData variable will store value that came via Bridge
}
void setTemp();
void calculatedTemp()
{
tempTemp1 = pinData22+pinData23;
tempTemp1 = tempTemp1/2;
Blynk.virtualWrite(V7,tempTemp1);
tempTemp2 = pinData23+pinData24;
tempTemp2 = tempTemp2/2;
Blynk.virtualWrite(V8,tempTemp2);
tempTemp3 = pinData22+pinData24;
tempTemp3 = tempTemp3/2;
Blynk.virtualWrite(V9,tempTemp3);
tempTemp = pinData22+pinData23+pinData24;
tempTemp = tempTemp/3;
Blynk.virtualWrite(V6, tempTemp);
// setTemp();
}
BLYNK_WRITE(V0)
{
tempThreshold = param.asInt();
//Serial.print(tempThreshold);
}
BLYNK_WRITE(V1)
{
autoOrManual = param.asInt();
//Serial.println(autoOrManual);
}
void setTemp()
{
Serial.println(autoOrManual);
if (autoOrManual == 1){Serial.print("on manual\r\n");}//return;}
else
{
if ((tempThreshold+5) < (int)tempTemp2)
{
Serial.println(tempThreshold);
Serial.println((int)tempTemp2);
Serial.print("turning on AC\r\n");
digitalWrite(13,1);
digitalWrite(12,1);
}
else if (tempTemp2 <= (tempThreshold - 5))
{
Serial.print("temp at threshold\r\n");
digitalWrite(13,0);
digitalWrite(12,0);
}
else
{
Serial.print("AC off\r\n");
digitalWrite(13,0);
digitalWrite(12,0);
}
}
}
void setup()
{
// Debug console
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
// You can also specify server:
//Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
//Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8442);
// Setup a function to be called every time period
timer.setInterval(1000L, calculatedTemp);
timer.setInterval(2000L, setTemp);
}
void loop()
{
Blynk.run();
timer.run(); // Initiates SimpleTimer
}
Most likely because your issue is just a bad code segment, not a timer or Blynk command issue.
Have you tried creating some additional print statements in various parts of your code and running it while hooked up to USB and the serial monitor… effectively tracking where your program is when it stalls?
PS, the way you have your timers set, both functions will run at the same time every 2 seconds… stagger them a bit more, i.e. every second and every 1.9 seconds… this way they may eventually coincide, but not as often (arrgg, math )
I wondered about that. Does one cause an interrupt in the middle of the other? I will stagger the times and see what happens! I will add some more debugging stuff. I was trying to avoid having to wait some big amount of time to see where it hangs up and hoping it would be obvious! Dang. I will report back ASAP.
So I changed the timer frequency calls. In my calculatedTemp() function after the third Blynk virtual write I see the “Blynk connected ping…” And it resumes running the code. Is that something to look into?
Does the esp need to refresh the connection to the Blynk servers periodically?
Yes, there is a timeout of sorts that if for simplicitys sake, you don’t do a Blynk.run for more than 10 seconds you get disconnected. Also esp has an internal watch dog that kicks in if you don’t yield() or reach loop end every X seconds, can’t remember really.
Hence why void loop should be short, especially for beginners.
After my first conversion. It seems to choke right there for a few seconds, then it connects again and continues. However, I have lost control through the app.
That was added to declare the function before it was defined since I was going to call setTemp() from calculatedTemp() in a previous attempt. I’ll remove it. Does declaring functions not work in the arduino IDE?
commented out 3 of the 4 Blynk.virtualWrite() functions.
with #1 I noticed the same hangup as before where the Serial output stalls during calculatedTemp() function and my Blynk app loses the ability to control anything.
with #2 it seems to be working without any delays. Is there a max frequency I can update with a Blynk.virtualWrite() call?
Good point. I suppose it’s more of a habit more than anything. I’m sure it doesn’t affect anything.
I cleaned up my code with what appears to be working correctly. I believe the problem was trying to write too many times per second with the Blynk.virtualWrite() function calls.
/*************************************************************
Blynk is a platform with iOS and Android apps to control
Arduino, Raspberry Pi and the likes over the Internet.
You can easily build graphic interfaces for all your
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: http://www.blynk.cc
Blynk community: http://community.blynk.cc
Social networks: http://www.fb.com/blynkapp
http://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
*************************************************************/
//#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "f2ad6c1f";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "";
char pass[] = "";
/*******************************************
* Globals
*******************************************/
float tempTemp,tempTemp1,tempTemp2,tempTemp3;
float pinData22, pinData23, pinData24 = 0;
int autoOrManual, tempThreshold;
SimpleTimer timer;
WidgetRTC rtc;
/**********************************************************
* function called on first connect with Blynk
* servers
*
* Blynk.syncAll() grabs the data from the app
* like whether in auto or manual mode and
* temp threshold and actual temperature
*
* rtc.begin() creates Real Time Clock object from the
* RTC widget in the app for use with the
* ESP device
***********************************************************/
bool isFirstConnect = true;
BLYNK_CONNECTED()
{
if (isFirstConnect){Blynk.syncAll();}
isFirstConnect = false;
rtc.begin();
}
/**************************************************
* Data passed from app/other devices to this device
* V0 - app widget sends integer between 50F and 90F
* V1 - app widget butten sends 0(auto) or 1(manual).
* Manual mode will bypass setTemp() control of
* the AC in the function
* V22 - device 1
* V23 - device 2
* V24 - device 3
**************************************************/
BLYNK_WRITE(V22)
{
pinData22 = param.asFloat(); // pinData variable will store value that came via Bridge
}
BLYNK_WRITE(V23)
{
pinData23 = param.asFloat(); // pinData variable will store value that came via Bridge
}
BLYNK_WRITE(V24)
{
pinData24 = param.asFloat(); // pinData variable will store value that came via Bridge
}
BLYNK_WRITE(V0)
{
tempThreshold = param.asInt();
//Serial.print(tempThreshold);
}
BLYNK_WRITE(V1)
{
autoOrManual = param.asInt();
//Serial.println(autoOrManual);
}
/*************************************************************
* tempTemp1 - averages devices 1 and 2 and writes it to V7
* tempTemp2 - averages devices 2 and 3 and writes it to V8
* tempTemp3 - averages devices 1 and 3 and writes it to V9
* tempTemp - averages devices 1, 2, and 3 and writes it to V6
* yield() function is (need to read up on this one)
*************************************************************/
void calculatedTemp()
{
tempTemp1 = pinData22+pinData23;
tempTemp1 = tempTemp1/2;
// Blynk.virtualWrite(V7,tempTemp1);
yield();
tempTemp2 = pinData23+pinData24;
tempTemp2 = tempTemp2/2;
Blynk.virtualWrite(V8,tempTemp2);
yield();
tempTemp3 = pinData22+pinData24;
tempTemp3 = tempTemp3/2;
// Blynk.virtualWrite(V9,tempTemp3);
yield();
tempTemp = pinData22+pinData23+pinData24;
tempTemp = tempTemp/3;
// Blynk.virtualWrite(V6,tempTemp);
yield();
// clockDisplay();
}
/************************************************
* setTemp() checks V1 whether mode is set to
* auto or manual
* if manual -> exit function
* if auto -> proceed to control AC based on
* set point
* takes setpoint from the app on channel V0 and
* compares it to the averaged temperature calculated
* in calculatedTemp() then proceeds to control
* AC to get temperature to within threshold with
* some minor hysteresis.
************************************************/
void setTemp()
{
if (autoOrManual == 1)
{
// Serial.print("on manual\r\n");
}
else
{
if ((tempThreshold+5) < (int)tempTemp2)
{
digitalWrite(13,1);
digitalWrite(12,1);
}
else if (tempTemp2 <= (tempThreshold - 5))
{
digitalWrite(13,0);
digitalWrite(12,0);
}
else
{
digitalWrite(13,0);
digitalWrite(12,0);
}
}
// clockDisplay();
}
/***************************************************
* clockDisplay() function is for debugging purposes.
* uncomment this function call at the end of the other
* functions to spit out the time.
***************************************************/
void clockDisplay()
{
String currentTime = String(hour()) + ":" + minute() + ":" + second();
String currentDate = String(day()) + " " + month() + " " + year();
Serial.print("Current time: ");
Serial.print(currentTime);
Serial.println();
}
/**********************************************
* arduino setup
* timer functions required different values
* to avoid potential conflicts when being
* called at the same time
**********************************************/
void setup()
{
// Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
while(Blynk.connect() == false); // seen in other examples, not
// not sure if useful
timer.setInterval(1357L, calculatedTemp);
timer.setInterval(2468L, setTemp);
// clockDisplay();
}
void loop()
{
Blynk.run();
timer.run();
// clockDisplay();
}