Hi Folks!
First time with Blynk. Everything is great, except for one thing: every Blynk.virtualWrite I run takes a LOT more time than I would have expected, somewhere on the order of 200ms per write. That means that if I have multiple writes, it takes over a second, which really messes up some of my other functions. I would really like to be able to update 2-6 variables per second and have my loops each take under 100ms if possible.
Similarly, if I press a button rapidly (say, 5 times), it holds up my arduino enough that the app thinks itâs disconnected. Thatâs not an actual use case for me, just helping add to debugging and identifying the problem.
Is this just a hardware/software limitation? Am I doing something wrong? Can I edit the libraries to make this work better? THANKS IN ADVANCE!!
For details:
- I am using a local server
- Hardware is an Arduino Mega communicating through an esp8266 wifi module
- I am not using delays of any kind, except in the setup.
- Sketch below is lightly edited to remove some extraneous functions
- Yes, I am using timers to avoid writing every loop
edit to add: - The pause ONLY occurs when the virtualwrite command is triggered (on timer). Almost all iterations take only a handful of milliseconds, except for those in which the virtualwrite is triggered
- If I comment out the virtualwrite command, the whole thing runs quickly and smoothly
- If I uncomment more of the virtualwrite commands, the delay becomes larger, leading me to conclude that the problem is the virtualwrite commands, NOT anything to do with the rest of the code.
edit again: - Commenting out the other things in the main loop does not solve my issue.
- Iteration time measured from serial monitor printing (not shown).
// Libraries
#include <Adafruit_MAX31865.h>
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <PID_v1.h>
#include <PID_AutoTune_v0.h>
#include <EEPROM.h>
// General definitions
#define ON 0
#define OFF 1
// Pin setup
// Arduino physical pins
// Temp probe pins
const int pin_probe_1_CLK = 13;
const int pin_probe_1_SDO = 12;
const int pin_probe_1_SDI = 11;
const int pin_probe_1_CS = 10;
// Relay board (element safety, pump, other)
const int pin_relay_600w = 42;
const int pin_relay_1000w = 43;
const int pin_relay_pump_1 = 40;
// Float switch / binary sensors
const int pin_FS_MT;
// EEPROM value addresses
// temp control PID values
const int ER_address_PID_1_mode_1_kp = 1;
const int ER_address_PID_1_mode_1_ki = 2;
const int ER_address_PID_1_mode_1_kd = 3;
// temp control offsets
const int ER_address_temp_probe_1_offset = 10;
// Variable declaration
// Blynk and network authentication
char ssid[] = "WIFISSID";
char pass[] = "PASSWORD";
char auth[] = "TOKEN";
char IPaddress[] = "IP";
#define EspSerial Serial1
#define ESP8266_BAUD 115200
ESP8266 wifi(&EspSerial);
// Initialize temp probe objects
Adafruit_MAX31865 temp_probe_1 = Adafruit_MAX31865(pin_probe_1_CLK, pin_probe_1_SDO, pin_probe_1_SDI, pin_probe_1_CS);
// Timer
int timer_start;
// Mode selection;
String control_mode="Manual";
// temp current and target
double temp_target=0;
int temp_target_holding = 0;
double temp_probe_1_current;
// temp probe 1 offset
double temp_probe_1_offset;
double temp_probe_1_offset_level_holding;
// Element power level (expressed as 0-100)
double element_power_level=0;
// PID settings
double PID_1_mode_1_kp;
double PID_1_mode_1_ki;
double PID_1_mode_1_kd;
// Initialize PID object
PID main_PID(&temp_probe_1_current, &element_power_level, &temp_target,0,0,0,P_ON_M, DIRECT);
// Set update timer for updating monitored values
BlynkTimer update_temp_timer;
long update_mon_interval = 1000;
// Initialize Blynk LEDs
WidgetLED LED_600w(V101);
WidgetLED LED_1000w(V102);
WidgetLED LED_pump_1(V103);
WidgetLED LED_MT_FS(V104);
WidgetLCD lcd(V100);
void setup()
{
// Start serial console
Serial.begin(9600);
delay(10);
// Start blynk
EspSerial.begin(ESP8266_BAUD);
delay(10);
Blynk.begin(auth, wifi, ssid, pass, IPaddress, 8080);
// Relay items (pumps, element safety, valves, etc.)
// Ensure relay board starts in OFF position
for (int i=pin_relay_600w; i<=(pin_relay_600w+7);i++){ digitalWrite(i,OFF);}
// Pins
pinMode(pin_relay_600w,OUTPUT);
pinMode(pin_relay_1000w,OUTPUT);
pinMode(pin_relay_pump_1,OUTPUT);
// temp probe
// RTD input pins
pinMode(pin_probe_1_CLK,INPUT);
pinMode(pin_probe_1_SDO,INPUT);
pinMode(pin_probe_1_SDI,INPUT);
pinMode(pin_probe_1_CS,INPUT);
// Start temp probe object
temp_probe_1.begin(MAX31865_3WIRE);
// Read EEPROM values
PID_1_mode_1_kp = EEPROM.read(ER_address_PID_1_mode_1_kp);
PID_1_mode_1_ki = EEPROM.read(ER_address_PID_1_mode_1_ki);
PID_1_mode_1_kd = EEPROM.read(ER_address_PID_1_mode_1_kd);
temp_probe_1_offset = EEPROM.read(ER_address_temp_probe_1_offset)/10;
// Initialize PID object
main_PID.SetMode(AUTOMATIC);
// Start temp update timer
update_temp_timer.setInterval(update_mon_interval, update_mon_blynk);
// Start timer
timer_start = millis();
}
// Main Loop
void loop()
{
// Update current temp (pull from arduino)
update_probe_1_temp();
// Update temp readouts (push to arduino)
update_temp_timer.run();
// Set PID temp control();
update_temp_control();
// Run Blynk
Blynk.run();
}
void update_mon_blynk()
{
// Temperatures
// Temp target to graph
Blynk.virtualWrite(V111, temp_target);
// Push current temp target to graph and manual monitor
// Blynk.virtualWrite(V110, temp_probe_1_current);
// Blynk.virtualWrite(V107, temp_probe_1_current);
// Element power
// Blynk.virtualWrite(V105,element_power_level/2.55);
// Lift
// Blynk.virtualWrite(V106,LA_current_pos);
// LCD
//lcd.print(0, 0, "Mode: " + control_mode);
}
void update_temp_control()
{
// Change PID settings if necessary
main_PID.SetTunings(PID_1_mode_1_kp, PID_1_mode_1_ki, PID_1_mode_1_kd);
// Update the PID settings
main_PID.Compute();
}
// Read temp probe 1 (including conversion to F and offset)
void update_probe_1_temp()
{ temp_probe_1_current = temp_probe_1.temperature(100.0, 430.0)*(9/5)+32 + temp_probe_1_offset; }
// Enable/disable temp probes
void element_600w_enable()
{ digitalWrite(pin_relay_600w,ON); }
// Enable/disable temp probes
void element_600w_disable()
{ digitalWrite(pin_relay_600w,OFF); }
void element_1000w_enable()
{ digitalWrite(pin_relay_1000w,ON); }
// Enable/disable temp probes
void element_1000w_disable()
{ digitalWrite(pin_relay_1000w,OFF); }
void update_probe_1_offset()
{
// Determine difference between calibrated temp and current readout temp
double temp_probe_1_offset = temp_probe_1_offset_level_holding - (temp_probe_1.temperature(100.0, 430.0)*(9/5)+32);
// Write new value to EEPROM
EEPROM.update(ER_address_temp_probe_1_offset,temp_probe_1_offset*10);
}
void pump_1_on()
{
digitalWrite(pin_relay_pump_1,ON);
LED_pump_1.on();
}
void pump_1_off()
{
digitalWrite(pin_relay_pump_1,OFF);
LED_pump_1.off();
}
// Blynk vpins
// Manual control inputs
// Temperature input
BLYNK_WRITE(V1) {
temp_target_holding = param.asInt();
control_mode = "Manual";
}
// Set temp from temp input using button
BLYNK_WRITE(V2) {
temp_target = temp_target_holding;
control_mode = "Manual";
}
// Turn on 600W element
BLYNK_WRITE(V10) {
int y = param.asInt();
if (y==1){ element_600w_enable(); }
if (y==0){ element_600w_disable(); }
control_mode = "Manual";
}
// Turn on 1000W element
BLYNK_WRITE(V11) {
int y = param.asInt();
if (y==1){ element_1000w_enable(); }
if (y==0){ element_1000w_disable(); }
control_mode = "Manual";
}
// Element power level (input as 0-100, converted to 0-255)
BLYNK_WRITE(V12) {
int y = param.asInt();
element_power_level=y*2.55;
control_mode = "Manual";
}
// Pump button
BLYNK_WRITE(V30) {
int y = param.asInt();
if (y==1){ pump_1_on(); }
if (y==0){ pump_1_off(); }
control_mode = "Manual";
}
// Config inputs
// temp offset input
BLYNK_WRITE(V40) { temp_probe_1_offset_level_holding = param.asDouble(); }
// temp offset set button
BLYNK_WRITE(V41) { update_probe_1_offset(); }