Is buffer overflow related to WiFi strength?

Hi, in this week, I always face the buffer overflow problem for my project.
Trust me, I have tried different methods searched from community and not work.

When I finish the coding and test in office (better WiFi strength), seems no this problem occur.
(For testing, I did not connect my hardwares, I just monitor the widget ON/OFF in the app to figure out the program is running correctly)
When I put the device in working place and connected all hardwares (worse WiFi strength, around 1 Mbps), buffer overflow always occurs even I did not touch any buttons after connected to Blynk in few seconds.
Note: hardwares are only 3 small 12V pump, just use virtual pin to determine the on/off time of the pumps.

I tried to place a 4G router with 4G sim next to the device, then I run the program over 30 times and no buffer overflow appear. So is it a bit relationship with the WiFi strength for data transmission?

Below is my code for reference, my void loop() is always clean, so I really confuse about that.
Besides, I would like to ask for BLYNK_WRITE(V1), is it better to call a void rather directly put the void code inside the BLYNK_WRITE, or no difference?


//  LIBRARY
//====================================================
#define BLYNK_PRINT Serial
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <WiFi.h>
//#include <EEPROM.h>
//#include <ESP8266WiFi.h>
//====================================================

//  DEKLARASI AWAL
//====================================================
char auth[] = "token";
char ssid[] = "wifiD";
char pass[] = "pass";

#define EspSerial Serial3
#define ESP8266_BAUD 115200
ESP8266 wifi(&EspSerial);

int small = 237; //8oz
int medium = 355; //12oz
int large = 473; //16oz
int drink_pump = 28;
int drink_pump2 = 26;
int water_pump = 23;
float apple_ratio = 1.0 / (1.0 + 9.0);
float orange_ratio = 1.0 / (1.0 + 9.0);
long drink_time;
long drink_time1;
long drink_time2;
long water_time;
float drink_type;
float drink_type1;
float drink_type2;
int cup_size;
int confirmPressed;
float pump1Flow = 5.33; //drink pump flow speed ml/s
float pump2Flow = 20; //water pump flow speed ml/s


BlynkTimer timer;
int timer_no1;
int timer_no2;
int timer_no3;
int timer_no4;
float water_ratio;
int type_no;
int cup_no;
int drink_no;

//====================================================
BLYNK_WRITE(V0)
{
  type_no = param[0].asInt();
  cup_no = param[1].asInt();
  Blynk.virtualWrite(V17, type_no);
  Blynk.virtualWrite(V16, cup_no);
}


BLYNK_WRITE(V1)
{
  confirmPressed = param.asInt(); 
   if (confirmPressed == 1)
 {
  mix();
 }
}

void mix()
{
  {if (drink_no == 4)
  {
      digitalWrite(drink_pump, HIGH);
      timer_no1 = timer.setTimeout(drink_time, []()
      {
        digitalWrite(drink_pump, LOW);
        timer.deleteTimer(timer_no1);
      });
  }
  else if (drink_no == 5)
    {
      digitalWrite(drink_pump2, HIGH);
      timer_no1 = timer.setTimeout(drink_time, []()
      {
        digitalWrite(drink_pump2, LOW);
        timer.deleteTimer(timer_no1);
      });
    }
    else if (drink_no == 9)
    {
      digitalWrite(drink_pump2, HIGH);
      digitalWrite(drink_pump, HIGH);
      timer_no1 = timer.setTimeout(drink_time, []()
      {
        digitalWrite(drink_pump, LOW);
        timer.deleteTimer(timer_no1);
      });
      timer_no4 = timer.setTimeout(drink_time1, []()
      {
        digitalWrite(drink_pump2, LOW);
        timer.deleteTimer(timer_no4);
      });
    }
  } 
  {
    digitalWrite(water_pump, HIGH);
    timer_no2 = timer.setTimeout(water_time, []()
    {
      digitalWrite(water_pump, LOW);
      timer.deleteTimer(timer_no2);
    });
  }
  float maxValue = max(drink_time, water_time);
  maxValue = maxValue + 2000.0;
  timer_no3 = timer.setTimeout(maxValue, []()
  {
    Blynk.virtualWrite(V16,0);
    Blynk.virtualWrite(V17,0);
    Blynk.virtualWrite(V1,0);
    timer.deleteTimer(timer_no3);
  });
  
}

BLYNK_WRITE(V2)
{
  int reset_button = param.asInt();
  if (reset_button == 1)
  {
    Blynk.virtualWrite(V16,0);
    Blynk.virtualWrite(V17,0);
  }
}





BLYNK_WRITE(V16)
{
  cup_no = param.asInt();
  switch(cup_no)
  {
    case 1:
    {
      cup_size = small;
      break;
    }
    case 2:
    {
      cup_size = medium;
      break;
    }
    case 3:
    {
      cup_size = large;
      break;
    }
    default:
    { 
      cup_size = 0;
      break;
    }
  }

}

BLYNK_WRITE(V17)
{
  drink_no = param.asInt();
  switch(drink_no)
  {
    case 4:
    {
      drink_type = apple_ratio; //apple
      drink_type1 = 0;
      drink_type2 = 0;
      break;
    }
    case 5:
    {
      drink_type = orange_ratio; //orange
      drink_type1 = 0;
      drink_type2 = 0;
      break;
    }
    case 9:
    {
      drink_type = orange_ratio / 2; //orange
      drink_type1 = apple_ratio / 2;
      drink_type2 = 0;
      break;
    }
    default:
    { drink_type = 0;
      drink_type1 = 0;
      drink_type2 = 0;
      break;
    }
  }
  water_ratio = 1.0 - drink_type - drink_type1 - drink_type2;
}



