Blynk response very slow

Hi Blynk

I was one of your kickstarter backers and using Blynk now with satisfaction!

Currently I have a problem. I use blynk to control my robot directions. I use:
joystick for directions and using it with virtual pin V1
slider for speed of the robot on virtual pin V0

I have android5.1 on my phone, Blynk app of 1 week old, my hardware is an ESP8266 in arduino ide and my connection Blynk-ESP is wifi

What I notice is when I change direction using the joystick it may take somewhere between 1-10 second before the robot responds. This was already that slow when I not even had the slider implemented so joystick only.
By the time it responds my robot already crashed to a wall :frowning:

The only thing I do in my arduino loop() is check 4 conditions with an if-elseif-elseif-else construction (the 4 directions). The directions come in here as global variables, the x and y from the joystick I made global and are gathered in the function:

BLYNK_WRITE(V1)
{
joy_x = param[0].asInt();
joy_y = param[1].asInt();
}

here is my loop()
{
Blynk.run();

if(joy_y > 1015) 
  forward();
else if(joy_x > 1015) 
  turnleft();
else if(joy_y <= 10) 
  backward();
else if(joy_x <= 10) 
  turnright();
else
  forward();

}

In the background using the ESP function Ticker I do every 50mS a short PING (HC04) ultrasonic measurement.
This is all I do. not a lot it seems to explain being so sluggish

What is going wrong here? The joystick does work only its way too slow to be useful

Cheers
Dennis

Hello. Few things to check :

  1. What is your ping (should be printed in debug mode);
  2. Is single button widget click fast enough?
  3. We need full code as for now it is not clear where is issue;
  4. Did you check with local server?

Hi Dmitriy

Tnx for the fast reply!

  1. what do you mean by that? I have ping in my project but not via blynk it runs local and measures every 50mS. This I verified in my terminal there I see good measurment results.
  2. no is also slow
  3. I will paste below or attach to this post
  4. I have no local server

Tnx! Dennis

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

//For Blynk app to control this via Android phone
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

//for PING sensor
#include <Ticker.h> //to do PING measurements every x mS (similar to irq based method)
#include <NewPing.h>

// called this way, it uses the addres you add as an argument, my chinese clone board has 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

//not used right now but they are safe values for my system
#define SERVOMIN  325 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  500 // this is the 'maximum' pulse length count (out of 4096)

//I2C speeds to let the Servo controller work faster if required
#define _100KHZ  100000
#define _200KHZ  200000
#define _300KHZ  300000
#define _400KHZ  400000


//local wifi
#define SSID1  "ID"
#define PASS1  "PASS"
#define WIFI_TIMEOUT  30 //divided by 2 is the time in seconds we give the WiFi to connect before giving up

//variable to control the robots moving speed (it is a delay between the moves the legs do and is controlled using Blynk slider)
int DELAY_BETWEEN_MOVES = 5;  //take  large value to debug legs

//To this pin(s) a virtual BLynk button on Android app is assigned to
const int buttonPin = D3;
char auth[] = "2d32633c488842f0a7955e1263ee986f"; // You should get Auth Token in the Blynk App, go to the Project Settings (nut icon).
int joy_x = 512; //to control the robot via Blynk's Joystick widget. These 2 start values correspond with moving forward
int joy_y = 1023;

//Ping pins and max distance
#define TRIGGER_PIN  D8  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     D7  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

//instantiate 1 ping 
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.

int staticpos = 375; //these are the midpositions for all servos
int delta1 = 120; //controls how deep the robot goes down w.r.t "staticpos"
int delta2 = 50; //controls how high the robot rises w.r.t "staticpos"
int delta3 = 38; //controls deviation of hips w.r.t "staticpos"

//instantiate the ticker and define a function to run using the ticker
Ticker measure_distance; //measure with ping periodically
int distance = 0; //global variable to store measured distance, ticker wants void functions as argument so cannot return values

boolean autonomous = true;

