Brown outs or reboots

In my Arduino project, while utilizing Blynk.begin(auth, server, port); in my sketch for a wired connection, I find that my sketch has become dependent on a re-established connection to the blynk-cloud after a brown out or reboot. The problem is that I have a long list of other tasks that need to be executed with or without network connection. I need it to be able to exit the void setup() and proceed to the void loop() immediately after regaining power and not get hung up awaiting a network connection. Is there a short answer to this? FWIW, I have a seasoned coder working with me privately, but the structure of the Blynk library has thrown a hurdle in our path as it relates to this one issue. Any insights will be helpful.

TYIA

If this means you are using the ESP hooked up to give WiFi to an Arduino the short answer is there is no easy fix.
If you use the ESP for it’s intended purpose, a MCU with WiFi, then I posted the code, again, in the last few days to bypass the Blynk.begin() code blocking routine.
If your seasoned coder looked closely at the Blynk libraries for Blynk.config() and Blynk.connect() they might be able to port them from an ESP to an Arduino.
Alternatively if you really need an Arduino in your project you could go ESP with Arduino shield route, rather than Arduino with ESP shield.

Sorry, I probably should have mentioned, I’m using an Ethernet connection directly from router. My code friend mentioned how WiFi is handled one way while Ethernet is handled another.

Which Arduino are you using?

Mega2560

@myggle this is for a Mega with ENC28J60. Tries Ethernet connection for 5s and then continues with your sketch regardless. Tries again 25s later. Serial Monitor suggests it works OK but my router is currently too far from the Mega to test it. Might also want some WDT stuff. See how you go.

#define BLYNK_PRINT Serial /* Comment this out to disable prints and save space */
#include <UIPEthernet.h>
#include <BlynkSimpleUIPEthernet.h>
BlynkTimer timer;
char auth[] = "YourAuthToken";
unsigned int myEthernetTimeout =   5000;  //  5.0s Ethernet Connection Timeout (ECT)
unsigned int blynkInterval     =  25000;  // 25.0s Check Server Frequency      (CSF)

void setup()
{
  Serial.begin(115200);      // Debug console, Mega is OK at 115200
  Serial.println();
  timer.setInterval(myEthernetTimeout, myfunction);
  timer.setInterval(blynkInterval, checkBlynk);   // check connection to server per blynkInterval  
  Blynk.config(auth, "blynk-cloud.com");  // this is OK
  Blynk.connect();
}


void myfunction(){
  Serial.println("\tLook, no Blynk  block.");
  if(Blynk.connected()){
    Serial.println("\tEthernet still  connected.");
    Blynk.virtualWrite(V11, millis() / 1000);
  }
}

void checkBlynk() {
  unsigned long startConnecting = millis();    
  while(!Blynk.connected()){
    Blynk.connect();  
    if(millis() > startConnecting + myEthernetTimeout){
      Serial.print("\tUnable to connect to server. ");
      break;
    }
  }
  Serial.println("Checking again in 25s.");
}

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

Edit: ignore the sketch above and use the one below as it was missing Ethernet connection.

1 Like

@myggle I hooked up my Ethernet cable and realised the sketch was missing the Ethernet connection.
This sketch certainly handles disconnecting the Ethernet / Power cables.

#define BLYNK_PRINT Serial /* Comment this out to disable prints and save space */
#include <UIPEthernet.h>
#include <BlynkSimpleUIPEthernet.h>
BlynkTimer timer;
char auth[] = "xxxxxxxxxxxxxx";
unsigned int myEthernetTimeout =   5000;  // Ethernet Connection Timeout (ECT)
unsigned int blynkInterval     =  25000;  // Check Server Frequency      (CSF)

byte arduino_mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };    //DE:ED:BA:FE:FE:ED
char server[]=    "blynk-cloud.com"; // can use "blynk-cloud.com" or an IP address
IPAddress arduino_ip ( 192,   168,   10,  120);
IPAddress dns_ip     (  192,   168,   10,   90);
IPAddress gateway_ip ( 192,   168,   10,   90);
IPAddress subnet_mask(255, 255, 255,   0);

void setup()
{
  Serial.begin(115200);      // Debug console, Mega is OK at 115200
  Serial.println();
  timer.setInterval(myEthernetTimeout, myfunction);
  timer.setInterval(blynkInterval, checkBlynk);   // check connection to server per blynkInterval    
  Ethernet.begin(arduino_mac, arduino_ip, dns_ip, gateway_ip, subnet_mask );
  Blynk.config(auth, server);  // this is OK
  Blynk.connect();             // this is OK
}