void ratio_calculation()
{
  drink_time = cup_size * drink_type / pump1Flow * 1000.0;
  drink_time1 = cup_size * drink_type1 / pump1Flow * 1000.0;
  drink_time2 = cup_size * drink_type2 / pump1Flow * 1000.0;
  water_time = cup_size * water_ratio / pump2Flow * 1000.0;
}




//====================================================


void setup()
{
  Serial.begin(115200);
  Serial3.begin(115200);
 EspSerial.begin(ESP8266_BAUD);
 Blynk.begin(auth, wifi, ssid, pass);            //Reguler server
  pinMode(drink_pump, OUTPUT);
  pinMode(drink_pump2, OUTPUT);
  pinMode(water_pump, OUTPUT);
  timer.setInterval(1000L, ratio_calculation);


}

void loop()
{
  Blynk.run();
 
  timer.run();
 
//if ( Serial3.available() )   {
//Serial3.read();
//}
//if ( Serial.available() )    {
// Serial.read();

}

//

You seem to have answered your own question, but without seeing the serial monitor information it’s difficult to understand exactly what it is that you are seeing.

Normally, functions (voids as you call them) are re-usable modules of code that can be called from multiple places within your code.
If you are only calling the function from one place within your code - BLYNK_WRITE(V1) in this case - then it makes no difference. Some people find it easier to have the whole code in one place, so you don’t have to keep jumping to a different location when you are debugging, but it’s a matter of personal taste.

Pete.

The serial monitor is shown as below

18:02:17.629 -> [0] 
18:02:17.629 ->     ___  __          __
18:02:17.629 ->    / _ )/ /_ _____  / /__
18:02:17.629 ->   / _  / / // / _ \/  '_/
18:02:17.629 ->  /____/_/\_, /_//_/_/\_\
18:02:17.629 ->         /___/ v0.6.1 on Arduino Mega
18:02:17.629 -> 
18:02:18.136 -> [506] Connecting to WiFI
18:02:21.160 -> [3557] WIFI GOT IP
18:02:21.160 -> AT version:1.1.0.0(May 11 2016 18:09:56)
18:02:21.160 -> SDK version:1.5.4(baaeaebb)
18:02:21.198 -> Ai-Thinker Technology Co. Ltd.
18:02:21.198 -> Jun 13 2016 11:29:20
18:02:21.198 -> OK
18:02:30.249 -> [12626] +CIFSR:STAIP,"192.168.1.4"
18:02:30.249 -> +CIFSR:STAMAC,"a4:cf:12:d7:30:b4"
18:02:30.249 -> [12627] Connected to WiFi
18:02:40.523 -> [22914] Ready (ping: 25ms).
18:03:20.129 -> [62493] Packet too big: 17452
18:03:25.365 -> [67746] Ready (ping: 21ms).
18:03:38.533 -> [80907] Buffer overflow
18:03:39.492 -> [81868] Buffer overflow
18:03:41.466 -> [83833] Buffer overflow
18:04:21.804 -> [124200] Ready (ping: 19ms).

So your actual issue is a “Packet too big”, which seems to roughly translate into “something went wrong”.
This is something that does seem to occur when RSSI is poor.

Pete.

Therefore, Wifi strength maybe one of the reason for the issue.
Is there any suggestion wifi strength requirement by Blynk for data transmission?
e.g. above 1mbps upload / download speed?

It’s more about signal strength (RSSI) than bandwidth.
If you fancy hacking the Blynk library then there is a way to see what the RSSI is when using your hardware combination…

Pete.

Dear Pete

I have tried your code, it returns -59 dB and -52 dB for the RSSI strength of 2 different wifi network…
In your experience, any numbers represented a good RSSI?

Acceptable Signal Strengths

Signal Strength TL;DR Required for
-30 dBm Amazing Max achievable signal strength. The client can only be a few feet from the AP to achieve this. Not typical or desirable in the real world. N/A
-67 dBm Very Good Minimum signal strength for applications that require very reliable, timely delivery of data packets. VoIP/VoWiFi, streaming video
-70 dBm Okay Minimum signal strength for reliable packet delivery. Email, web
-80 dBm Not Good Minimum signal strength for basic connectivity. Packet delivery may be unreliable. N/A
-90 dBm Unusable Approaching or drowning in the noise floor. Any functionality is highly unlikely. N/A

https://www.metageek.com/training/resources/understanding-rssi.html

You should maybe look at which WiFi channels are in use, using a WiFi scanner app, and ensure that you aren’t getting cross-channel interference from either your neighbours or from your own internal network(s).

Pete.

Dear Pete

I have add on an antenna on the board, the RSSI is improved to -46 dBm.
However,…packet too big are always occur…very confused about that.

As you seen, my codes did not run any functions before I press the virtual pin, I don’t know why packet too big will occur when I did not send or receive any data.

Also, when the wifi is disconnected, it did not auto reconnect it and keep offline…
BTW, my project is a DIY smart drink dispenser


//  LIBRARY
//====================================================
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <WiFi.h>
//#include <EEPROM.h>
//#include <ESP8266WiFi.h>
//====================================================

//  DEKLARASI AWAL
//====================================================
char auth[] = "token";
char ssid[] = "";
char pass[] = "";