void setup() 
{
  Serial.begin(9600);
  
  pwm.begin();
  
  /*DVEDEBUG the next piece of code only works for Arduino compatible boards not for ESP8266
  //next command is to make the PWM controller work 4 times as fast (default I2C clock is 100kHz)
  TWBR = ((F_CPU /(_200KHZ+1)) - 16) / 2; // Change the i2c clock to 200KHz
  */

  //this line changes the I2C frequency for esp8266
  twi_setClock(_200KHZ);
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates

  
  //DVEDEBUG not used right now, was for blynk first test
  //pinMode(buttonPin, INPUT);

  /*****************************the following is to use the robot independent from blynk connection, it prevents that the ESP keeps trying to connect to blynk while there is no wifi******/
  //connection to blynk now managed by first trying to connect to wifi, skip blynk if no wifi is connected
  WiFi.begin(SSID1, PASS1);
  int counter = 0;
  while (WiFi.status() != WL_CONNECTED && (counter <= WIFI_TIMEOUT)) 
  {
delay(500);
Serial.print(".");
counter++;
  }
  Blynk.config(auth);  // in place of Blynk.begin(auth, ssid, pass);
  Blynk.connect(3333);  // timeout set to 10 seconds and then continue without Blynk
  /****************************end Blynk connection code*********************************************************************************************************************************/
  
  //setup the ticker controlled function to do PINGs
  measure_distance.attach_ms(50,do_ping); //do a ping measurement every x mS using ticker 
  
  //Set ZERO pos
  zeropoz();
  delay(3000);

  //check if the robot is connected to blynk, if not then run in the loop() the autonomous program version instead of the remote controlled version via Blynk app
  if(!Blynk.connected())
autonomous=true;
  else
autonomous=false; 
}


//this process is running constantly it does not need to be called in the loop()
//V1 is virtual pin 1 so it does not take a pin resource
BLYNK_WRITE(V1) 
{
  joy_x = param[0].asInt();
  joy_y = param[1].asInt();
}

//this process is running constantly too and on V0 (virtual pin 0) it gets the slider position from my Blynk app, here it is assigned to a variable and used in the code 
//to control the robots speed
BLYNK_WRITE(V0)
{
  DELAY_BETWEEN_MOVES = param.asInt();
  Serial.print("Sliderposition = ");
  Serial.println(DELAY_BETWEEN_MOVES);
}

void loop() 
{ 
  if (autonomous == true)
  {
forward();
  }
  else //we control the robot via Blynk remote control app
  {
Blynk.run();

if(joy_y > 1015) 
  forward();
else if(joy_x > 1015) 
  turnleft();
else if(joy_y <= 10) 
  backward();
else if(joy_x <= 10) 
  turnright();
else
  forward();
  }  
}



void zeropoz()
{
  pwm.setPWM(0, 0, 375);
  pwm.setPWM(1, 0, 375);
  pwm.setPWM(2, 0, 375);
  pwm.setPWM(3, 0, 375);
  pwm.setPWM(4, 0, 375);
  pwm.setPWM(5, 0, 375);
  pwm.setPWM(6, 0, 375);
  pwm.setPWM(7, 0, 375);
  pwm.setPWM(8, 0, 375);
  pwm.setPWM(9, 0, 375);
  pwm.setPWM(10, 0, 375);
  pwm.setPWM(11, 0, 375);
  pwm.setPWM(12, 0, 375); //the servo which controls the scanning of the PING sensor
}
void walkpoz()
{
  int pdelta1 = 60;

  pwm.setPWM(0, 0, 375);
  pwm.setPWM(1, 0, 375);
  pwm.setPWM(2, 0, 375-pdelta1);
  pwm.setPWM(3, 0, 375);
  pwm.setPWM(4, 0, 375+pdelta1);
  pwm.setPWM(5, 0, 375);
  pwm.setPWM(6, 0, 375);
  pwm.setPWM(7, 0, 375);
  pwm.setPWM(8, 0, 375-pdelta1);
  pwm.setPWM(9, 0, 375);
  pwm.setPWM(10, 0, 375+pdelta1);
  pwm.setPWM(11, 0, 375);
}

