Blynk.virualwrite delay, please help me understand

Hello All,

I love this app and I think it’s exactly what I’m looking for but I’m running into a (common?) issue. I’m sending 9 integers from the phone app to a ESP8266 by wifi with a local server setup (debug notes 6ms ping). Blynk.run(); takes about 50-70microseconds while receiving data and the latency is well within a usable range (why I set up the local server). Unfortunately, sending back to the app through Blynk.virtualwrite() or led.on()/off() takes about 60-80milliseconds each?! I would be fine with excessive write latency but the command locks the MCU loop during.

I’ve read through the similar forum posts and documentation which notes ‘clean the loop’, ‘don’t use vituralwrite in loops’, to use a timer to initiate the push (which still locks the loop for 60-80ms for each write), or my favorite ‘it depends’. I’m trying to send 8 integers and 4 led status’ so the full write takes about 800-900ms!? And yes, the led.on()/off() take just as long as the .virturalwrite(). Putting this on a timer that sends every 1sec still locks the loop for 800-900ms every 1000ms.

How can it be so fast (50-70us) to receive data from the app (through local server) but take so long (60-80ms) to send data to the app? What is happening here? The documentation did not help me understand the fundamentals of IOT that are happening here.

If needed I’ll post simplified code but it’s the same as others have posted. I’m just looking to rationalize why the data direction so drastically affects the time. If there’s nothing to be done to fix the virtualwrite time then my solution here is to not send data from the mcu to the app which is unfortunate. I was looking forward to using this as a diagnostic display.

Thanks,

Have you tried adding Blynk.run(); commands after each Blynk.virtualWrite command and comparing the results?

BlynkTimer does have some anti-flood code built in apparently, so maybe this is the culprit?

The Blynk library also has a message limit:

// Limit the amount of outgoing commands.
#ifndef BLYNK_MSG_LIMIT
#define BLYNK_MSG_LIMIT      20
#endif

but 20 messages per second shouldn’t be a problem in your case, but it can be changed if you wish.

Pete.

Thank you for the quick reply!

Adding Blynk.run() after each did not change the virtualWrite time. Commenting all of them out except for one with blynk.run() after still resulted in 67ms time consumed. I thought it may have been because I was sending floats originally so I changed them to integers. In the test cases below I’m just sending zero. I didn’t think this would make a difference since the led on/off bit takes the same amount of time but just trying to rule things out.

  int32_t p_micros = micros();
  Blynk.virtualWrite(V14,0);
  Serial.println(micros() - p_micros);

~67,000us

  int32_t p_micros = micros();
  Blynk.virtualWrite(V14,0);
  Blynk.run();
  Serial.println(micros() - p_micros);

~67,000us

  int32_t p_micros = micros();
  Blynk.virtualWrite(V14,0);
  Blynk.virtualWrite(V15,0);
  Blynk.virtualWrite(V24,0);
  Blynk.virtualWrite(V25,0);
  Blynk.virtualWrite(V34,0);
  Blynk.virtualWrite(V35,0);
  Blynk.virtualWrite(V44,0);
  Blynk.virtualWrite(V45,0);
  Serial.println((micros() - p_micros)/8);

66,950us on average

  int32_t p_micros = micros();
  Blynk.virtualWrite(V14,0);
  Blynk.run();
  Blynk.virtualWrite(V15,0);
  Blynk.run();
  Blynk.virtualWrite(V24,0);
  Blynk.run();
  Blynk.virtualWrite(V25,0);
  Blynk.run();
  Blynk.virtualWrite(V34,0);
  Blynk.run();
  Blynk.virtualWrite(V35,0);
  Blynk.run();
  Blynk.virtualWrite(V44,0);
  Blynk.run();
  Blynk.virtualWrite(V45,0);
  Blynk.run();
  Serial.println((micros() - p_micros)/8);

66,900 - 67,100us, less consistent than before.

Any thoughts?

I’m confused!

You seem to have switched from milliseconds to microseconds…

Around 70 microseconds seems like an entirely reasonable amount of time for a virtualWrite.

Pete.

Sorry for the confusion; 66,950us as in 66.95ms. My most recent post normalized everything in us. yes, there is that large of a difference in getting data and sending.

App to ESP8266: 50-70us
ESP8266 to App: 67,000us.

70us for virturalWrite would be amazing! My calculation and serial print methods run at about 20,000us intervals +/- not to overlap.

Okay, apologies over the millis/micros confusion, I typed my last message on my p-hone whilst pushing a trolley around the local supermarket, and didn’t realise that it was 67,000 millis rather than 67.000 millis :crazy_face:

Back home from the supermarket craziness now and I thought I’d do some tests of my own.

I decided to capture the micros() time immediately before and after the Blynk.virtualWrite the serial print the result, to remove ant delays in the serial print process.

I was getting roughly the same results using both the Blynk cloud and local server, each giving around 67,000 micros.

I then added this line to the start of my sketch:

#define BLYNK_MSG_LIMIT 40

and the result fell to around 26,000 micros.

Changing the MSG_LIMIT to 100 gave a result of around 11,000 micros

Changing the MSG_LIMIT to 1000 gave a result of around 2,100 micros

