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();
}