void forward()
{
  Group1Up();
  delay(DELAY_BETWEEN_MOVES);
  Group2Bw();
  delay(DELAY_BETWEEN_MOVES);
  Group1Fw();
  delay(DELAY_BETWEEN_MOVES);
  Group1Down();
  delay(DELAY_BETWEEN_MOVES);
  Group2Up();
  delay(DELAY_BETWEEN_MOVES);
  Group1Bw();
  delay(DELAY_BETWEEN_MOVES);
  Group2Fw();
  delay(DELAY_BETWEEN_MOVES);
  Group2Down();
  delay(DELAY_BETWEEN_MOVES);
}

void backward()
{
  Group1Up();
  delay(DELAY_BETWEEN_MOVES);
  Group2Fw();
  delay(DELAY_BETWEEN_MOVES);
  Group1Bw();
  delay(DELAY_BETWEEN_MOVES);
  Group1Down();
  delay(DELAY_BETWEEN_MOVES);
  Group2Up();
  delay(DELAY_BETWEEN_MOVES);
  Group1Fw();
  delay(DELAY_BETWEEN_MOVES);
  Group2Bw();
  delay(DELAY_BETWEEN_MOVES);
  Group2Down();
  delay(DELAY_BETWEEN_MOVES);
}

void turnright(void)
{
  Group1Up();
  delay(DELAY_BETWEEN_MOVES);
  Group2Right();
  delay(DELAY_BETWEEN_MOVES);
  Group1Left(); 
  delay(DELAY_BETWEEN_MOVES);
  Group1Down();
  delay(DELAY_BETWEEN_MOVES);
  Group2Up();
  delay(DELAY_BETWEEN_MOVES);
  Group1Right();
  delay(DELAY_BETWEEN_MOVES);
  Group2Left(); 
  delay(DELAY_BETWEEN_MOVES);
  Group2Down();
  delay(DELAY_BETWEEN_MOVES);
}

void turnleft(void)
{
  Group1Up();
  delay(DELAY_BETWEEN_MOVES);
  Group2Left();
  delay(DELAY_BETWEEN_MOVES);
  Group1Right();            
  delay(DELAY_BETWEEN_MOVES);
  Group1Down();
  delay(DELAY_BETWEEN_MOVES);
  Group2Up();
  delay(DELAY_BETWEEN_MOVES);
  Group1Left();
  delay(DELAY_BETWEEN_MOVES);
  Group2Right();              
  delay(DELAY_BETWEEN_MOVES);
  Group2Down();
  delay(DELAY_BETWEEN_MOVES);
}

//groups down dept is arranged by delta1 value and rise hight by delta12 value
void Group1Up()
{
  for(int jk=375+delta2; jk>=375-delta1; jk--)
  {
pwm.setPWM(1, 0, jk); //knee left back
pwm.setPWM(5, 0, jk); //knee left front
pwm.setPWM(9, 0, jk); //knee right middle
//delay(5);
  }
}

void Group2Up()
{
  for(int jk=375+delta2; jk>=375-delta1; jk--)
  {
pwm.setPWM(3, 0, jk); //knee left middle
pwm.setPWM(7, 0, jk); //knee right front
pwm.setPWM(11, 0, jk); //knee righ back
//delay(5);
  }
}

void Group1Down()
{
  for(int jk=375-delta1; jk<=375+delta2; jk++)
  {
pwm.setPWM(1, 0, jk); //knee left back
pwm.setPWM(5, 0, jk); //knee left front
pwm.setPWM(9, 0, jk); //knee right middle
//delay(5);
  }
}

void Group2Down()
{
  for(int jk=375-delta1; jk<=375+delta2; jk++)
  {
pwm.setPWM(3, 0, jk); //knee left middle
pwm.setPWM(7, 0, jk); //knee right front
pwm.setPWM(11, 0, jk); //knee right back
//delay(5);
  }
}

void Group1Fw() 
{
  //pwm.setPWM(0, 0, (staticpos - (delta3-10))); //hip left back //DVE this was finetuned: endvalue needs to be slightly higher so it goes less forward, prevent it from slamming to the hip left middle
  pwm.setPWM(0, 0, (staticpos - delta3)); //hip left back 
  pwm.setPWM(4, 0, (staticpos - delta3)); //hip left front (was 500)
  pwm.setPWM(8, 0, (staticpos + delta3)); //hip right middle 
}

