[SOLVED] Login Timeout using Blynk Timer - Cmd skipped:16 (BLYNK_CMD_HARDWARE_SYNC)

Hello Blynkers !

Firstly, I really want to thank the Blynk team for their App : so powerful !

I am using an ESP8266 module version with an Arduino UNO and my coding knowledge is limited, I will need your help with a “Login Timeout” error. Here is my code, I tried to made it as clear as possible:

#define BLYNK_PRINT Serial

#include <Wire.h>
#include <SPI.h>
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <DHT.h>
#include <SoftwareSerial.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>

//**********TOKEN (OK)**********//
char auth[] = "*********************";

//**********WIFI (OK)**********//
//char ssid[] = "**********";
//char pass[] = "*********";
char ssid[] = "***********";
char pass[] = "***********";

//**********PIN**********//
const int btnPin = 4;
const int HeatPin = 5;

//**********RTC**********//
char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
char dateBuffer[12];

//**********CUSTOM CHAR LCD**********//
byte thermo[8] = {
  0b00100,
  0b01010,
  0b01010,
  0b01110,
  0b01110,
  0b11111,
  0b11111,
  0b01110
};

byte drop[8] = {
  0b00100,
  0b00100,
  0b01010,
  0b01010,
  0b10001,
  0b10001,
  0b10001,
  0b01110
};

byte heat[8] = {
  0b10010,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b01001
};

SoftwareSerial EspSerial(2, 3); // RX, TX

#define ESP8266_BAUD 9600
#define DHTPIN 7
#define DHTTYPE DHT22

ESP8266 wifi(&EspSerial);
WidgetLED led1(V1);
DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,20,4);

void HeatButton();
int ledState = HIGH;
int btnState;
int lastButtonState = LOW;
// the following variables are unsigned long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(V20);

  // Alternatively, you could override server state using:
  //Blynk.virtualWrite(V2, ledState);
}

// When App button is pushed - switch the state
BLYNK_WRITE(V20) {
  ledState = param.asInt();
  digitalWrite(HeatPin, ledState);
}

//**********HEAT PUSH BUTTON (OK)**********//
void HeatButton()
{
  // read the state of the switch into a local variable:
  int reading = digitalRead(btnPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != btnState) {
      btnState = reading;

      // only toggle the LED if the new button state is HIGH
      if (btnState == HIGH) {
        ledState = !ledState;
      }
    }
  }

  // set the LED:
  digitalWrite(HeatPin, ledState);

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;
  if (digitalRead(btnPin) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btnState != LOW) {
      // Toggle LED state
      ledState = !ledState;
      digitalWrite(HeatPin, ledState);
      // Update Button Widget
      Blynk.virtualWrite(V20, ledState);
    }
    btnState = LOW;
  } else {
    btnState = HIGH;
  }
}

//**********LCD 4x20 DISPLAY**********//
void LCDisplay(){
   DateTime now = rtc.now();
   lcd.setCursor ( 0, 0 ); // go to the top left corner
   sprintf(dateBuffer,"%02u:%02u ",now.hour(),now.minute());
   Serial.println(dateBuffer);
   lcd.print(dateBuffer);
}

//**********DHT TO BLYNK (OK)**********//
void sendSensor()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  Blynk.virtualWrite(V18, h);
  Blynk.virtualWrite(V17, t);
}