#define EspSerial Serial3
#define ESP8266_BAUD 115200
ESP8266 wifi(&EspSerial);
//====================================================

//  global variables
//====================================================

int drink_pump1 = 27;
int drink_pump2 = 28;
int drink_pump3 = 31;
int drink_pump4 = 32;
int drink_pump5 = 35;
int drink_pump6 = 36;
int water_pump = 39;
int timer_no1;
int timer_no2;
int timer_no3;
int timer_no4;
int timer_no5;
int timer_no6;
long drink_time1;
long drink_time2;
long drink_time3;
long drink_time4;
long drink_time5;
long drink_time6;
long water_time;
float drink_type1;
float drink_type2;
float drink_type3;
float drink_type4;
float drink_type5;
float drink_type6;
int cup_size;
int confirmPressed;
float pump1Flow = 4; //drink pump flow speed ml/s
float pump2Flow = 6; //water pump flow speed ml/s
float pump3Flow = 8; //drink pump flow speed ml/s
float pump4Flow = 10; //water pump flow speed ml/s
float pump5Flow = 12; //drink pump flow speed ml/s
float pump6Flow = 14; //water pump flow speed ml/s
float hotwaterFlow = 15;
float coldwaterFlow = 20;
BlynkTimer timer;
float water_ratio;
int type_no;
int cup_no;
int drink_level;
int temp;
//====================================================
BLYNK_WRITE(V0)
{
  type_no = param[0].asInt();
  cup_no = param[1].asInt();
  temp = param[2].asInt();
  Blynk.virtualWrite(V17, type_no);
  Blynk.virtualWrite(V16, cup_no);
  Blynk.virtualWrite(V18, temp);
}

BLYNK_WRITE(V16)
{
int small = 237; //8oz
int medium = 355; //12oz
int large = 473; //16oz
  cup_no = param.asInt();
  switch(cup_no)
  {
    case 1:
    {
      cup_size = small;
      break;
    }
    case 2:
    {
      cup_size = medium;
      break;
    }
    case 3:
    {
      cup_size = large;
      break;
    }
    default:
    { 
      cup_size = 0;
      break;
    }
  }
  Serial.println(cup_size);
}

BLYNK_WRITE(V17)
{
  float drink1_ratio = 1.0 / (1.0 + 9.0);
  float drink2_ratio = 1.0 / (1.0 + 9.0);
  float drink3_ratio = 1.0 / (1.0 + 9.0);
  float drink4_ratio = 1.0 / (1.0 + 9.0);
  float drink5_ratio = 1.0 / (1.0 + 9.0);
  float drink6_ratio = 1.0 / (1.0 + 9.0);
  type_no = param.asInt();
  switch(type_no)
  {
    case 1:
    {
      drink_type1 = drink1_ratio; //apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
    case 2:
    {
      drink_type1 = 0; //orange
      drink_type2 = drink2_ratio;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
    case 3:
    {
      drink_type1 = 0; //orange
      drink_type2 = 0;
      drink_type3 = drink3_ratio;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
    case 4:
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = drink4_ratio;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
    case 5:
    {
      drink_type1 = 0;; //orange
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = drink5_ratio;
      drink_type6 = 0;
      break;
    }
    case 6:
    {
      drink_type1 = 0; //orange
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = drink6_ratio;
      break;
    }
    case 9:
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = drink4_ratio / 2.0;
      drink_type5 = drink5_ratio / 2.0;
      drink_type6 = 0;
      break;
    }
    case 10:
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = drink4_ratio / 2.0;
      drink_type5 = 0;
      drink_type6 = drink6_ratio / 2.0;
      break;
    }
    case 11:
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = drink5_ratio / 2.0;
      drink_type6 = drink6_ratio / 2.0;
      break;
    }
    case 15:
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = drink4_ratio / 3.0;
      drink_type5 = drink5_ratio / 3.0;
      drink_type6 = drink6_ratio / 3.0;
      break;
    }
    default:
    { drink_type1 = 0;
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
  }
  water_ratio = 1.0 - drink_type1 - drink_type2 - drink_type3 - drink_type4 - drink_type5 - drink_type6;
  Serial.println(drink_type1);
  Serial.println(drink_type2);
  Serial.println(drink_type3);
  Serial.println(drink_type4);
  Serial.println(drink_type5);
  Serial.println(drink_type6);

}

BLYNK_WRITE(V1)
{
  unsigned long PreviousMillis = 0;
  unsigned long CurrentMillis = millis();
  long interval = 2000;
  confirmPressed = param.asInt(); 
   if (confirmPressed == 1)
 {
  drink_time1 = cup_size * drink_type1 / pump1Flow * 1000.0;
  drink_time2 = cup_size * drink_type2 / pump2Flow * 1000.0;
  drink_time2 = cup_size * drink_type3 / pump3Flow * 1000.0;
  drink_time4 = cup_size * drink_type4 / pump4Flow * 1000.0;
  drink_time5 = cup_size * drink_type5 / pump5Flow * 1000.0;
  drink_time6 = cup_size * drink_type6 / pump6Flow * 1000.0;
  water_time = cup_size * water_ratio / coldwaterFlow * 1000.0;
 }
 if (CurrentMillis - PreviousMillis > interval)
 {
  mix();
 }
 Serial.println(drink_time1);
 Serial.println(drink_time2);
 Serial.println(drink_time3);
 Serial.println(drink_time4);
 Serial.println(drink_time5);
 Serial.println(drink_time6);
 Serial.println(water_time);
}