//this one was not worked out, I derived it from Group1Fw()
void Group2Fw()
{
  pwm.setPWM(2, 0, (staticpos - delta3)); //hip left middle
  pwm.setPWM(6, 0, (staticpos + delta3)); //hip right front
  pwm.setPWM(10, 0, (staticpos + delta3)); //hip right back
}

void Group1Bw()
{
  pwm.setPWM(0, 0, (staticpos + delta3)); //hip left back
  //pwm.setPWM(4, 0, (staticpos + (delta3+10))); //hip left front //finetuned: goes slightly more backward then the others
  pwm.setPWM(4, 0, (staticpos + delta3)); //hip left front 
  pwm.setPWM(8, 0, (staticpos - delta3)); //hip right middle
}

void Group2Bw()
{
  //pwm.setPWM(2, 0, (staticpos + (delta3-10))); //hip left middle. //slightly finetuned to solve slamming into leg Left back by slightly making end value lower, makes it go less backward
  pwm.setPWM(2, 0, (staticpos + delta3)); //hip left middle.
  pwm.setPWM(6, 0, (staticpos - delta3)); //original was 375 (hip right front) 
  pwm.setPWM(10, 0, (staticpos - delta3));//original was 285 (hip right back)
}

void Group1Right() //go right is acomplished by moving the left 2 legs forward while the middle right leg goes backward
{
  pwm.setPWM(0, 0, (staticpos - delta3)); //hip left back
  pwm.setPWM(4, 0, (staticpos - delta3)); //hip left front (was 500)
  pwm.setPWM(8, 0, (staticpos - delta3)); //hip right middle //to make the right middle leg go backward we need - delta3
}

void Group2Right() //to go right with group2 the 2 right legs of the group need to move backward and the 1 left needs to move forward
{
  pwm.setPWM(2, 0, (staticpos - delta3)); //hip left middle //going forward now
  pwm.setPWM(6, 0, (staticpos - delta3)); //original was 375 (hip right front)
  pwm.setPWM(10, 0, (staticpos - delta3));//original was 285 (hip right back)
}


void Group1Left() //go left is acomplished by moving the left 2 legs backward while the middle right leg goes forward
{
  pwm.setPWM(0, 0, (staticpos + delta3)); //hip left back
  pwm.setPWM(4, 0, (staticpos + delta3)); //hip left front
  pwm.setPWM(8, 0, (staticpos + delta3)); //hip right middle now going forward to make going left possible
}

void Group2Left() //to go right with group2 the 2 right legs of the group need to move forward and the 1 left needs to move backward
{
  pwm.setPWM(2, 0, (staticpos + delta3)); //hip left middle, now moving backward ( + delta instead of -) so that the robot can go left
  pwm.setPWM(6, 0, (staticpos + delta3)); //hip right front
  pwm.setPWM(10, 0, (staticpos + delta3)); //hip right back
}


void do_ping(void)
{
  distance = sonar.ping_cm();
}

@Dennis_van_Elteren please use formatting for you code. It is impossible to read it.

I hope it looks better now

I mean - What ping do you have from hardware to Blynk Servers? This is very important. You can see thin with Bylnk Debug enabled.

You may need it in case your ping is high. As this would be network issue in that case and we can do nothing here.

How big is DELAY_BETWEEN_MOVES?

DELAY_BETWEEN_MOVES ranges from 5-200mS.
This is not the problem. It must be in the ping’s.
I now understood what you mean so I re-enstated #define BLYNK_PRINT Serial

But I see nothing on my serial…
Do I need to do more?

Never mind I needed to put this define and another for debug as 1st lines in the sketch

Now it works. Ping =0mS and it gets updated very slowly like every 5 seconds. No server problem?

....[7780] 
    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.4.3 on ESP-12