void setup()
{
  //**********DEBUG CONSOLE**********//
  Serial.begin(9600);
  delay(10);
  
  //**********ESP SETUP (OK)**********//
  EspSerial.begin(ESP8266_BAUD);
  delay(10);
  Blynk.begin(auth, wifi, ssid, pass);
  
  //**********DHT SENSOR (OK)**********//
  dht.begin();
  timer.setInterval(30000L, sendSensor);
  
  //**********SWITCH HEAT ON/OFF (OK)**********//
  pinMode(HeatPin, OUTPUT);
  pinMode(btnPin, INPUT_PULLUP);
  digitalWrite(HeatPin, ledState);
  timer.setInterval(500L, HeatButton);

  //**********LCD 4x20 BACKGROUND**********//
  lcd.init();  //initialize the lcd
  lcd.backlight();  //open the backlight
  lcd.createChar(0, thermo);
  lcd.createChar(1, drop);
  lcd.createChar(2,heat);
  lcd.setCursor ( 0, 1 );
  lcd.write(byte(0));
  lcd.setCursor ( 0, 2 );
  lcd.write(byte(1));
  lcd.setCursor ( 0, 3 );
  lcd.write(byte(2));
  lcd.setCursor ( 12, 0 );
  lcd.write(byte(1));
  lcd.print(" Period");
  lcd.setCursor ( 6, 0 );
  lcd.print("AUTO");
  //timer.setInterval(5000L, LCDisplay);
  
  //**********RTC SETUP**********//
  // following line sets the RTC to the date & time this sketch was compiled
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  //rtc.adjust(DateTime(2017, 4, 5, 19, 30, 0));
}
void loop()
{
  Blynk.run();
  timer.run();
}

So, everything is working well except the “live” display of Real Time (with a RTC) on Hardware LCD 2004. Every time I uncomment //timer.setInterval(5000L, LCDisplay); I get an error like this :

[10060] Connected to WiFi
[20591] Ready (ping: 23ms).
[30726] Login timeout
[46495] Ready (ping: 243ms).
[56630] Login timeout

I have no idea why, I am aware of flood issues that may cause Timeout, but in my case, the period is quite long, and the LCDisplay() function doesn’t even requires/sends data from/to Blynk server … Maybe I made a wrong use of timer function, but I don’t how to do it in another way.
If you have an idea why I get this Login timeout, and maybe a solution to my issue, you are welcome !

Perhaps an issue with the I2C communication??

Do you get any actual displayed data on the LCD before timeout? If so for how long before the timeout (less than or more than the 5 seconds you have set).

I also see you have a print statement to the serial monitor, does that data show before timeout??

Hi Gunner, thank for answering !

The “LCD Background” is displayed on LCD, and the “live” time has never been displayed, even before the timeout. In my previous Code, I used delay() function to refresh the clock time, and it worked. I simply move from delay() to timer()

Here is my previous piece of code :

// Libraries
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>

RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,20,4);

char daysOfTheWeek[7][12] = {"Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"};
char dateBuffer[12];
char ARELAY=7;
char button=2;
char arros1[12];
uint8_t heureArrosage=18;
uint8_t minuteArrosage=13;
uint8_t dureeArrosage=20;
int valHeat = 0; // variable to store the read value

// Custom Character for LCD
byte thermo[8] = {
  0b00100,
  0b01010,
  0b01010,
  0b01110,
  0b01110,
  0b11111,
  0b11111,
  0b01110
};

byte drop[8] = {
  0b00100,
  0b00100,
  0b01010,
  0b01010,
  0b10001,
  0b10001,
  0b10001,
  0b01110
};

byte heat[8] = {
  0b10010,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b01001
};

void setup() {
  Serial.begin(9600);
  pinMode(ARELAY,OUTPUT);
  pinMode(button,INPUT_PULLUP);
//pinMode(ARELAY,INPUT);
// LCD initialization
  lcd.init();  //initialize the lcd
  lcd.backlight();  //open the backlight
  lcd.createChar(0, thermo);
  lcd.createChar(1, drop);
  lcd.createChar(2,heat);
  lcd.setCursor ( 0, 1 );
  lcd.write(byte(0));
  lcd.setCursor ( 0, 2 );
  lcd.write(byte(1));
  lcd.setCursor ( 0, 3 );
  lcd.write(byte(2));
  lcd.setCursor ( 14, 0 );
  lcd.print("Next ");
  lcd.write(byte(1));
  lcd.setCursor ( 14, 1 );
  lcd.print(heureArrosage);
  lcd.print(":");
  lcd.print(minuteArrosage);
  lcd.setCursor ( 7, 0 );
  lcd.print("AUTO");
  
// RTC Setup
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2017, 4, 5, 19, 30, 0));
 
 }
}
void loop() {
    DateTime now = rtc.now();
        lcd.setCursor ( 0, 0 ); // go to the top left corner
        sprintf(dateBuffer,"%02u:%02u ",now.hour(),now.minute());
        Serial.println(dateBuffer);
        lcd.print(dateBuffer);

    // Watering Planned
    if (now.hour()==heureArrosage && now.minute()==minuteArrosage && now.second()==0){
        for(int compteurA = 0;compteurA<dureeArrosage;compteurA++)
        {
        digitalWrite(ARELAY,LOW);
        //Display RTC
        DateTime now = rtc.now();
        lcd.setCursor ( 0, 0 ); // go to the top left corner
        sprintf(dateBuffer,"%02u/%02u/%04u ",now.day(),now.month(),now.year());
        Serial.print(dateBuffer);
        sprintf(dateBuffer,"%02u:%02u:%02u ",now.hour(),now.minute());
        Serial.println(dateBuffer);
        lcd.print(dateBuffer);
        lcd.setCursor ( 0, 2 );
        lcd.write(byte(1));
        lcd.print(" ARROSAGE EN COURS");
        delay(1000);
        }
        lcd.setCursor ( 1, 2 );
        lcd.print("                  ");
    }else{
    digitalWrite(ARELAY,HIGH);
    delay(1000);
 }
}