void myfunction(){
  Serial.println("\tLook, no Blynk block.");
  if(Blynk.connected()){
    Serial.println("\tEthernet still connected.");
    Blynk.virtualWrite(V11, millis() / 1000);
  }
}

void checkBlynk() {
  unsigned long startConnecting = millis();    
  while(!Blynk.connected()){
    Blynk.connect();  
    if(millis() > startConnecting + myEthernetTimeout){
      Serial.println("\tUnable to connect to server. ");
      break;
    }
  }
  Serial.print("\tChecking again in ");
  Serial.print(blynkInterval / 1000.0);
  Serial.println("s.");
}

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

I added in your first suggested mods and ran it, but it didn’t connect. It seems no matter what we’ve tried, if it favors Blynk.config(x, x, x) over Blynk.begin(x, x, x), it never actually connects. The moment I revert it back to .begin(x, x, x), it connects and does all of the magic except exit the setup loop until the connection is re-established. I noticed your 2nd suggestion also uses Blynk.config(). In your honest opinion, do you think it will make the connection? I’m using the W5100 Wiznet Ethernet Shield. Actually, here is my sketch. Perhaps you can familiarize yourself with the network approaches we’ve made. FWIW, my guy uses a WEMOs and a different RTC, but I was able to mod his sketch to work in with my hardware.

#include <SPI.h>                    // Used by Blynk
#include <Ethernet.h>               // Used by Blynk
#include <BlynkSimpleEthernet.h>    // Used by Blynk
#include <Wire.h>                   // I2c
#include <WidgetRTC.h>
#include <DHT.h>                    // DHT data wire connected to I/O pin with a 10k pullup resistor to 5V
#include <RTClib.h>                 // RealTimeClock Library for DS1307 and DS3231
#define BLYNK_PRINT Serial

char auth[] = "AUTH";
char server[] = "blynk-cloud.com";
unsigned int port = 8442;
unsigned int myEthernetTimeout =   5000;  //  5.0s Ethernet Connection Timeout (ECT)
unsigned int blynkInterval     =  25000;  // 25.0s Check Server Frequency      (CSF)
unsigned long startConnecting = millis();

//  DHT Reference Values - CHANGE THESE TO MANAGE YOUR ROOM'S CLIMATE - //
byte hiMaxTemp = 80;   // temp that triggers heat removal device(s) on
byte lowMaxTemp = 70;  // temp that triggers heat removal device(s) off
byte hiMinTemp = 55;   // temp that triggers heater on
byte lowMinTemp = 65;  // temp that triggers heater off
byte hiHum = 58;       // High humidity value that triggers dehumidifier on
byte lowHum = 40;      // Low humidity value that triggers dehumidifier off