void mix()
{
  Serial.print("fuck u");
  switch(type_no)
  {
    case 1:
    {
      digitalWrite(drink_pump1, HIGH);
      timer_no1 = timer.setTimeout(drink_time1, []()
      {
        digitalWrite(drink_pump1, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 2:
    {
      digitalWrite(drink_pump2, HIGH);
      timer_no1 = timer.setTimeout(drink_time2, []()
      {
        digitalWrite(drink_pump2, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    }
    case 3:
    {
      digitalWrite(drink_pump3, HIGH);
      timer_no1 = timer.setTimeout(drink_time3, []()
      {
        digitalWrite(drink_pump3, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 4:
    {
      digitalWrite(drink_pump4, HIGH);
      timer_no1 = timer.setTimeout(drink_time4, []()
      {
        digitalWrite(drink_pump4, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 5:
    {
      digitalWrite(drink_pump5, HIGH);
      timer_no1 = timer.setTimeout(drink_time5, []()
      {
        digitalWrite(drink_pump5, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 6:
    {
      digitalWrite(drink_pump6, HIGH);
      timer_no1 = timer.setTimeout(drink_time6, []()
      {
        digitalWrite(drink_pump6, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 9:
    {
      digitalWrite(drink_pump4, HIGH);
      timer_no2 = timer.setTimeout(drink_time4, []()
      {
        digitalWrite(drink_pump4, LOW);
        timer.deleteTimer(timer_no2);
      }); 
      digitalWrite(drink_pump5, HIGH);
      timer_no3 = timer.setTimeout(drink_time5, []()
      {
        digitalWrite(drink_pump5, LOW);
        timer.deleteTimer(timer_no3);
      }); 
      break;
    } 
    case 10:
    {
      digitalWrite(drink_pump4, HIGH);
      timer_no2 = timer.setTimeout(drink_time4, []()
      {
        digitalWrite(drink_pump4, LOW);
        timer.deleteTimer(timer_no2);
      }); 
      digitalWrite(drink_pump6, HIGH);
      timer_no3 = timer.setTimeout(drink_time6, []()
      {
        digitalWrite(drink_pump6, LOW);
        timer.deleteTimer(timer_no3);
      }); 
      break;
    }
    case 11:
    {
      digitalWrite(drink_pump5, HIGH);
      timer_no2 = timer.setTimeout(drink_time5, []()
      {
        digitalWrite(drink_pump5, LOW);
        timer.deleteTimer(timer_no2);
      }); 
      digitalWrite(drink_pump6, HIGH);
      timer_no3 = timer.setTimeout(drink_time6, []()
      {
        digitalWrite(drink_pump6, LOW);
        timer.deleteTimer(timer_no3);
      }); 
      break;
    }
    case 15:
    {
      digitalWrite(drink_pump4, HIGH);
      timer_no2 = timer.setTimeout(drink_time4, []()
      {
        digitalWrite(drink_pump4, LOW);
        timer.deleteTimer(timer_no2);
      }); 
      digitalWrite(drink_pump5, HIGH);
      timer_no3 = timer.setTimeout(drink_time5, []()
      {
        digitalWrite(drink_pump5, LOW);
        timer.deleteTimer(timer_no3);
      }); 
      digitalWrite(drink_pump6, HIGH);
      timer_no4 = timer.setTimeout(drink_time6, []()
      {
        digitalWrite(drink_pump6, LOW);
        timer.deleteTimer(timer_no4);
      }); 
      break;
    }
    default:
    {
      digitalWrite(drink_pump1, LOW);
      digitalWrite(drink_pump2, LOW);
      digitalWrite(drink_pump3, LOW);
      digitalWrite(drink_pump4, LOW);
      digitalWrite(drink_pump5, LOW);
      digitalWrite(drink_pump6, LOW);
    }
   
}
{
  digitalWrite(water_pump, HIGH);
  timer_no5 = timer.setTimeout(water_time, []()
    {
      digitalWrite(water_pump, LOW);
      timer.deleteTimer(timer_no5);
    });
  }
  float finishTime = water_time + 2000.0;
   timer_no6 = timer.setTimeout(finishTime, []()
  {
    Blynk.virtualWrite(V16,0);
    Blynk.virtualWrite(V17,0);
    Blynk.virtualWrite(V18,0);
    Blynk.virtualWrite(V1,0);
    Serial.println("Mixing is finish");
    timer.deleteTimer(timer_no6);
  });
}


BLYNK_WRITE(V2)
{
  int reset_button = param.asInt();
  if (reset_button == 1)
  {
    Blynk.virtualWrite(V16,0);
    Blynk.virtualWrite(V17,0);
    
    //terminal.clear();
  }
}












//====================================================


void setup()
{
  Serial.begin(115200);
  Serial3.begin(115200);

 
 EspSerial.begin(ESP8266_BAUD);
 //Blynk.begin(auth, wifi, ssid, pass);            //Reguler server
Blynk.config(wifi, auth, "blynk-cloud.com", 8080);
Blynk.connectWiFi(ssid, pass);
////Blynk.connect();
int i = 0;
 while ((i++ < 20) && !Blynk.connect()) 
{       
delay(500);
    }

  pinMode(drink_pump1, OUTPUT);
  pinMode(drink_pump2, OUTPUT);
  pinMode(drink_pump3, OUTPUT);
  pinMode(drink_pump4, OUTPUT);
  pinMode(drink_pump5, OUTPUT);
  pinMode(drink_pump6, OUTPUT);
  pinMode(water_pump, OUTPUT);
  String ap_stats = wifi.getNowConecAp();
  Serial.println(ap_stats);

}


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

if ( Serial3.available() )   {
Serial3.read();
}
if ( Serial.available() )    {
  Serial.read();
}

}

//

Sounds like it’s time to do some forensic fault-finding.
If the device works perfectly on your desk, but not in a remote location then look at what is changing.
Are you using the same power supply in both situations?
What happens if you move the device away from your desk and towards the location where it will be used? Do you start to get errors as it moved towards your new location?
What happens if you place the 4G router at your desk and use the router’s WiFi rather than the WiFi that works at your desk?

Stick to the principle of changing one thing at a time until you find the cause of the issue.

Pete.

Now even I tried on my desk (no hardwares connected , RSSI is -46dBm)
packet too big is still occur.

But it really fluctuate, sometimes there is no problem for few hours, sometimes will keep error occurring

Can you explain the logic behind this code in your void loop?

Pete.

Ah, it just the coding I copy from another, as I thought the buffer overflow issue related to Serial data transmission.

However, I had tried to remove this code, packet too big / buffer overflow still occur.
And now when the error occur, it disconnect my device and never online again.
(in previous trial, it will auto connect wifi again)
even I tried Blynk.config or Blynk.begin, same result.

Actually, I am using the Robotdyn ATMega2560 with built-in ESP8266 module, I don’t know is it the hardware problem. I activate the board by following this guy’s video.


Is it better to use UNO WiFi? (but my codes is so long as a smart drink dispenser with IoT function). Besides, I have used NodeMCU for some small projects with same WiFi too, it is very smooth and nearly no disconnection over a week, so…it may really related to my board…I guess

It sounds like an ESP32 would be a much better choice for this project.

Pete.

You mean Nodemcu?
Or use UNO + esp-01 as AP?
As i need several Analog and digital pin, so UNO or Mega is necessary

Pete, I changed to NodeMcu for this project , it seems very stable for this morning trial.
I may use 2 Nodemcu with bridge function to solve the demand of I/O pins.

However, a strange thing I found.
Everything is fine before running void mix().
When case(type_no) is 1,4,5,6,9, 10,11 or 15 the program runs correctly.
when case(type_no) is 2, 3 after pressed V1 button
(run BLYNK_WRITE(V1) then run mix()),
**the board will restart and reconnect **
(exactly same effect as press RST button on the board).

But I don’t think it is related to the digital Pin D1 & D2, it is normal that I check with pressing D1 & D2 button widget, also I changed D1 & D2 to D7 & D8, same issue occur.

I also change the virtual pin button from V1 to V3, same issue occur when case is 2 or 3.

I am also confused why I press the V1 button will run the previous mixing procedure even I have not send the case(type_no) or case = 0, and I have reset V16 V17 & V1 value to 0 after mixing finish or pressed reset button (V2).
e.g. Run case(1) -> finished -> reset to zero -> press V1 (now case is 0) -> case(1) run again

Below is my code and serial monitor.
The serial monitor is the condition of doing case 1 then do case 2


//  LIBRARY
//====================================================
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

//====================================================

//  DEKLARASI AWAL
//====================================================
char auth[] = 
char ssid[] = 
char pass[] = 

//====================================================

//  global variables
//====================================================

int drink_pump1 = 16; //D0
int drink_pump2 = 5; //D1
int drink_pump3 = 4; //D2
int drink_pump4 = 0; //D3
int drink_pump5 = 2; //D4
int drink_pump6 = 14; //D5
int water_pump = 12; //D6
int timer_no1;
int timer_no2;
int timer_no3;
int timer_no4;
int timer_no5;
int timer_no6;
long drink_time1;
long drink_time2;
long drink_time3;
long drink_time4;
long drink_time5;
long drink_time6;
long water_time;
float drink_type1;
float drink_type2;
float drink_type3;
float drink_type4;
float drink_type5;
float drink_type6;
int cup_size;
int confirmPressed;
float pump1Flow = 4; //drink pump flow speed ml/s
float pump2Flow = 6; //water pump flow speed ml/s
float pump3Flow = 8; //drink pump flow speed ml/s
float pump4Flow = 10; //water pump flow speed ml/s
float pump5Flow = 12; //drink pump flow speed ml/s
float pump6Flow = 14; //water pump flow speed ml/s
float hotwaterFlow = 15;
float coldwaterFlow = 20;
BlynkTimer timer;
float water_ratio;
int type_no;
int cup_no;
int drink_level;
int temp;
//====================================================
BLYNK_WRITE(V0)
{
  type_no = param[0].asInt();
  cup_no = param[1].asInt();
  temp = param[2].asInt();
  Blynk.virtualWrite(V17, type_no);
  Blynk.virtualWrite(V16, cup_no);
  Blynk.virtualWrite(V18, temp);
}

BLYNK_WRITE(V16)
{
int small = 237; //8oz
int medium = 355; //12oz
int large = 473; //16oz
  cup_no = param.asInt();
  switch(cup_no)
  {
    case 1:
    {
      cup_size = small;
      break;
    }
    case 2:
    {
      cup_size = medium;
      break;
    }
    case 3:
    {
      cup_size = large;
      break;
    }
    default:
    { 
      cup_size = 0;
      break;
    }
  }
  Serial.println(cup_size);
}

BLYNK_WRITE(V17)
{
  float drink1_ratio = 1.0 / (1.0 + 9.0);
  float drink2_ratio = 1.0 / (1.0 + 9.0);
  float drink3_ratio = 1.0 / (1.0 + 9.0);
  float drink4_ratio = 1.0 / (1.0 + 9.0);
  float drink5_ratio = 1.0 / (1.0 + 9.0);
  float drink6_ratio = 1.0 / (1.0 + 9.0);
  type_no = param.asInt();
  switch(type_no)
  {
    case 1:
    {
      drink_type1 = drink1_ratio; //apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
    case 2:
    {
      drink_type1 = 0; //orange
      drink_type2 = drink2_ratio;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
    case 3:
    {
      drink_type1 = 0; //orange
      drink_type2 = 0;
      drink_type3 = drink3_ratio;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
    case 4:
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = drink4_ratio;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
    case 5:
    {
      drink_type1 = 0;; //orange
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = drink5_ratio;
      drink_type6 = 0;
      break;
    }
    case 6:
    {
      drink_type1 = 0; //orange
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = drink6_ratio;
      break;
    }
    case 9: //mix drink 4 + drink 5
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = drink4_ratio / 2.0;
      drink_type5 = drink5_ratio / 2.0;
      drink_type6 = 0;
      break;
    }
    case 10: //mix drink 4 + drink 6
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = drink4_ratio / 2.0;
      drink_type5 = 0;
      drink_type6 = drink6_ratio / 2.0;
      break;
    }
    case 11: //mix drink 6 + drink 5
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = drink5_ratio / 2.0;
      drink_type6 = drink6_ratio / 2.0;
      break;
    }
    case 15: //mix drink 4 + drink 5 + drink 6
    {
      drink_type1 = 0;//apple
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = drink4_ratio / 3.0;
      drink_type5 = drink5_ratio / 3.0;
      drink_type6 = drink6_ratio / 3.0;
      break;
    }
    default:
    { drink_type1 = 0;
      drink_type2 = 0;
      drink_type3 = 0;
      drink_type4 = 0;
      drink_type5 = 0;
      drink_type6 = 0;
      break;
    }
  }
  water_ratio = 1.0 - drink_type1 - drink_type2 - drink_type3 - drink_type4 - drink_type5 - drink_type6;
  Serial.print("drink_type1 =");
  Serial.println(drink_type1);
  Serial.print("drink_type2 =");
  Serial.println(drink_type2);
  Serial.print("drink_type3 =");
  Serial.println(drink_type3);
  Serial.print("drink_type4 =");
  Serial.println(drink_type4);
  Serial.print("drink_type5 =");
  Serial.println(drink_type5);
  Serial.print("drink_type6 =");
  Serial.println(drink_type6);

}

BLYNK_WRITE(V1)
{
  unsigned long PreviousMillis = 0;
  unsigned long CurrentMillis = millis();
  long interval = 2000;
  confirmPressed = param.asInt(); 
   if (confirmPressed == 1)
 {
  drink_time1 = cup_size * drink_type1 / pump1Flow * 1000.0;
  drink_time2 = cup_size * drink_type2 / pump2Flow * 1000.0;
  drink_time2 = cup_size * drink_type3 / pump3Flow * 1000.0;
  drink_time4 = cup_size * drink_type4 / pump4Flow * 1000.0;
  drink_time5 = cup_size * drink_type5 / pump5Flow * 1000.0;
  drink_time6 = cup_size * drink_type6 / pump6Flow * 1000.0;
  water_time = cup_size * water_ratio / coldwaterFlow * 1000.0;
 }
 if (CurrentMillis - PreviousMillis > interval)
 {
  mix();
 }
 Serial.print("drink_time1 =");
 Serial.println(drink_time1);
 Serial.print("drink_time2 =");
 Serial.println(drink_time2);
 Serial.print("drink_time3 =");
 Serial.println(drink_time3);
 Serial.print("drink_time4 =");
 Serial.println(drink_time4);
 Serial.print("drink_time5 =");
 Serial.println(drink_time5);
 Serial.print("drink_time6 =");
 Serial.println(drink_time6);
 Serial.print("water_time=");
 Serial.println(water_time);
}


void mix()
{
  Serial.println("Start mixing");
  switch(type_no)
  {
    case 1:
    {
      digitalWrite(drink_pump1, HIGH);
      timer_no1 = timer.setTimeout(drink_time1, []()
      {
        digitalWrite(drink_pump1, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 2:
    {
      digitalWrite(drink_pump2, HIGH);
      timer_no1 = timer.setTimeout(drink_time2, []()
      {
        digitalWrite(drink_pump2, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    }
    case 3:
    {
      digitalWrite(drink_pump3, HIGH);
      timer_no1 = timer.setTimeout(drink_time3, []()
      {
        digitalWrite(drink_pump3, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 4:
    {
      digitalWrite(drink_pump4, HIGH);
      timer_no1 = timer.setTimeout(drink_time4, []()
      {
        digitalWrite(drink_pump4, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 5:
    {
      digitalWrite(drink_pump5, HIGH);
      timer_no1 = timer.setTimeout(drink_time5, []()
      {
        digitalWrite(drink_pump5, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 6:
    {
      digitalWrite(drink_pump6, HIGH);
      timer_no1 = timer.setTimeout(drink_time6, []()
      {
        digitalWrite(drink_pump6, LOW);
        timer.deleteTimer(timer_no1);
      }); 
      break;
    } 
    case 9:
    {
      digitalWrite(drink_pump4, HIGH);
      timer_no2 = timer.setTimeout(drink_time4, []()
      {
        digitalWrite(drink_pump4, LOW);
        timer.deleteTimer(timer_no2);
      }); 
      digitalWrite(drink_pump5, HIGH);
      timer_no3 = timer.setTimeout(drink_time5, []()
      {
        digitalWrite(drink_pump5, LOW);
        timer.deleteTimer(timer_no3);
      }); 
      break;
    } 
    case 10:
    {
      digitalWrite(drink_pump4, HIGH);
      timer_no2 = timer.setTimeout(drink_time4, []()
      {
        digitalWrite(drink_pump4, LOW);
        timer.deleteTimer(timer_no2);
      }); 
      digitalWrite(drink_pump6, HIGH);
      timer_no3 = timer.setTimeout(drink_time6, []()
      {
        digitalWrite(drink_pump6, LOW);
        timer.deleteTimer(timer_no3);
      }); 
      break;
    }
    case 11:
    {
      digitalWrite(drink_pump5, HIGH);
      timer_no2 = timer.setTimeout(drink_time5, []()
      {
        digitalWrite(drink_pump5, LOW);
        timer.deleteTimer(timer_no2);
      }); 
      digitalWrite(drink_pump6, HIGH);
      timer_no3 = timer.setTimeout(drink_time6, []()
      {
        digitalWrite(drink_pump6, LOW);
        timer.deleteTimer(timer_no3);
      }); 
      break;
    }
    case 15:
    {
      digitalWrite(drink_pump4, HIGH);
      timer_no2 = timer.setTimeout(drink_time4, []()
      {
        digitalWrite(drink_pump4, LOW);
        timer.deleteTimer(timer_no2);
      }); 
      digitalWrite(drink_pump5, HIGH);
      timer_no3 = timer.setTimeout(drink_time5, []()
      {
        digitalWrite(drink_pump5, LOW);
        timer.deleteTimer(timer_no3);
      }); 
      digitalWrite(drink_pump6, HIGH);
      timer_no4 = timer.setTimeout(drink_time6, []()
      {
        digitalWrite(drink_pump6, LOW);
        timer.deleteTimer(timer_no4);
      }); 
      break;
    }
    default:
    {
      digitalWrite(drink_pump1, LOW);
      digitalWrite(drink_pump2, LOW);
      digitalWrite(drink_pump3, LOW);
      digitalWrite(drink_pump4, LOW);
      digitalWrite(drink_pump5, LOW);
      digitalWrite(drink_pump6, LOW);
    }
   
}
{
  digitalWrite(water_pump, HIGH);
  timer_no5 = timer.setTimeout(water_time, []()
    {
      digitalWrite(water_pump, LOW);
      timer.deleteTimer(timer_no5);
    });
  }
  float finishTime = water_time + 2000.0;
   timer_no6 = timer.setTimeout(finishTime, []()
  {
    Blynk.virtualWrite(V16,0);
    Blynk.virtualWrite(V17,0);
    Blynk.virtualWrite(V18,0);
    Blynk.virtualWrite(V1,0);
    Serial.println("Mixing is finish");
    timer.deleteTimer(timer_no6);
  });
}


BLYNK_WRITE(V2)
{
  int reset_button = param.asInt();
  if (reset_button == 1)
  {
    Blynk.virtualWrite(V16,0);
    Blynk.virtualWrite(V17,0);
    Blynk.virtualWrite(V1, 0);
    drink_level = drink_level + 5000.0;
  }
}












//====================================================


void setup()
{
  Serial.begin(115200);
//Blynk.begin(auth, ssid, pass);            //Reguler server

Blynk.config(auth);
Blynk.connectWiFi(ssid, pass);

Blynk.connect();

  pinMode(drink_pump1, OUTPUT);
  pinMode(drink_pump2, OUTPUT);
  pinMode(drink_pump3, OUTPUT);
  pinMode(drink_pump4, OUTPUT);
  pinMode(drink_pump5, OUTPUT);
  pinMode(drink_pump6, OUTPUT);
  pinMode(water_pump, OUTPUT);
  digitalWrite(drink_pump1, LOW);
  digitalWrite(drink_pump2, LOW);
  digitalWrite(drink_pump3, LOW);
  digitalWrite(drink_pump4, LOW);
  digitalWrite(drink_pump5, LOW);
  digitalWrite(drink_pump6, LOW);
  digitalWrite(water_pump, LOW);
  Blynk.virtualWrite(V0, 0);
  Blynk.virtualWrite(V1, 0);
  

}


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


}

//

11:32:14.054 -> drink_type1 =0.10
11:32:14.054 -> drink_type2 =0.00
11:32:14.054 -> drink_type3 =0.00
11:32:14.054 -> drink_type4 =0.00
11:32:14.054 -> drink_type5 =0.00
11:32:14.054 -> drink_type6 =0.00
11:32:14.834 -> 237
11:32:18.434 -> Start mixing
11:32:18.434 -> drink_time1 =5925
11:32:18.434 -> drink_time2 =0
11:32:18.434 -> drink_time3 =0
11:32:18.434 -> drink_time4 =0
11:32:18.434 -> drink_time5 =0
11:32:18.434 -> drink_time6 =0
11:32:18.434 -> water_time=10664
11:32:31.205 -> Mixing is finish
11:32:35.321 -> drink_type1 =0.00
11:32:35.355 -> drink_type2 =0.10
11:32:35.355 -> drink_type3 =0.00
11:32:35.355 -> drink_type4 =0.00
11:32:35.355 -> drink_type5 =0.00
11:32:35.355 -> drink_type6 =0.00
11:32:36.803 -> 237
11:32:38.111 -> Start mixing
11:32:38.111 -> drink_time1 =0
11:32:38.111 -> drink_time2 =0
11:32:38.111 -> drink_time3 =0
11:32:38.111 -> drink_time4 =0
11:32:38.111 -> drink_time5 =0
11:32:38.111 -> drink_time6 =0
11:32:38.111 -> water_time=10664
11:32:38.111 -> 
11:32:38.111 -> Exception (0):
11:32:38.111 -> epc1=0x4000e25d epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
11:32:38.147 -> 
11:32:38.147 -> >>>stack>>>
11:32:38.147 -> 
11:32:38.147 -> ctx: cont
11:32:38.147 -> sp: 3ffffdc0 end: 3fffffc0 offset: 0190
11:32:38.147 -> 3fffff50:  0004c5b5 3ffeeccc 00000000 402045dd  
11:32:38.147 -> 3fffff60:  0004c5b5 00000000 0004c5b5 00000000  
11:32:38.147 -> 3fffff70:  00000001 00000002 0000000c 3ffe84f8  
11:32:38.147 -> 3fffff80:  00000000 00000000 00000001 3ffeee5c  
11:32:38.147 -> 3fffff90:  3fffdad0 00000000 3ffeee1c 40202da5  
11:32:38.147 -> 3fffffa0:  3fffdad0 00000000 3ffeee1c 40205430  
11:32:38.185 -> 3fffffb0:  feefeffe feefeffe 3ffe854c 40100cb9  
11:32:38.185 -> <<<stack<<<
11:32:38.185 -> 
11:32:38.185 ->  ets Jan  8 2013,rst cause:2, boot mode:(3,6)
11:32:38.185 -> 
11:32:38.185 -> load 0x4010f000, len 3456, room 16 
11:32:38.185 -> tail 0
11:32:38.185 -> chksum 0x84
11:32:38.185 -> csum 0x84
11:32:38.185 -> va5432625
11:32:38.185 -> ~ld
11:32:38.257 -> [67] 
11:32:38.257 ->     ___  __          __
11:32:38.257 ->    / _ )/ /_ _____  / /__
11:32:38.257 ->   / _  / / // / _ \/  '_/
11:32:38.257 ->  /____/_/\_, /_//_/_/\_\
11:32:38.257 ->         /___/ v0.6.1 on NodeMCU
11:32:38.257 -> 
11:32:38.257 -> [69] Connecting to GWIFI99
11:32:38.754 -> [574] Connected to WiFi
11:32:38.754 -> [575] IP: 172.31.2.229
11:32:38.792 -> [575] Connecting to blynk-cloud.com:80
11:32:38.975 -> [769] Ready (ping: 50ms).

I suggested an ESP32 because it has more usable I/O pins than the NodeMCU and many of the pins can be defined as digital or analog to suit your needs…

As far as your unexpected crashes are concerned, it’s difficult to say.
I tried to make some sense of your code but couldn’t figure-out what widgets you had attached to the the various virtual pins and your code seemed to be very clunky in places. I cant understand the need for the whole switch case function in BLYNK_WRITE(V17) and the purpose of the drink_type1 to drink_type6 variables, so I gave up trying to figure it out.

Pete.


As my team mate will create a UI using the RESTful HTTP API to send the information what order has the client made through V0 (order information) and V1 (click to confirm)

Why there are V16 and V17 because I can test the program by input number on mobile blynk.
In finished prototype, V16 and V17 can be eliminated and move all codes into BLYNK_WRITE(V0).

As there are 6 types of drinks and 6 independent syrup pumps in my machine, I need to analyze the data stored in V0 to ask the specific pump get ON.
And drinks can be selected in 1 type, mix of 2 types or mix of 3 types.

e.g.
V0 = [1, 1], i.e. [drink1 is selected, small size is selected]
V0 = [4, 2], i.e. [drink4 is selected, medium size is selected]
Therefore, I have so many case to ensure I could pass the correct data to calculate the accurate pump ON time and drink volume. Drink_type is the syrup-water ratio, e.g. 1:9. , when it is mix of 2 drinks,
each ratio will be divided by 2, mix of 3 drinks, ratio will be divided by 3, etc.

But anyway, I will buy some ESP32 boards to test. Thanks Pete

None of what you’ve said tells me anything about what type of widget is attached to each of the virtual pins!

Is this going to be built-in to a commercial drinks machine?

Pete.


Sorry, my bad.
No, it is not for commercial, it is our college final year group project to build up a prototype drink dispenser with smart function
(e.g. online ordering, auto notification to refill drink before sold out, etc)

Basically, the client would not touch the Blynk app, they just use our UI and data transmission through Blynk virtual pins and RESTFul HTTPAPI to the machine (Arduino Board).
The system would only use WiFi for data transmission

Besides, I found that if the V0 value sent from HTTP API write via GET, the issue will occur in any cases, but in Blynk app is normal except case(2 & 3)