And no, no clock related data to the serial monitor before neither after.

EDIT : There is no display on LCD, even background stuff in setup() function, it is like this piece of code is not executed for some reason

So, after a few tests, I noticed that issue is about timers and interval. I have 3 different interval for 1timer. 1 for a pushbutton with debouncing,1 to send DHT data to Blynk, and the last one for LCD display :

  //**********TIMERS**********//
  timer.setInterval(5000L, LCDisplay);
  timer.setInterval(30000L, sendSensor);
  timer.setInterval(200L, HeatButton);

It works fine when I activate 2 of them, but I get Timeout error when I activate all.

EDIT : Back after few tests, it appears to be a Router problem : the code is working like a charm when it is connected to my smartphone Access point. I use a 3G/4G Archer MR200 router from TP-Link.
I set up a static IP for ESP, I checked MAC blacklist, I enabled 8442. Here is the debug console when 3 timers are active :

[10067] Connected to WiFi
[20401] <[02|00|01|00] **********TOKEN**********
[20570] >[00|00|01|00|C8]
[20570] Ready (ping: 25ms).
[20571] <[11|00|01|00]fver[00]0.4.7[00]h-beat[00]10[00]buff-in[00]256[00]dev
[30730] Cmd error
[30775] Cmd skipped:16
[30775] Login timeout

And here is the debug console when only timer.setInterval(200L, HeatButton); is commented (nearly the same when only timer.setInterval(30000L, sendSensor); is commented) :

[9075] Connected to WiFi
[19325] <[02|00|01|00] ******TOKEN*************
[19505] >[00|00|01|00|C8]
[19505] Ready (ping: 24ms).
[19506] <[11|00|01|00]fver[00]0.4.7[00]h-beat[00]10[00]buff-in[00]256[00]dev
[19769] <[00]Arduino Uno[00]cpu[00]ATmega328P[00]con[00]ESP8266[00]
[19957] <build[00]Apr 29 2017 18:30:11[00]
[20122] <[10|00|02|00|05]vr[00]20
[21439] >[00|00|01|00|C8]
[21449] >[14|00|02|00|07]
[21449] >vw[00]20[00]1
18:30 

Help would be very appreciated :slight_smile:

Hello Blynkers !

After 4 days of debugging, I am still struggling to find how can I troubleshoot Cmd skipped:16
Here is the debug log :

[10067] Connected to WiFi
[20401] <[02|00|01|00] TOKEN
[20570] >[00|00|01|00|C8]
[20570] Ready (ping: 25ms).
[20571] <[11|00|01|00]fver[00]0.4.7[00]h-beat[00]10[00]buff-in[00]256[00]dev
[30730] Cmd error
[30775] Cmd skipped:16
[30775] Login timeout

Can someone explicit this error ? I can’t find find info/topic about it :disappointed:

That code seems to be a BLYNK_CMD_HARDWARE_SYNC issue. So you probably have a communications issue or something in your code… which we will need to see to go much further. Oh, ya, and what hardware are you using and Local or Cloud server?

Hi @Gunner !