[7781] Free RAM: 43088
[7781] Connecting to blynk-cloud.com:8442
[7809] <[02|00|01|00] 2d32633c488842f0a7955e1263ee986f
[7827] >[00|00|01|00]È
[7827] Ready (ping: 0ms).
[7827] <[11|00|01|00]Gver[00]0.4.3[00]h-beat[00]10[00]buff-in[00]1024[00]dev[00]ESP-12[00]build[00]Jan 19 2017 14:26:18[00]
[20199] >[14|00|01|00|08]
[20200] >pm[00]0[00]out
[20200] <[06|00|02|00|00]
[30297] >[00|00|01|00]È
[30298] <[06|00|03|00|00]
[40362] >[14|00|01|00|08]
[40362] >pm[00]0[00]out
[40362] <[06|00|04|00|00]
[50426] >[14|00]’[00|0D]
[50426] >vw[00]1[00]615[00]1019
[50427] <[06|00|05|00|00]
[60524] >[14|00]“[00|0C]
[60524] >vw[00]1[00]610[00]880
[60524] <[06|00|06|00|00]

I think this exactly your problem.

No. That correct.

using delays is the problem?
I have no clue how else to slow down the movements of the robot?

By the way it just disconnected and then the ping was 10000 mS. Can it be a problem with the server after all?

[90503] Cmd error
[100542] Connecting to blynk-cloud.com:8442
[100566] <[02|00|01|00] 2d32633c488842f0a7955e1263ee986f
[110628] >[00|00|01|00]È
[110628] Ready (ping: 10041ms).
[110628] <[11|00|09|00]Gver[00]0.4.3[00]h-beat[00]10[00]buff-in[00]1024[00]dev[00]ESP-12[00]build[00]Jan 19 2017 14:26:18[00]
[116356] >[14|00|01|00|08]
[116357] >pm[00]0[00]out
[126400] >[00|00|09|00]È
[126400] <[06|00|0A|00|00]
[136474] >[00|00|0A|00]È
[136474] <[06|00|0B|00|00]
[146538] >[00|00|0B|00]È
[146538] <[06|00|0C|00|00]
[156610] >[00|00|0C|00]È
[156610] <[06|00|0D|00|00]
[166677] >[00|00|0D|00]È
[166678] <[06|00|0E|00|00]
[176745] >[00|00|0E|00]È
[176745] <[06|00|0F|00|00]
[186810] >[00|00|0F|00]È
[186810] <[06|00|10|00|00]

@Dennis_van_Elteren consider simple flow of your program :

void loop() {
  Blynk.run();
  if(joy_y > 1015) 
     forward();
  }
}

now imagine, your code always go in forward() method.

forward() calls delay(DELAY_BETWEEN_MOVES); 8 times.

Now imagine that DELAY_BETWEEN_MOVES is only 5ms. So your code adds at least 40ms delay for every blynk command. 40ms - is huge delay and will be visible visually. Now you see where is your issue?

Can it be a problem with the server after all?

You are looking in wrong direction :wink:

I see now Dmitriy!
I forgot that my movement function calls a group of actions which has many delays in between.

So then Blynk has no problem but how to make a “correct” delay in between do you have a suggestion?
Because unfortunately I do need them otherwise the robot is faster then the speed of light :slight_smile:

There are few ways. I would recommend you to google similar solutions based on blynk. Sorry I don’t give you ready code :slight_smile:, you have to do it by yourself.

ok!

Found a nice solution, it even takes care not to try to run blynk when it is not connected (causing unwanted delays)

void Blynk_Delay(int milli)
{
  int end_time = millis() + milli;
  while (millis() < end_time)
  {
    if (Blynk.connected())
    {
      Blynk.run();
    }
    yield();
  }
}
1 Like

Hmm. Does it work as expected?

It does to me. Why? See something wrong with it? My joystick is now very fast responsive while I clearly see the movement speed go lower if I move the slider. So works like a charm!

Super. I was just wondering. glad you make it work.

Interesting, I have a tracked robot (called Gunnerator :wink: ) that I have been controlling with a different app called BTBotControl.

I have been wanting to change to Blynk (although I will miss the telepresence video integration the other app has - and it works in landscape - HINT Blynk ;)).

Blynk has excellent GUI and personalization features, but I also have had issues with real-time motion-control timing. This might be a solution for me?

Would you mind re-posting your updated code, so I may dig into it and try to integrate it with my, currently non-Blynkified, code?

Also, please show more info, and photos of your Blynkified robot in action (here if allowed, or if you have other links like YouTube)

So why didn’t you tell us :slight_smile:? We are eager to help. @vshymanskyy for example did a quadcopter controller with Blynk and relatime timing!

1 Like