@Costas. Code appended. I’m not been a programmer and my code is possibly very tardy. Excuse that please. Any suggestions to make it better is welcome. This code was built by looking at examples, cutting and pasting what I thought was relevant for what I wanted to achieve. The code works except for the hostname part. However, I doubt the code is bad or wrong w.r.t the hostname setting. I could be very wrong though.
/*************************************************************
Blynk is a platform with iOS and Android apps to control
Arduino, Raspberry Pi and the likes over the Internet.
You can easily build graphic interfaces for all your
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: http://www.blynk.cc
Sketch generator: http://examples.blynk.cc
Blynk community: http://community.blynk.cc
Follow us: http://www.fb.com/blynkapp
http://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
This sketch shows how to access WiFiClient directly in Blynk
1. This gives you full control of the connection process.
2. Shows a sensible way of integrating other connectivity hardware,
that was not supported by Blynk out-of-the-box.
NOTE: This requires ESP8266 support package:
https://github.com/esp8266/Arduino
Please be sure to select the right ESP8266 module
in the Tools -> Board menu!
*************************************************************/
/*************************************************************
Whats new in this version?
*************************************************************
v1.3.4
1. This sketch is an minor improvement over 1.3.3 trying to use timers
for the first time for this board.
2. Will use BlynkSimpleTimer.
3. Will use it to connect to Blynk Services.
4. If Wifi disconnects, the board anyway reboots going back to
saved configuration to reconnect.
5. If it is unable to connect to any wifi network, it enters config
mode as an AP to capture wifi to connect to and token for the board.
6. Changed all diag LED calls to be common calls instead of
direct pin high/low calls in different places. Easy to
understand code.
v1.3.5
1. Removed fields to trap Blynk Server and Port info from user.1.3.5
2. Initiate Unix time sync and set RTC to Unix time of Blynk server. 1.3.5
v2.0.0 started on 09 Feb 2018
1. Introduce Terminal widget to show info on the app from the device
to be used for diagnostics and support.
2. Will show firmware version, chip info, RTC time, up since time,
wifi settings.
v2.0.1 started on 15 Feb 2018
1. Timer for all the lights.
*************************************************************/
#include <FS.h> //this needs to be first, or it all crashes and burns...
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
//needed for library
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <EEPROM.h>
#include <TimeLib.h>
#include <time.h>
//#include <WidgetRTC.h>
//define colours needed
#define BLYNK_GREEN "#23C48E"
#define BLYNK_BLUE "#04C0F8"
#define BLYNK_YELLOW "#ED9D00"
#define BLYNK_RED "#D3435C"
#define BLYNK_DARK_BLUE "#5F7CD8"
#define PURPLE "#800080"
#define BLUE_VIOLET "#8A2BE2"
#define BROWN "#A52A2A"
#define DARK_CYAN "#008B8B"
#define DARK_MAGENTA "#8B008B"
#define DARK_ORCHID "#9932CC"
#define FUCHSIA "#FF00FF"
#define MAROON "#800000"
#define TEAL "#008080"
/******************* Begin general declarations Section *******/
char auth[] = "1234567890123456789023456789012";
char firmware_ver_date[] = "NodeMCU1.0 ESP8266 Testing v2.0.1 dtd 15 Feb 2018 ";
char device_type[] = "Device: Wifi 4 switch SSRD";
/******************* end general declarations Section *******/
/***************** Begin Terminal declarations Section **********/
// Attach virtual serial terminal to Virtual Pin V9. Common for
// 4 and 8 switch versions
WidgetTerminal terminal(V9);
char termtxt[12]=" ";
char prevcmd[12]=" ";
/****************** end Terminal declarations Section ***********/
/*************** Begin Timer/RTC declarations Section *******/
BlynkTimer timer;
//WidgetRTC rtc;
char Date[16];
char Time[16];
long startsecondswd; // start time in seconds
long stopsecondswd; // stop time in seconds
long nowseconds; // time now in seconds
int IsFirstConnect=1;
long FirstConnectTime;
String firstconnect_ts;
char time_stamp[80];
struct tm * ts;
time_t rawtime;
char dayname[4];
char monthname[4];
long uptime_secs=millis()/1000;
String last_check_time;
String current_check_time;
/* Vn_Sxhour/min. n is relay number. x is T for start and P for stop */
int V1_SThour, V1_STmin, V1_SPhour, V1_SPmin;
int V2_SThour, V2_STmin, V2_SPhour, V2_SPmin;
int V3_SThour, V3_STmin, V3_SPhour, V3_SPmin;
int V4_SThour, V4_STmin, V4_SPhour, V4_SPmin;
void requestTime() {
Blynk.sendInternal("rtc", "sync");
}
BLYNK_WRITE(InternalPinRTC) {
long t = param.asLong();
setTime(t);
Serial.print("\nUnix time: ");
Serial.print(t);
Serial.println();
rawtime=t;
char daystr[3]="";
char timestr[6]="";
char yearstr[5] = "";
if (IsFirstConnect)
{
FirstConnectTime=t;
IsFirstConnect=0;
Serial.print("First Connect: ");
Serial.print(t);
Serial.print(" :: ");
/* Needs <time.h> to be included. Can give out formatted time.*/
ts = localtime ( &rawtime );
strftime (time_stamp,80,"%a %I:%M %p %d %b %G %Z.",ts);
Serial.println(time_stamp);
firstconnect_ts=time_stamp;
}
}
/*Routine to check schedules and act accordingly */
// call with timer every 30 seconds
void schedule_check() {
rawtime=now();
ts = localtime ( &rawtime );
strftime (time_stamp,80,"%a %I:%M %p %d %b %G %Z.",ts);
//check all starts
if ((hour() == V1_SThour) && (minute() == V1_STmin) && !(last_check_time == time_stamp)) {
digitalWrite(14,1);
Blynk.virtualWrite(V1,1);
Serial.println(time_stamp);
Serial.println("Switch 1 started by timer");
terminal.println(time_stamp);
terminal.println("Switch 1 started by timer");
terminal.flush();
}
if ((hour() == V2_SThour) && (minute() == V2_STmin) && !(last_check_time == time_stamp)) {
digitalWrite(12,1);
Blynk.virtualWrite(V2,1);
Serial.println(time_stamp);
Serial.println("Switch 2 started by timer");
terminal.println(time_stamp);
terminal.println("Switch 2 started by timer");
terminal.flush();
}
if ((hour() == V3_SThour) && (minute() == V3_STmin) && !(last_check_time == time_stamp)) {
digitalWrite(4,1);
Blynk.virtualWrite(V3,1);
Serial.println(time_stamp);
Serial.println("Switch 3 started by timer");
terminal.println(time_stamp);
terminal.println("Switch 3 started by timer");
terminal.flush();
}
if ((hour() == V4_SThour) && (minute() == V4_STmin) && !(last_check_time == time_stamp)) {
digitalWrite(13,1);
Blynk.virtualWrite(V4,1);
Serial.println(time_stamp);
Serial.println("Switch 4 started by timer");
terminal.println(time_stamp);
terminal.println("Switch 4 started by timer");
terminal.flush();
}
//check all stops
if ((hour() == V1_SPhour) && (minute() == V1_SPmin) && !(last_check_time == time_stamp)) {
digitalWrite(14,0);
Blynk.virtualWrite(V1,0);
Serial.println(time_stamp);
Serial.println("Switch 1 stopped by timer");
terminal.println(time_stamp);
terminal.println("Switch 1 stopped by timer");
terminal.flush();
}
if ((hour() == V2_SPhour) && (minute() == V2_SPmin) && !(last_check_time == time_stamp)) {
digitalWrite(12,0);
Blynk.virtualWrite(V2,0);
Serial.println(time_stamp);
Serial.println("Switch 2 stopped by timer");
terminal.println(time_stamp);
terminal.println("Switch 2 stopped by timer");
terminal.flush();
}
if ((hour() == V3_SPhour) && (minute() == V3_SPmin) && !(last_check_time == time_stamp)) {
digitalWrite(4,0);
Blynk.virtualWrite(V3,0);
Serial.println(time_stamp);
Serial.println("Switch 3 stopped by timer");
terminal.println(time_stamp);
terminal.println("Switch 3 stopped by timer");
terminal.flush();
}
if ((hour() == V4_SPhour) && (minute() == V4_SPmin) && !(last_check_time == time_stamp)) {
digitalWrite(13,0);
Blynk.virtualWrite(V4,0);
Serial.println(time_stamp);
Serial.println("Switch 4 stopped by timer");
terminal.println(time_stamp);
terminal.println("Switch 4 stopped by timer");
terminal.flush();
}
last_check_time=time_stamp;
}
/**************** end Timer/RTC declarations Section ********/
/***************** Begin WiFi declarations Section **********/
WiFiManager wifiManager;
WiFiClient wifiClient;
/****************** end WiFi declarations Section ***********/
/********************** Begin EEPROM Section *****************/
#define EEPROM_SALT 12664
typedef struct {
int salt = EEPROM_SALT;
char blynkToken[33] = "1234567890123456789023456789012";
char blynkServer[33] = "blynk-cloud.com";
char blynkPort[6] = "8442";
} WMSettings;
WMSettings settings;
void eeprom_read()
{
Serial.print("Values before reading EEPROM\n");
Serial.print(settings.salt);
Serial.print("::");
Serial.print(settings.blynkToken);
Serial.print("::");
Serial.print(settings.blynkServer);
Serial.print("::");
Serial.print(settings.blynkPort);
Serial.print("\n");
//custom params
EEPROM.begin(512);
EEPROM.get(0, settings);
EEPROM.end();
Serial.print("Values after reading EEPROM\n");
Serial.print(settings.salt);
Serial.print("::");
Serial.print(settings.blynkToken);
Serial.print("::");
Serial.print(settings.blynkServer);
Serial.print("::");
Serial.print(settings.blynkPort);
Serial.print("\n");
Serial.println(settings.blynkToken);
Serial.println(settings.blynkServer);
Serial.println(settings.blynkPort);
}
void eeprom_saveconfig()
{
//save the custom parameters to FS
Serial.println("Saving config to EEPROM");
Serial.println(settings.blynkToken);
Serial.println(settings.blynkServer);
Serial.println(settings.blynkPort);
EEPROM.begin(512);
EEPROM.put(0, settings);
EEPROM.commit();
EEPROM.end();
}
/********************** end EEPROM Section *****************/
/********************** Begin LED Section *****************/
int BlynkLED=LED_BUILTIN;
int wifiLED=2;
int BlynkLEDstate=HIGH;
int wifiLEDstate=HIGH;
void wifiLEDoff()
{
digitalWrite(wifiLED, HIGH);
}
void wifiLEDon()
{
digitalWrite(wifiLED, LOW);
}
void BlynkLEDoff()
{
digitalWrite(BlynkLED, HIGH);
}
void BlynkLEDon()
{
digitalWrite(BlynkLED, LOW);
}
void BlynkLEDtoggle()
{
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate=!BlynkLEDstate;
}
void wifiLEDtoggle()
{
digitalWrite(wifiLED, !wifiLEDstate);
wifiLEDstate=!wifiLEDstate;
}
/********************** end LED Section *****************/
/***************************************************************************************
BUTTONS HANDLING SECTION:
Map virtual pins to actual GPIOs. Helps abstract across boards to a common interface
V0 is for all relays to turn on/off
Vn is for nth relay to turn on/off
***************************************************************************************/
BLYNK_WRITE(V0)
{
int pinValue = param.asInt(); // assigning incoming value from pin V0 to a variable
Serial.print("\nV0 is set to ");
Serial.println(pinValue);
if (pinValue)
{
digitalWrite(14, HIGH);
digitalWrite(4, HIGH);
digitalWrite(12, HIGH);
digitalWrite(13, HIGH);
}
else
{
digitalWrite(14, LOW);
digitalWrite(4, LOW);
digitalWrite(12, LOW);
digitalWrite(13, LOW);
}
Blynk.virtualWrite(V1, pinValue);
Blynk.virtualWrite(V2, pinValue);
Blynk.virtualWrite(V3, pinValue);
Blynk.virtualWrite(V4, pinValue);
}
BLYNK_WRITE(V1)
{
int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
digitalWrite(14, pinValue); // GPIO2
Serial.print("\nV1 is set to ");
Serial.println(pinValue);
}
BLYNK_WRITE(V2)
{
int pinValue = param.asInt(); // assigning incoming value from pin V2 to a variable
digitalWrite(12, pinValue); // GPIO2
Serial.print("\nV2 is set to ");
Serial.println(pinValue);
}
BLYNK_WRITE(V3)
{
int pinValue = param.asInt(); // assigning incoming value from pin V3 to a variable
digitalWrite(4, pinValue);
Serial.print("\nV3 is set to ");
Serial.println(pinValue);
}
BLYNK_WRITE(V4)
{
int pinValue = param.asInt(); // assigning incoming value from pin V4 to a variable
digitalWrite(13, pinValue);
Serial.print("\nV4 is set to ");
Serial.println(pinValue);
}
/***************************************************************************************
TIMER BUTTONS HANDLING SECTION:
V1n is for nth relay to turn on/off by timer imput
***************************************************************************************/
BLYNK_WRITE(V11)
{
TimeInputParam t(param);
V1_SThour = t.getStartHour();
V1_STmin = t.getStartMinute();
V1_SPhour = t.getStopHour();
V1_SPmin = t.getStopMinute();
Serial.print(hour());
Serial.print(":");
Serial.print(minute());
Serial.print(" :: ");
Serial.print("\nRelay 1 turn on @");
Serial.print(V1_SThour);
Serial.print(":");
Serial.print(V1_STmin);
Serial.print(" and off @");
Serial.print(V1_SPhour);
Serial.print(":");
Serial.println(V1_SPmin);
}
BLYNK_WRITE(V12)
{
TimeInputParam t(param);
V2_SThour = t.getStartHour();
V2_STmin = t.getStartMinute();
V2_SPhour = t.getStopHour();
V2_SPmin = t.getStopMinute();
Serial.print(hour());
Serial.print(":");
Serial.print(minute());
Serial.print(" :: ");
Serial.print("\nRelay 2 turn on @");
Serial.print(V2_SThour);
Serial.print(":");
Serial.print(V2_STmin);
Serial.print(" and off @");
Serial.print(V2_SPhour);
Serial.print(":");
Serial.println(V2_SPmin);
}
BLYNK_WRITE(V13)
{
TimeInputParam t(param);
V3_SThour = t.getStartHour();
V3_STmin = t.getStartMinute();
V3_SPhour = t.getStopHour();
V3_SPmin = t.getStopMinute();
Serial.print(hour());
Serial.print(":");
Serial.print(minute());
Serial.print(" :: ");
Serial.print("\nRelay 3 turn on @");
Serial.print(V3_SThour);
Serial.print(":");
Serial.print(V3_STmin);
Serial.print(" and off @");
Serial.print(V3_SPhour);
Serial.print(":");
Serial.println(V3_SPmin);
}
BLYNK_WRITE(V14)
{
TimeInputParam t(param);
V4_SThour = t.getStartHour();
V4_STmin = t.getStartMinute();
V4_SPhour = t.getStopHour();
V4_SPmin = t.getStopMinute();
Serial.print(hour());
Serial.print(":");
Serial.print(minute());
Serial.print(" :: ");
Serial.print("\nRelay 4 turn on @");
Serial.print(V4_SThour);
Serial.print(":");
Serial.print(V4_STmin);
Serial.print(" and off @");
Serial.print(V4_SPhour);
Serial.print(":");
Serial.println(V4_SPmin);
}
/*********************************************************************************
CONNECTION SECTION:
Has both Wifi and Blynk server connection segments
**********************************************************************************/
//WiFi connection segment
void configModeCallback (WiFiManager *myWiFiManager) {
Serial.println("Entered config mode");
Serial.println(WiFi.softAPIP());
String ssid = "Mo4W-" + String(ESP.getChipId());
Serial.print("\nSet up device as passwordless AP called ");
Serial.println(ssid);
Serial.print("Blue LED next to ESP8266 will be lit in this phase");
Serial.print("\nTurns off once configured WiFi connection is successfully established\n");
//Serial.println(myWiFiManager->getConfigPortalSSID());
}
// This function tries to connect to the Blynk cloud using TCP if not connected
void connectBlynk()
{
wifiClient.stop();
//All LEDs off in this routine
wifiLEDoff();
BlynkLEDoff();
if(!Blynk.connected() )
{
Serial.print("\nReconnecting to Blynk server");
BlynkLEDoff();
wifiClient.connect(settings.blynkServer, atoi(settings.blynkPort));
}
else
{
wifiLEDoff();
BlynkLEDon();
}
}
BLYNK_CONNECTED() {
// Request the latest state from the server
Serial.print("\nConnected to server");
Blynk.syncVirtual(V1, V2, V3, V4, V11, V12, V13, V14);
Serial.print("\nSyncAll done");
wifiLEDoff();
BlynkLEDon();
requestTime();
//Clear terminal
terminal.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nReady");
terminal.flush();
Blynk.setProperty(V4, "color", FUCHSIA);
}
/**************************************************************************************
TERMINAL INTERACTION SECTION
Attached to Virtual Pin V9
Commands supported are help, info, time, upime, wifi, ver, ip, name, reboot, erase
**************************************************************************************/
BLYNK_WRITE(V9)
{
int j=0;
//convert keyed in text to lower case
strcpy(termtxt,param.asStr());
for(int i = 0; termtxt[i]; i++){
termtxt[i] = tolower(termtxt[i]);
}
Serial.println(termtxt);
if (String("help") == termtxt) {
terminal.println("\nCommands are not case sensitive");
terminal.println("Supported commands: help, info, time, uptime, wifi, ip, name, ver");
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if (String("info") == termtxt) {
terminal.print(device_type);
terminal.println();
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if (String("time") == termtxt) {
terminal.print("\nTime: ");
rawtime=now();
ts = localtime ( &rawtime );
strftime (time_stamp,80,"%a %I:%M %p %d %b %G %Z.",ts);
terminal.println(time_stamp);
Serial.println(time_stamp);
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if (String("uptime") == termtxt) {
int x, days, hours, minutes, months = 0;
x=(millis()/1000);
Serial.println(x);
days = x / 60 / 60 / 24;
hours = (x / 60 / 60) % 24;
minutes = (x / 60) % 60;
terminal.print("\nUp since ");
terminal.println(firstconnect_ts);
terminal.flush();
terminal.print("Uptime: " );
terminal.print(days);
terminal.print("d:");
terminal.print(hours);
terminal.print("h:");
terminal.print(minutes);
terminal.println("m");
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if (String("wifi") == termtxt) {
terminal.print("\nSSID: ");
terminal.println(WiFi.SSID());
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if (String("ip") == termtxt) {
terminal.print("\nName: ");
terminal.println(WiFi.hostname());
terminal.print("Device ip: ");
terminal.println(WiFi.localIP());
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if (String("name") == termtxt) {
terminal.print("\nName: ");
terminal.println(WiFi.hostname());
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if (String("clear") == termtxt) {
for (int i = 0; i <= 50; i++)
{
terminal.println(""); // "clear screen" in app.
}
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if (String("reboot") == termtxt) {
terminal.println("\npassword:");
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if (String("erase") == termtxt) {
terminal.println("\npassword:");
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
}
if ((String("mohan") == termtxt) && (String("reboot") == prevcmd)) {
ESP.reset();
}
if ((String("maple") == termtxt) && (String("erase") == prevcmd)) {
wifiManager.resetSettings();
ESP.reset();
}
if (String("ver") == termtxt) {
terminal.print("\nVer: ");
terminal.println(firmware_ver_date);
j=1;
strcpy(prevcmd,termtxt);
terminal.flush();
} else {
if (!j) {terminal.println("\nInvalid command");
terminal.flush();
}
}
Serial.print("prevcmd: ");
Serial.println(prevcmd);
//exit point of BLYNK_WRITE(V9) Terminal section
}
/**************************** SETUP and LOOP Sections *******************************/
void setup()
{
// Debug console
Serial.begin(115200);
Serial.println();
//set all pinmodes to output for relay control
pinMode(14, OUTPUT);
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(4, OUTPUT);
pinMode(2, OUTPUT);
pinMode(16, OUTPUT);
Serial.print("\nBooting firmware ");
Serial.println(firmware_ver_date);
Serial.print(device_type);
Serial.print("\nModified by Mohan Sundaram\n");
Serial.print("\nSetup done\n");
wifiLEDon();
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
//WiFiManager wifiManager;
//Pass on to callback to denote entering webconfig portal mode
wifiManager.setAPCallback(configModeCallback);
//exit after config instead of connecting
wifiManager.setBreakAfterConfig(true);
//for testing only
//wifiManager.resetSettings();
eeprom_read();
if (settings.salt != EEPROM_SALT) {
Serial.println("Invalid settings in EEPROM, trying with defaults");
WMSettings defaults;
settings = defaults;
}
Serial.println("Settings after EEPROM SALT check");
Serial.println(settings.blynkToken);
Serial.println(settings.blynkServer);
Serial.println(settings.blynkPort);
//Set hostname for easy identification.
String ssid = "Mo4W-" + String(ESP.getChipId());
WiFi.hostname(ssid);
WiFiManagerParameter custom_blynk_text("<br/><B/>Blynk configuration.");
wifiManager.addParameter(&custom_blynk_text);
WiFiManagerParameter custom_blynk_token("blynk-token", "blynk token", settings.blynkToken, 33);
wifiManager.addParameter(&custom_blynk_token);
//WiFiManagerParameter custom_blynk_server("blynk-server", "blynk server", settings.blynkServer, 33);
//wifiManager.addParameter(&custom_blynk_server);
//WiFiManagerParameter custom_blynk_port("blynk-port", "blynk port", settings.blynkPort, 6);
//wifiManager.addParameter(&custom_blynk_port);
//tries to connect to last known settings
//if it does not connect it starts an access point with the specified name
//here "Mo4W-xxxxxx" with no password
//and goes into a blocking loop awaiting configuration
if (!wifiManager.autoConnect(ssid.c_str(), NULL)) {
Serial.println("failed to connect, we should reset and see if it connects");
delay(3000);
ESP.reset();
delay(5000);
}
strcpy(settings.blynkToken, custom_blynk_token.getValue());
//strcpy(settings.blynkServer, custom_blynk_server.getValue());
//strcpy(settings.blynkPort, custom_blynk_port.getValue());
eeprom_saveconfig();
wifiLEDoff();
//if you get here you have connected to the WiFi
Serial.print("connected to wifi Access Point configured....");
Serial.print(WiFi.SSID());
Serial.print("\nlocal ip: ");
Serial.print(WiFi.localIP());
Serial.print("\n");
Blynk.config(settings.blynkToken);
//check Blynk connect every 1 secnd
timer.setInterval(1000L, connectBlynk);
//check schedule every 30 seconds
timer.setInterval(30000L, schedule_check);
//Sync time every hour
timer.setInterval(3600000L, requestTime);
}
void loop()
{
Blynk.run();
timer.run();
}
I plan to make the GPIO pin declarations right on top and use the defines in the code body where ever needs to use those pins.