You can see my code on my previous topic. I started a new topic because I would like more specific answer about Cmd skipped:16 but the issue/hardware are the same.

Hardware : Arduino Uno + ESP8266 (correctly wired, 3.3v external powered) + Real Time Clock (I2C) + LCD 2004 (I2C) + DHT.

I took an old version of my sketch, which worked, and tried to add other functions piece by piece. This error seems to appear when my code becoming bigger (RAM and also EEPROM are about 80% in use.), no matter what function I add, in example :

RTC + LCD = work well
LCD + DHT to Blynk = work well
RTC + DHT to Blynk = work well
RTC + LCD + DHT to Blynk = Not working (Cmd skipped:16 and Timeout every 10 seconds)

Ok so, there is an example :

#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG Serial

#define ESP8266_BAUD 9600
#define DHTPIN 7
#define DHTTYPE DHT22

//**********LIB**********//
#include <Wire.h>
#include <SPI.h>
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <DHT.h>
#include <DHT_U.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>

SoftwareSerial EspSerial(2, 3); // RX, TX
ESP8266 wifi(&EspSerial);
WidgetLED led1(V1);
DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,20,4);

//**********TOKEN (OK)**********//
char auth[] = "7828def9f8ea485597e8bd10cdc367c3";

//**********WIFI (OK)**********//
char ssid[] = "6edd54";
char pass[] = "284444652";
//char ssid[] = "AndroidAP";
//char pass[] = "loicloic";

//**********HEAT BUTTON PIN**********//
const int heatbuttonPin = 4;
const int heatrelayPin = 5;
void HeatButton();
int heatrelayState = HIGH;
int heatbuttonState;
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

//**********DHT**********//

//**********RTC**********//
char dateBuffer[12];

//**********CUSTOM CHARACTER**********//
byte thermo[8] = {
  0b00100,
  0b01010,
  0b01010,
  0b01110,
  0b01110,
  0b11111,
  0b11111,
  0b01110
};

byte drop[8] = {
  0b00100,
  0b00100,
  0b01010,
  0b01010,
  0b10001,
  0b10001,
  0b10001,
  0b01110
};

byte heat[8] = {
  0b10010,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b10101,
  0b01001
};

BLYNK_CONNECTED() {
  Blynk.syncVirtual(V20);
}
BLYNK_WRITE(V20) {
  heatrelayState = param.asInt();
  digitalWrite(heatbuttonPin, heatrelayState);
}

void HeatButton()
{
  // read the state of the switch into a local variable:
  int reading = digitalRead(heatbuttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH),  and you've waited
  // long enough since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != heatbuttonState) {
      heatbuttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (heatbuttonState == HIGH) {
        heatrelayState = !heatrelayState;
      }
    }
  }

  // set the LED:
  digitalWrite(heatrelayPin, heatrelayState);

  // save the reading.  Next time through the loop,
  // it'll be the lastButtonState:
  lastButtonState = reading;
  if (digitalRead(heatbuttonPin) == LOW) {
    // btnState is used to avoid sequential toggles
    if (heatbuttonState != LOW) {
      // Toggle LED state
      heatrelayState = !heatrelayState;
      digitalWrite(heatbuttonPin, heatrelayState);
      // Update Button Widget
      Blynk.virtualWrite(V20, heatrelayState);
    }
    heatbuttonState = LOW;
  } else {
    heatbuttonState = HIGH;
  }
}

//**********DHT TO BLYNK (OK)**********//
void sendSensor()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  Blynk.virtualWrite(V18, h);
  Blynk.virtualWrite(V17, t);
  lcd.setCursor ( 2, 1 );
  lcd.print(t,0);
  lcd.setCursor ( 2, 2 );
  lcd.print(h,0);
}

//**********LCD RTC**********//
void lcdrtc(){
  DateTime now = rtc.now();
  lcd.setCursor ( 0, 0 ); // go to the top left corner
  sprintf(dateBuffer,"%02u:%02u ",now.hour(),now.minute());
  Serial.println(dateBuffer);
  lcd.print(dateBuffer);
}