Changing the MSG_LIMIT to 10000 gave a result of around 1,100 micros, but these were jumping from 240micros to 1800 micros, so very inconsistent.

These last tests were all done with my local server, and I wouldn’t recommend trying this with the cloud servers as you’ll probably get disconnected for flooding the server with too many requests.

I didn’t use a BlynkTimer to do these tests, in case the anti-flood functionality in BlynkTimer was a factor. I simply did 8 consecutive virtualWrites in the void loop, followed by a delay. Here’s a snippet of some of that void loop code…

  startmicros = micros();
  Blynk.virtualWrite(V14,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);

  startmicros = micros();
  Blynk.virtualWrite(V15,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);

  startmicros = micros();  
  Blynk.virtualWrite(V24,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);

  startmicros = micros();
  Blynk.virtualWrite(V25,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);

I also tried increasing this setting in my server.properties file:

#user is limited with 100 messages per second.
user.message.quota.limit=100

to 1000 and restarting the server, but it didn’t seem to make any real difference.

Hope this helps!

BTW, I’d avoid going too crazy with the MSG_LIMIT number, it’s clearly there for a reason!

Pete.

Pete,

Thank you for spending so much time on this! I really appreciate the replies. Unfortunately, I’m not getting the results that you did… My micros time appears to be unaffected (~66800 micros) with #define BLYNK_MSG_LIMIT 40, 100, 1000, or 10000.

I am getting a compiler message “BLYNK_MSG_LIMIT” redefined [enabled by default]?

I’m definitely keeping this all local and ensured I’m signed into the local server admin@blynk.cc.

I don’t get how this is happening while sending zeros or led states? This is so little information to pass.

Thanks,

Are you using BlynkTimer?

Pete.

I am not. I’m using a interval counter in the main loop to call Blynk virtualWrite methods. It runs every 21277micros (47Hz). This functions appears the same when using the BlynkTimer so I reverted back to the interval.

The main loop, with Blynk.run() receiving values, only consumes (edit; was ~110micros, copied my /8 from the write average :sweat_smile:) ~925micros while completing calculations. The calculations are on a 18868micro interval (53Hz) to minimize the occurrence of the methods overlapping.

Try running my sketch…

#define BLYNK_PRINT Serial
#define BLYNK_MSG_LIMIT      1000

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "REDACTED";

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

int32_t startmicros;
int32_t endmicros;

void setup()
{
  // Debug console
  Serial.begin(74880);
  Blynk.begin(auth, ssid, pass,"LOCAL_SERVER_IP",8080);
}

void loop()
{
  Blynk.run();
  startmicros = micros();
  Blynk.virtualWrite(V14,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);
  startmicros = micros();
  Blynk.virtualWrite(V15,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);
  startmicros = micros();  
  Blynk.virtualWrite(V24,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);
  startmicros = micros();
  Blynk.virtualWrite(V25,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);
  startmicros = micros();  
  Blynk.virtualWrite(V34,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);
  startmicros = micros();  
  Blynk.virtualWrite(V35,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);
  startmicros = micros();  
  Blynk.virtualWrite(V44,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);
  startmicros = micros();  
  Blynk.virtualWrite(V45,0);
  endmicros = micros();
  Serial.println(endmicros-startmicros);
  startmicros = micros();
  Serial.println();  

 delay (1000);
}

and this is my serial output:

21:58:57.927 -> [3566] Connected to WiFi
21:58:57.927 -> [3566] IP: REDACTED
21:58:57.927 -> [3566] 
21:58:57.927 ->     ___  __          __
21:58:57.973 ->    / _ )/ /_ _____  / /__
21:58:57.973 ->   / _  / / // / _ \/  '_/
21:58:57.973 ->  /____/_/\_, /_//_/_/\_\
21:58:57.973 ->         /___/ v0.6.1 on NodeMCU
21:58:57.973 -> 
21:58:57.973 -> [3576] Connecting to REDACTED:8080
21:58:57.973 -> [3599] Ready (ping: 7ms).
21:58:57.973 -> 1542
21:58:57.973 -> 1973
21:58:57.973 -> 1999
21:58:57.973 -> 1865
21:58:57.973 -> 2068
21:58:57.973 -> 1728
21:58:57.973 -> 1965
21:58:57.973 -> 2099
21:58:57.973 -> 
21:58:58.986 -> 888
21:58:58.986 -> 1673
21:58:58.986 -> 1936
21:58:58.986 -> 2763
21:58:58.986 -> 2178
21:58:58.986 -> 2108
21:58:58.986 -> 2046
21:58:58.986 -> 2032
21:58:58.986 -> 
21:58:59.995 -> 962
21:58:59.995 -> 2405
21:58:59.995 -> 2328
21:58:59.995 -> 2344
21:58:59.995 -> 1065
21:59:00.040 -> 2035
21:59:00.040 -> 1822
21:59:00.040 -> 1976

Pete.

Ah! You have this before including Blynk…h! I’ll work on this more later.

Thanks,

1 Like

Ok, moving the message limit to the top does help and I was able to significantly reduce the virtualwrite time. Going above msg limit of 100 seems to cause wifi connectivity issues so I separated the writes between multiple calculation cycles. Still seems slow compared to the receiving data. Nonetheless I think this is workable for now.

Thanks,

1 Like