//-Digital Pins - Peristaltic Pump Variables - 00 Series Pins
const int pumpPin[8] = { 2, 3, 4, 5, 6, 7, 8, 9 };
int dosingLEDs[8]  = { V14, V15, V16, V17, V18, V19, V20, V21 };
uint32_t multiplier[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; //ms per ml
uint32_t startPump = 0;
uint32_t runCount;
bool pumpRunning;
const char *nuteType[8] = { "GH Armor Si", "GH Flora Blend", "GH CALiMAGic", "GH Kool Bloom",
                            "GH Flora Gro", "GH Flora Micro", "GH Flora Bloom", "GH pH Down"
                          }; //Text Printed to Terminal Widget^^

float DOSEml;      //Step Widget (0.25 per step, send step/NO, loop values ON)
int button = 0;   //Button Widget set to Switch
int x;           //Correlates Array Positions with Pump Motor Pins
int calibration;

BLYNK_WRITE(V4) {
  x = param.asInt() - 1;
}
BLYNK_WRITE(V5) {
  DOSEml = param.asFloat();
}
BLYNK_WRITE(V6) {
  button = param.asInt();
}
BLYNK_WRITE(V13) {
  calibration = param.asInt();
}
//
uint32_t msPerGallon = 33000; //ms per gallon
uint32_t ROstart = 0;
uint32_t countGallons;
boolean runningRO = false;
int pumpAon;          //Blynk Override to turn pumpA back on
int pumpBon;          //Blynk Override to turn pumpB back on

int ROpumpOn = 0;     //Blynk Triggered RO Pump
float totalGallons;   //Number of RO Gallons Selected in Widget
BLYNK_WRITE(V9) {
  pumpAon = param.asInt();  // pumpA remote
}
BLYNK_WRITE(V10) {
  pumpBon = param.asInt();  // pumpB remote
}
BLYNK_WRITE(V11) {
  ROpumpOn = param.asInt();  // ROpump remote
}
BLYNK_WRITE(V12) {
  totalGallons = param.asFloat();  // ROpump remote
}

// Digital Pin 10 is <RESERVED> for W5100 Wiznet chip
// Digital Pins - 8 Channel Relay Assignments - 20 Series Pins - 120VAC~ switching
#define lightA 22             //Relay 1/a  
#define lightB 23             //Relay 2/b  
#define pumpA 24              //Relay 3/c 
#define pumpB 25              //Relay 4/d  
#define ROpump 26             //Relay 5/e  
#define scrubberFan 27        //Relay 6/f  
#define VentA 28              //Relay 7/g  
#define VentB 29              //Relay 8/h 

//-Digital Pins - 8 Channel Relay Assignments - 30 Series Pins - 120VAC~ switching
// -Dpins 30-37 are reserved for another bank of Relays.

//Digital Pin Valves Assignments - 40 Series Pins - Hi/Lo Solenoid Valves
//const byte valve[13] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 };

#define TURN_ON LOW // TURN_ON and TURN_OFF are defined to account for Active LOW relays
#define TURN_OFF HIGH // Used to switch relay states for on/off of 120VAC~ devices  

RTC_DS1307 RTC;
float UTCOffset = -5.0;    // Your timezone relative to UTC (http://en.wikipedia.org/wiki/UTC_offset)

WidgetLCD lcdA(V7);  //Set LCD widget to Advanced Mode - Widget to display project clock
WidgetTerminal terminal(V8);
DHT dhtA(A0, DHT22);     // DHT instance named dhtA, (I/O pin, sensor type)
DHT dhtB(A2, DHT22);     // DHT instance named dhtB, (I/O pin, sensor type)
BlynkTimer timer;       // SimpleTimer instance named timer
WidgetRTC rtcWidget;  // requires RTC widget in app


// all initialization and timer setups go here


//**********************Functions***************************//
//**********************************************************//
// This is called for all virtual pins that do not have BLYNK_WRITE handler
BLYNK_WRITE_DEFAULT()
{
  Serial.println("BLYNK_WRITE_DEFAULT()");
  terminal.print("BLYNK_WRITE for pin ");
  terminal.print(request.pin);
  terminal.println(" not defined.");
  terminal.println("Values: ");
  for (auto i = param.begin(); i < param.end(); ++i) {
    terminal.print("* ");
    terminal.println(i.asString());
  }
  terminal.flush();
}

// This is called for all virtual pins that do not have BLYNK_READ handler
BLYNK_READ_DEFAULT()
{
  Serial.println("BLYNK_READ_DEFAULT");
  terminal.print("BLYNK_READ for pin ");
  terminal.print(request.pin);
  terminal.println(" not defined.");
  terminal.flush();
}

// This is called when Blynk has successfully connected
BLYNK_CONNECTED()
{
  Serial.println("BLYNK_CONNECTED");
  rtcWidget.begin();      // Synchronize with widget (server) time on connection
  setSyncInterval(5 * 60); // subsequent time sync interval in seconds (5 minutes)

  for (int i = V4; i <= V6; i++)
    for (int j = V9; j <= V21; j++)
    {
      Blynk.virtualWrite(i, j, 0);
    }
}

void myfunction() {
  Serial.println("\tLook, no Blynk  block.");
  if (Blynk.connected()) {
    Serial.println("\tEthernet still  connected.");
    Blynk.virtualWrite(V11, millis() / 1000);
  }
}

void checkBlynk() {
  while (!Blynk.connected()) {
    Blynk.connect();
    if (millis() > startConnecting + myEthernetTimeout) {
      Serial.print("\tUnable to connect to server. ");
      break;
    }
  }
  Serial.println("Checking again in 25s.");
}

void displayDateTime()
{
  Serial.println("displayDateTime");
  DateTime now = RTC.now();          // reads time at beginning of loop
  byte HOUR = now.hour();
  byte twelveHour = now.hour() - 12; // Variable used to display 13+ hours in 12 hour format
  byte zeroHour = 12;                // Variable use to convert "0" zero hour to display it as 12:00+
  byte displayHour;
  byte MIN = now.minute();
  byte SEC = now.second();
  char* meridian;

  if (now.hour() == 0)  // First we test if the hour reads "0"
  {
    displayHour = zeroHour;
    meridian = "AM";
  }
  else if (now.hour() >= 13)  // if no, Second we test if the hour reads "13 or more"
  {
    displayHour = twelveHour;
    meridian = "PM";
  }
  else
  {
    displayHour = now.hour();
    meridian = "AM";
  }
  if (Blynk.connected())
  {
    char stamp[16];
    lcdA.clear();
    sprintf(stamp, "%02d:%02d:%02d-%02s", displayHour, MIN, SEC, meridian);
    lcdA.print(3, 0, stamp);
    sprintf(stamp, "%02d/%02d/%04d", now.month(), now.day(), now.year());
    lcdA.print(3, 1, stamp);
  }
}
// synchronize the RTC hardware device with our server provided date/time values
void syncRTCHardware()
{
  if (!Blynk.connected())
  {
    Serial.println("Blynk not connected. Exiting syncRTCHardware.");
    return;
  }
  Serial.println("syncRTCHardware");
  DateTime now = RTC.now();          // reads time at beginning of loop

  char currentTime[16];
  char currentDate[16];
  sprintf(currentDate, "%02d/%02d/%04d", month(), day(), year());
  sprintf(currentTime, "%02d:%02d:%02d", hour(), minute(), second());
  Serial.print("Server Time: ");
  Serial.print(currentDate);
  Serial.print (" ");
  Serial.println(currentTime);

  // time library is synchronized by the Blynk WidgetRTC
  if (Blynk.connected())
  {
    bool syncClocks;
    if (now.hour() != hour() && now.minute() != minute()) syncClocks = true;
    if (syncClocks == true)
    {
      syncClocks = false;
      Serial.println("Resynching RTC Time...");
      terminal.println("Resynching RTC Time...");
      RTC.adjust(DateTime(year(), month(), day(), hour(), minute(), second()));
      terminal.flush();
    }
  }
}

// checks connection to Blynk server and attempts reconnect if disconnectedd checkBlynkConnection()
void checkBlynkConnection()
{
  Serial.println("Attempting to Connect");
  if (!Blynk.connected())
  {
    Serial.println("checkBlynkConnection");
    Blynk.connect();  // try to connect to server with default timeout
  }
}

void climateRoutine()
{
  byte h1 = dhtA.readHumidity();          // f1 and h1 are fahrenheit and humidity readings
  byte f1 = dhtA.readTemperature(true);   // from DHT/A
  byte h2 = dhtB.readHumidity();          // f2 and h2 are fahrenheit and humidity readings
  byte f2 = dhtB.readTemperature(true);   // from DHT/B
  if (isnan(f1) || isnan(f2) || isnan(h1) || isnan(h2)) {
    terminal.println("Failed to read from a DHT sensor");
    terminal.flush();
    return;
  }
  Blynk.virtualWrite(V0, f1);      //  Set Virtual Pin 0 frequency to PUSH in Blynk app
  Blynk.virtualWrite(V1, h1);      //  Set Virtual Pin 1 frequency to PUSH in Blynk app
  Blynk.virtualWrite(V2, f2);      //  Set Virtual Pin 2 frequency to PUSH in Blynk app
  Blynk.virtualWrite(V3, h2);      //  Set Virtual Pin 3 frequency to PUSH in Blynk app
  //-------------------Bloom A Temp Test---------------------------------------//
  if (f1 >= hiMaxTemp)  //if "f1" is greater than or equal to hiMaxTemp,
  {
    digitalWrite(VentA, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the heat from Bloom A"); //  Text printed to terminal monitor
  }
  else if (f1 <= lowMaxTemp)  //  or else if "f1" is less than or equal to lowMaxTemp
  {
    digitalWrite(VentA, TURN_OFF); //  TURN_OFF relay E.
  }
  //-----------------------Bloom A Humidity Test-------------------------//
  if (h1 >= hiHum)  //if "h2" is greater than or equal to hiHum,
  {
    digitalWrite(VentA, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the RH from Bloom A"); //  Text printed to terminal monitor
  }
  else if (h1 <= lowHum)  //  or else if "h1" is less than or equal to lowHum
  {
    digitalWrite(VentA, TURN_OFF);
  }
  //-----------------------Bloom B Temp Test-----------------------------//
  if (f2 >= hiMaxTemp)  //if "f2" is greater than or equal to hiMaxTemp,
  {
    digitalWrite(VentB, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the heat from Bloom B"); //  Text printed to terminal monitor
  }
  else if (f2 <= lowMaxTemp)  //  or else if "f2" is less than or equal to lowMaxTemp
  {
    digitalWrite(VentB, TURN_OFF);
  }
  //-----------------------Bloom B Humidity Test-------------------------//
  if (h2 >= hiHum)  //if "h2" is greater than or equal to hiHum,
  {
    digitalWrite(scrubberFan, TURN_ON);  // TURN_ON heatVentA (fan).
    terminal.println("Exhausting the RH from Bloom B"); //  Text printed to terminal monitor
  }
  else if (h2 <= lowHum)  //  or else if "h2" is less than or equal to lowHum
  {
    digitalWrite(scrubberFan, TURN_OFF);
  }
  terminal.flush();
}

void timeRoutine()
{
  DateTime now = RTC.now();          // reads time at beginning of loop

  //------------------12/12 BloomA Light - 5AM-5PM
  //Adjust hours and minutes in accordance with 24 hour time format.
  //Create tests where true is ON time and false is OFF time.
  boolean lightAstate = false;
  if (now.hour() >= 5 && now.hour() <= 16) lightAstate = true;
  if (lightAstate == true)
  {
    digitalWrite(lightA, TURN_ON);
    terminal.println("Lights On In Bloom A");  //  Text printed to terminal monitor
  }
  else
  {
    digitalWrite(lightA, TURN_OFF);
  }
  //--------------------12/12 Bloom B Light - 5PM-5AM
  //lightB is lit during the opposing 12 hours to lightA to conserve current draw from HID ballasts.
  boolean lightBstate = false;
  if (lightAstate == false) lightBstate = true;
  if (lightBstate == true)
  {
    digitalWrite(lightB, TURN_ON);
    terminal.println("Lights On In Bloom B");  //  Text printed to terminal monitor
  }
  else
  {
    digitalWrite(lightB, TURN_OFF);
  }
  //---------------Bloom A Feed Times------------------------
  boolean pumpAstate = false;
  if (pumpAon == 1) pumpAstate = true;
  if (now.hour() == 6 && now.minute() >= 0 && now.minute() < 10) pumpAstate = true;    //6:00 am - 10 mins
  if (now.hour() == 8 && now.minute() >= 30 && now.minute() < 40) pumpAstate = true;  //8:30 am - 10 mins
  if (now.hour() == 11 && now.minute() >= 00 && now.minute() < 10) pumpAstate = true;  //11:00 am - 10 mins
  if (now.hour() == 13 && now.minute() >= 30 && now.minute() < 40) pumpAstate = true;  //1:30 pm - 10 mins
  if (now.hour() == 16 && now.minute() >= 0 && now.minute() < 10) pumpAstate = true;  //4:00 pm - 10 mins
  if (pumpAstate == true)
  {
    Blynk.virtualWrite(V9, 1);
    digitalWrite(pumpA, TURN_ON);
    terminal.println("Pump A Is On");  //  Text printed to terminal monitor
  }
  else
  {
    pumpAon = 0;
    Blynk.virtualWrite(V9, 0);
    digitalWrite(pumpA, TURN_OFF);
  }
  //---------------------------Bloom B Feed Times-------------------------------------
  boolean pumpBstate = false;
  if (pumpBon == 1) pumpBstate = true;
  if (now.hour() == 18 && now.minute() >= 0 && now.minute() < 10) pumpBstate = true;     //6:00 pm - 10 mins -//- 1 hour after light on
  if (now.hour() == 20 && now.minute() >= 30 && now.minute() < 40) pumpBstate = true;   //8:30 pm - 10 mins
  if (now.hour() == 23 && now.minute() >= 0 && now.minute() < 10) pumpBstate = true;     //11:00 pm - 10 mins
  if (now.hour() == 1 && now.minute() >= 30 && now.minute() < 40) pumpBstate = true;    //1:30 am - 10 mins
  if (now.hour() == 4 && now.minute() >= 0 && now.minute() < 10) pumpBstate = true;     //4:00 am - 10 mins
  if (pumpBstate == true)
  {
    Blynk.virtualWrite(V10, 1);
    digitalWrite(pumpB, TURN_ON);
    terminal.println("Pump B Is On");  //  Text printed to terminal monitor
  }
  else
  {
    pumpBon = 0;
    Blynk.virtualWrite(V10, 0);
    digitalWrite(pumpB, TURN_OFF);
  }
  terminal.flush();
}

void ROcheck()  //RO Pump = 34 seconds on time per gallon
{
  if (ROpumpOn == 1 && runningRO == false)            // Activates when Blynk button is toggled
  {
    digitalWrite(ROpump, TURN_ON);
    Blynk.virtualWrite(V11, 255);                     // Illuminates Blynk button widget
    runningRO = true;
    ROstart = millis();
    countGallons = msPerGallon * totalGallons;        // Calculates length of runtime for pump
    Blynk.virtualWrite(V12, 0);
    terminal.print("Pumping:");
    terminal.print(totalGallons);
    terminal.println(" Gallons of RO");
  }
  if (millis() - ROstart > countGallons)              // Determines when runtime ends
  {
    ROpumpOn = 0;
    runningRO = false;
    digitalWrite(ROpump, TURN_OFF);
    Blynk.virtualWrite(V11, 0);
    //Blynk.virtualWrite(V22, 0);
  }
  terminal.flush();
}

void dosingPumps()
{
  if (button == 1 && pumpRunning == false)
  {
    multiplier[x] = calibration;                      // Gets the value in [x] position from Blynk
    Blynk.virtualWrite(V4, 0);
    Blynk.virtualWrite(V5, 0);
    Blynk.virtualWrite(V6, 0);                        // Keeps button ON until fully executed
    pumpRunning = true;
    digitalWrite(pumpPin[x], HIGH);
    Blynk.virtualWrite(dosingLEDs[x], 255);           // [x] position Blynk indicator LED
    startPump = millis();
    runCount = DOSEml * multiplier[x];
    terminal.print("Dosing in: ");
    terminal.print(DOSEml);
    terminal.print(" milliliters of ");
    terminal.println(nuteType[x]);
  }
  if (millis() - startPump > runCount)
  {
    digitalWrite(pumpPin[x], LOW);
    Blynk.virtualWrite(dosingLEDs[x], 0);
    pumpRunning = false;
    button = 0;
  }
  terminal.flush();
}

void setup()
{
  Serial.begin(9600);
  Serial.println("setup start...");

  Serial.println("dhtA.begin()...");
  dhtA.begin();

  Serial.println("dhtB.begin()...");
  dhtB.begin();

  Serial.println("setting DHT's...");
  pinMode(A0, INPUT_PULLUP);    // DHT22 use internal 20k pullup resistors
  pinMode(A2, INPUT_PULLUP);

  Serial.println("Wire.begin()...");
  Wire.begin();

  Serial.println("RTC.begin()...");
  RTC.begin();

  Serial.println("turning relays off...");
  for (int allRelays = lightA; allRelays <= VentB; allRelays++)
  {
    pinMode(allRelays, OUTPUT);
    digitalWrite(allRelays, TURN_OFF);
  }

  Serial.println("setting pump pinMode's...");

  for (int p = 0; p <= 7; p++)
  {
    pinMode(pumpPin[p], OUTPUT);
  }

  Serial.println("setting timers...");
  timer.setInterval(2000L, timeRoutine);      // 2 second intervals between timed routiness
  timer.setInterval(5001L, climateRoutine);   // 5 second intervals between climate routines
  timer.setInterval(15000L, syncRTCHardware);  // synchronize the RTC device with the server time every 15 seconds
  timer.setInterval(5000L, displayDateTime);   // update the LCD Widget every 5 seconds
  timer.setInterval(15000L, checkBlynkConnection); // check Blynk connection every 15 seconds
  timer.setInterval(207L, dosingPumps);       // 0.2 second interval to maintain accuracy (+/- .25)
  timer.setInterval(1003L, ROcheck);          // 1 second interval between RO pump routines
  timer.setInterval(myEthernetTimeout, myfunction);
  timer.setInterval(blynkInterval, checkBlynk);   // check connection to server per blynkInterval

  Serial.println("beginning Blynk...");
  // Blynk stuff after timers
  //Blynk.config(auth, server, port);
  Blynk.begin(auth, server, port);
  while (Blynk.connect() == false)
  {
    Blynk.connect();
    if (millis() > startConnecting + myEthernetTimeout) {
      Serial.print("\tUnable to connect to server. ");
      break;
    }
    //Blynk.disconnect(); // skip connecting to the Blynk server until checkBlynkConnection timer fires

    Serial.println("setup complete.");
  }
}
  void loop()
  {
    // only attempt Blynk-related functions when connected to Blynk
    if (Blynk.connected())
    {
      Blynk.run();
    }
    timer.run();
  }

I am not familiar with the W5100 but Sketch Builder shows this as the basic sketch required for Blynk. Does this sketch get you connected to Blynk or do you have to define MAC addresses etc like we do with the ENC28J60?

#define BLYNK_PRINT Serial
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>

char auth[] = "YourAuthToken";

#define W5100_CS  10
#define SDCARD_CS 4

void setup()
{
  Serial.begin(9600);
  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card

  Blynk.begin(auth);

}

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

No, just the Blynk ethernet library and other traditional libraries for Blynk. I started with Blynk’s Ethernet sketch and stripped it down to what was needed to function properly. I’ve never had to set MAC and IP with Blynk and Ethernet, though perhaps this is board specific. The above sketch works great, it’s just that it being a hydroponics controller, it NEEDS to be able to execute time related functions, and if it gets hung up in the setup after a brown out, this can have detrimental effects to plants in bloom.

With your full sketch plus my mods and with the Ethernet cable unplugged what does Serial Monitor show?

I just now added the SDCARD language and this is the serial with no internet. Mind you, I still need to add your second suggested edit if you still want that, but this sketch has your first and third suggestions included.

setup start...
dhtA.begin()...
dhtB.begin()...
setting DHT's...
Wire.begin()...
RTC.begin()...
turning relays off...
setting pump pinMode's...
setting timers...
beginning Blynk...

I don’t have a W5100 but this is Serial Monitor from the following sketch (effectively with Ethernet cable unplugged).

[0] 
    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.4.8 on Arduino Mega

[501] Connecting to blynk-cloud.com:8442
[1002] Connecting to blynk-cloud.com:8442
[1503] Connecting to blynk-cloud.com:8442
[2004] Connecting to blynk-cloud.com:8442
[2505] Connecting to blynk-cloud.com:8442
[3006] Connecting to blynk-cloud.com:8442
[3507] Connecting to blynk-cloud.com:8442
[4008] Connecting to blynk-cloud.com:8442
[4509] Connecting to blynk-cloud.com:8442
[5010] Connecting to blynk-cloud.com:8442
[5511] Connecting to blynk-cloud.com:8442
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
[25000] Connecting to blynk-cloud.com:8442
[25501] Connecting to blynk-cloud.com:8442
[26002] Connecting to blynk-cloud.com:8442
[26503] Connecting to blynk-cloud.com:8442
[27004] Connecting to blynk-cloud.com:8442
[27505] Connecting to blynk-cloud.com:8442
[28006] Connecting to blynk-cloud.com:8442
[28507] Connecting to blynk-cloud.com:8442
[29008] Connecting to blynk-cloud.com:8442
[29509] Connecting to blynk-cloud.com:8442
[30010] Connecting to blynk-cloud.com:8442
[30511] Connecting to blynk-cloud.com:8442
	Unable to connect to server. 
	Checking again in 25.00s.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
[50000] Connecting to blynk-cloud.com:8442
[50501] Connecting to blynk-cloud.com:8442
[51002] Connecting to blynk-cloud.com:8442
[51503] Connecting to blynk-cloud.com:8442
[52004] Connecting to blynk-cloud.com:8442
[52505] Connecting to blynk-cloud.com:8442
[53006] Connecting to blynk-cloud.com:8442
[53507] Connecting to blynk-cloud.com:8442
[54008] Connecting to blynk-cloud.com:8442
[54509] Connecting to blynk-cloud.com:8442
[55010] Connecting to blynk-cloud.com:8442
[55511] Connecting to blynk-cloud.com:8442
	Unable to connect to server. 
	Checking again in 25.00s.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
[75000] Connecting to blynk-cloud.com:8442
[75501] Connecting to blynk-cloud.com:8442
[76002] Connecting to blynk-cloud.com:8442
[76503] Connecting to blynk-cloud.com:8442
[77004] Connecting to blynk-cloud.com:8442
[77505] Connecting to blynk-cloud.com:8442
[78006] Connecting to blynk-cloud.com:8442
[78507] Connecting to blynk-cloud.com:8442
[79008] Connecting to blynk-cloud.com:8442
[79509] Connecting to blynk-cloud.com:8442
[80010] Connecting to blynk-cloud.com:8442
[80512] Connecting to blynk-cloud.com:8442
	Unable to connect to server. 
	Checking again in 25.00s.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
[100000] Connecting to blynk-cloud.com:8442
[100501] Connecting to blynk-cloud.com:8442
[101002] Connecting to blynk-cloud.com:8442
[101504] Connecting to blynk-cloud.com:8442
[102005] Connecting to blynk-cloud.com:8442
[102506] Connecting to blynk-cloud.com:8442
[103007] Connecting to blynk-cloud.com:8442
[103508] Connecting to blynk-cloud.com:8442
[104009] Connecting to blynk-cloud.com:8442
[104510] Connecting to blynk-cloud.com:8442
[105011] Connecting to blynk-cloud.com:8442
[105512] Connecting to blynk-cloud.com:8442
	Unable to connect to server. 
	Checking again in 25.00s.
	Look, no Blynk block.
	Look, no Blynk block.

Try this sketch:

#define BLYNK_PRINT Serial
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
BlynkTimer timer;
char auth[] = "YourAuthToken";
unsigned int myEthernetTimeout =   5000;  // Ethernet Connection Timeout (ECT)
unsigned int blynkInterval     =  25000;  // Check Server Frequency      (CSF)
char server[]=    "blynk-cloud.com"; // could use "blynk-cloud.com" or an IP address
#define W5100_CS  10
#define SDCARD_CS 4

void setup()
{
  Serial.begin(115200);
  Serial.println();
  pinMode(SDCARD_CS, OUTPUT);
  digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
  timer.setInterval(myEthernetTimeout, myfunction);
  timer.setInterval(blynkInterval, checkBlynk);   // check connection to server per blynkInterval     
  //Blynk.begin(auth);
  Blynk.config(auth, server);  // this is OK
  Blynk.connect();             // this is OK
  
}

void myfunction(){
  Serial.println("\tLook, no Blynk block.");
  if(Blynk.connected()){
    Serial.println("\tEthernet still connected.");
    Blynk.virtualWrite(V11, millis() / 1000);
  }
}

void checkBlynk() {
  unsigned long startConnecting = millis();    
  while(!Blynk.connected()){
    Blynk.connect();  
    if(millis() > startConnecting + myEthernetTimeout){
      Serial.println("\tUnable to connect to server. ");
      break;
    }
  }
  Serial.print("\tChecking again in ");
  Serial.print(blynkInterval / 1000.0);
  Serial.println("s.");
}

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

No you didn’t because you still have Blynk.begin() in your sketch.

This is how your setup() should end:

  Serial.println("beginning Blynk...");
  // Blynk stuff after timers
  Blynk.config(auth, server);
  Blynk.connect();
   Serial.println("setup complete.");
 }

I ran the first suggestion, but using Blynk.config instead of Blynk.begin hindered the connection. I’ve since reverted it, but left the rest of your first suggestion intact. This is the one you wanted me to skip, but I already ran it. At any rate, here is the serial of the sketch you just shared. I left the internet disconnected for a few loops, than reconnected it and it began trying to reach blynk-cloud.


[0] 
    ___  __          __
   / _ )/ /_ _____  / /__
  / _  / / // / _ \/  '_/
 /____/_/\_, /_//_/_/\_\
        /___/ v0.4.7 on Arduino Mega

[5001] Connecting to blynk-cloud.com:8442
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
[25000] Connecting to blynk-cloud.com:8442
[30001] Connecting to blynk-cloud.com:8442
	Unable to connect to server. 
	Checking again in 25.00s.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
	Look, no Blynk block.
[50000] Connecting to blynk-cloud.com:8442

I just noticed my library isn’t current, perhaps this is the reason?

You should be on 0.4.8 for BlynkTimer etc but it’s unlikely to fix your problem.

1 Like

Presumably it never connected to the Blynk server?

I have modified your full sketch and it looks to be running fine without Blynk but if your card can’t connect, on request to the server, then the mods will not be effective.

There are other possible fixes but I’m surprised the mods we have offered don’t work. Maybe spend $2 and get a decent Ethernet card :slight_smile:

1 Like

Actually some Ethernet connections seem to take a very long time. Ours doesn’t because we allocate the IP and server etc in the sketch. You might need to increase the 5s and 25s to 45s and 55s respectively.

1 Like

I think I’ll take your advice and get a new Ethernet adapter. It’s kind of a bummer too b/c the board I use for the project is a Freetronics Ethermega that has an onboard W5100, and at $120 for that board, saying farewell will be tough, but their lack of support for their driver makes that sting a little bit less. Thanks Costas for your time and efforts. I will link this thread to the guy that’s helping me out to see if he can spot something that you said/shared that will help him to help me, lol. Thanks again!