void setup()
{
  //**********DEBUG CONSOLE**********//
  Serial.begin(9600);
  delay(10);
  
  //**********DHT SENSOR (OK)**********//
  dht.begin();
  timer.setInterval(5000L, sendSensor);

  //**********LCD BACKGROUND**********//
  lcd.init();  //initialize the lcd
  lcd.backlight();  //open the backlight
  lcd.clear();
  lcd.createChar(0, thermo);
  lcd.createChar(1, drop);
  lcd.createChar(2,heat);
  lcd.setCursor ( 0, 1 );
  lcd.write(byte(0));
  lcd.setCursor ( 0, 2 );
  lcd.write(byte(1));
  lcd.setCursor ( 0, 3 );
  lcd.write(byte(2));
  lcd.setCursor ( 6, 0 );
  lcd.print("AUTO");
  lcd.setCursor ( 12, 0 );
  lcd.write(byte(1));
  lcd.print(" Period");
//  lcd.setCursor ( 4, 1 );
//  lcd.print("°C");
//  lcd.setCursor ( 4, 2 );
//  lcd.print("%");
  
  //**********LCD 3SEC REFRESH**********//
  timer.setInterval(3000L, lcdrtc);

  
  //**********SWITCH HEAT ON/OFF**********//
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); //Uncomment to adjust RTC
  
  //**********SWITCH HEAT ON/OFF**********//
  pinMode(heatrelayPin, OUTPUT);
  pinMode(heatbuttonPin, INPUT_PULLUP);
  digitalWrite(heatrelayPin, heatrelayState);
  timer.setInterval(200L, HeatButton);

  //**********ESP SETUP (OK)**********//
  EspSerial.begin(ESP8266_BAUD);
  delay(10);
  Blynk.begin(auth, wifi, ssid, pass);
}

void loop()
{
  Blynk.run();
  timer.run();
}

This sketch works perfectly (log) :

[1751] Connecting to 6edd54
[4919] 1,CLOSED
AT version:1.1.0.0(May 11 2016 18:09:56)
SDK version:1.5.4(baaeaebb)
compile time:Mar 9 2017 19:22:12
OK
[12207] +CIFSR:STAIP,“*"
+CIFSR:STAMAC,"

[12216] Connected to WiFi
[22602] Ready (ping: 24ms).
01:46
01:46
01:46
01:46

And if I uncomment

//  lcd.setCursor ( 4, 1 );
//  lcd.print("°C");
//  lcd.setCursor ( 4, 2 );
//  lcd.print("%");

I get this log file:

[13219] +CIFSR:STAIP,“"
+CIFSR:STAMAC,"
***”
[13229] Connected to WiFi
[23625] Ready (ping: 24ms).
[38747] Login timeout
[54141] Ready (ping: 25ms).
[64275] Login timeout

Notice that the Login timeout comes each 10sec after Ready. @Gunner, I am using Blynk’s Cloud.

Both your topics are about the same general issue so I merged them. Please try not to create multiple topics on same issue… if you have a specific question, just ask it in the one topic as it all shows up in the same forum, but keeps the forum topics from getting fragmented.

As for your issue, I think you have already pointed out some of the primary causes… you can not overload the memory without it having ramifications on performance and in your case the timing of the Hardware <–> Server communications link.

This seems like something you can resolve with more compact coding.

If it is a memory issue, maybe this will help. I haven’t really read it but it may help.

https://learn.adafruit.com/memories-of-an-arduino/you-know-you-have-a-memory-problem-when-dot-dot-dot

@Gunner Thank for your reply, I apologize for the new topic. Yeah, the problem is probably about memory overload.

@Toro_Blanco Your link is interesting, it gives some advice on how to deal with memory issue, but, as I think I’m not using any useless libraries, other solutions are a bit hard to set up : switching between SRAM/EEPROM etc. but I feel like it will cause some additionnal communication issues. Also, I really want to implement more functions, and so I think I will be stuck at a certain point.

I am considering moving from ESP8266+Arduino to ESP8266 Standalone like NodeMCU. I have the choice between This one and This other one. They are relatively similar, the only difference seems to be Serial Chip (CP2102 vs CH340G)

As they have 4MB flash memory, It should be resolve this issue and allow me to implement even more functions.
Any advice on wich NodeMcu could be the ‘best’ choice ?