I want to try Blynk provisioning and migrate to it in order to build an app with blynk.io plans. I’m using WifiManager right now. Looking for advice here.
- What are the steps I must follow?
- I’ve looked at the export demo and see the include files in the examples. I tried the export demo sketch but that fails in compilation. The myplant sketch compiles well.
- I want to define my own SSID in the AP mode but the blynk provisioning sketch does not seem to have that option. Am I mistaken? I want to use a dynamic SSID which has the serial number and not a static SSID for all bords.a
- The BlynkProvisioning.run() seems to be doing everything like Blynk.run() and more. I’ve had some problems with Blynk.begin and so went with Blynk.config and let Blynk.run do the rest of the work. I guess I can use Blynk.config now too before invoking BlynkProvisioning.run. Right?
- Should I make my phone project into an app on the phone and only then will I be able to test the sketch that uses BlynkProvisioning?
Edit: just found a video by Anna. Will try that and come back. Please ignore this post for now.
Edit: Tried the provisioning as per the video. Put in the include files, declared NodeMCU board and the program compiled well. Made an app of my Blynk project too.
- On flashing the board, the board came up. The blue light was not blinking.
- The AP was active as I could see it on my PC wireless listing.
- Invoked the app, configured the 2.4Ghz router name and password. It then showed me the AP to select for the device. Selected it and it said fetching device information.
- Nothing happens after that.
- Unfortunately, there are no messages on the serial monitor for me know what is going on.
Am stuck here. Any pointers from anyone?
@Costas I know you use the blynk provisioning.
#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
#define USE_NODE_MCU_BOARD // Comment out the boards you are not using
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266_SSL.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 "BlynkProvisioning.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[] = "9bfce62ec5f248e1962a0f0d135426f4";
#define firmware_ver_date "ESP8266 Testing v2.0.6 dtd 22 Mar 2018"
#define device_type "Device: Wifi 4 switch SSRD"
#define msg_separator "\n################################################################\n"
#define clear_terminal "\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\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
//logo
#define logotxt " __ __ _ \n| \\/ |__ _ _ __| |___ \n| |\\/| / _` | '_ \\ / -_)\n|_| |_\\__,_| .__/_\\___|\n |_| \n"
//sw"n" is created to assign the right GPIO pin numbers to switches
#define sw1 14 //relay 1
#define sw2 12 //relay 2
#define sw3 4 //relay 3
#define sw4 13 //relay 4
/******************* 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 *******/
#define timeformat "%a %I:%M%p %d %b %G."
BlynkTimer timer;
int isFirstConnect = 1;
long FirstConnectTime;
String firstconnect_ts;
char time_stamp[80];
struct tm * ts;
time_t rawtime;
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("\nBlynk Server Unix time: ");
Serial.println(t);
rawtime = t;
if (isFirstConnect)
{
FirstConnectTime = t;
isFirstConnect = 0;
Serial.print("First Connect epoch: ");
Serial.print(t);
Serial.print(" :: Timestamp : ");
/* Needs <time.h> to be included. Can give out formatted time.*/
ts = localtime ( &rawtime );
strftime (time_stamp, 80, timeformat, 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, timeformat, ts);
//check all starts
if ((hour() == V1_SThour) && (minute() == V1_STmin) && !(last_check_time == time_stamp)) {
digitalWrite(sw1, 1);
Blynk.virtualWrite(V1, 1);
Serial.println(time_stamp);
Serial.println("Switch 1 turned ON by timer");
Blynk.virtualWrite(V9, time_stamp, "\n");
Blynk.virtualWrite(V9, "Switch 1 turned ON by timer\n");
}
if ((hour() == V2_SThour) && (minute() == V2_STmin) && !(last_check_time == time_stamp)) {
digitalWrite(sw2, 1);
Blynk.virtualWrite(V2, 1);
Serial.println(time_stamp);
Serial.println("Switch 2 turned ON by timer");
Blynk.virtualWrite(V9, time_stamp, "\n");
Blynk.virtualWrite(V9, "Switch 2 turned ON by timer\n");
}
if ((hour() == V3_SThour) && (minute() == V3_STmin) && !(last_check_time == time_stamp)) {
digitalWrite(sw3, 1);
Blynk.virtualWrite(V3, 1);
Serial.println(time_stamp);
Serial.println("Switch 3 turned ON by timer");
Blynk.virtualWrite(V9, time_stamp, "\n");
Blynk.virtualWrite(V9, "Switch 3 turned ON by timer\n");
}
if ((hour() == V4_SThour) && (minute() == V4_STmin) && !(last_check_time == time_stamp)) {
digitalWrite(sw4, 1);
Blynk.virtualWrite(V4, 1);
Serial.println(time_stamp);
Serial.println("Switch 4 turned ON timer");
Blynk.virtualWrite(V9, time_stamp, "\n");
Blynk.virtualWrite(V9, "Switch 4 turned ON by timer\n");
}
//check all stops
if ((hour() == V1_SPhour) && (minute() == V1_SPmin) && !(last_check_time == time_stamp)) {
digitalWrite(sw1, 0);
Blynk.virtualWrite(V1, 0);
Serial.println(time_stamp);
Serial.println("Switch 1 turned OFF by timer");
Blynk.virtualWrite(V9, time_stamp, "\n");
Blynk.virtualWrite(V9, "Switch 1 turned OFF by timer\n");
}
if ((hour() == V2_SPhour) && (minute() == V2_SPmin) && !(last_check_time == time_stamp)) {
digitalWrite(sw2, 0);
Blynk.virtualWrite(V2, 0);
Serial.println(time_stamp);
Serial.println("Switch 2 turned OFF by timer");
Blynk.virtualWrite(V9, time_stamp, "\n");
Blynk.virtualWrite(V9, "Switch 2 turned OFF by timer\n");
}
if ((hour() == V3_SPhour) && (minute() == V3_SPmin) && !(last_check_time == time_stamp)) {
digitalWrite(sw3, 0);
Blynk.virtualWrite(V3, 0);
Serial.println(time_stamp);
Serial.println("Switch 3 turned OFF by timer");
Blynk.virtualWrite(V9, time_stamp, "\n");
Blynk.virtualWrite(V9, "Switch 3 turned OFF by timer\n");
}
if ((hour() == V4_SPhour) && (minute() == V4_SPmin) && !(last_check_time == time_stamp)) {
digitalWrite(sw4, 0);
Blynk.virtualWrite(V4, 0);
Serial.println(time_stamp);
Serial.println("Switch 4 turned OFF by timer");
Blynk.virtualWrite(V9, time_stamp, "\n");
Blynk.virtualWrite(V9, "Switch 4 turned OFF by timer\n");
}
last_check_time = time_stamp;
}
/**************** end Timer/RTC declarations Section ********/
/********************** Begin LED Section *****************/
int BlynkLED = 5; //LED_BUILTIN;
int wifiLED = 2;
int BlynkLEDstate = LOW;
int wifiLEDstate = HIGH;
void wifiLEDoff()
{
digitalWrite(wifiLED, HIGH);
wifiLEDstate = HIGH;
}
void wifiLEDon()
{
digitalWrite(wifiLED, LOW);
wifiLEDstate = LOW;
}
void BlynkLEDoff()
{
digitalWrite(BlynkLED, LOW);
BlynkLEDstate = LOW;
}
void BlynkLEDon()
{
digitalWrite(BlynkLED, HIGH);
BlynkLEDstate = HIGH;
}
void BlynkLEDtoggle()
{
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate = !BlynkLEDstate;
}
void wifiLEDtoggle()
{
digitalWrite(wifiLED, !wifiLEDstate);
wifiLEDstate = !wifiLEDstate;
}
void BlynkLEDtwice()
{
BlynkLEDoff();
BlynkLEDstate=LOW;
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate = !BlynkLEDstate;
delay(50L);
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate = !BlynkLEDstate;
delay(100L);
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate = !BlynkLEDstate;
delay(50L);
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate = !BlynkLEDstate;
}
void BlynkLEDslow()
{
BlynkLEDoff();
BlynkLEDstate=LOW;
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate = !BlynkLEDstate;
delay(500L);
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate = !BlynkLEDstate;
delay(500L);
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate = !BlynkLEDstate;
delay(500L);
digitalWrite(BlynkLED, !BlynkLEDstate);
BlynkLEDstate = !BlynkLEDstate;
}
/********************** 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("\nApp button change. V0 is set to ");
Serial.println(pinValue);
if (pinValue)
{
digitalWrite(sw1, HIGH);
digitalWrite(sw2, HIGH);
digitalWrite(sw3, HIGH);
digitalWrite(sw4, HIGH);
}
else
{
digitalWrite(sw1, LOW);
digitalWrite(sw2, LOW);
digitalWrite(sw3, LOW);
digitalWrite(sw4, 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(sw1, pinValue);
Serial.print("\nApp button change. V1 is set to ");
Serial.println(pinValue);
}
BLYNK_WRITE(V2)
{
int pinValue = param.asInt(); // assigning incoming value from pin V2 to a variable
digitalWrite(sw2, pinValue);
Serial.print("\nApp button change. V2 is set to ");
Serial.println(pinValue);
}
BLYNK_WRITE(V3)
{
int pinValue = param.asInt(); // assigning incoming value from pin V3 to a variable
digitalWrite(sw3, pinValue);
Serial.print("\nApp button change. V3 is set to ");
Serial.println(pinValue);
}
BLYNK_WRITE(V4)
{
int pinValue = param.asInt(); // assigning incoming value from pin V4 to a variable
digitalWrite(sw4, pinValue);
Serial.print("\nApp button change. V4 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);
}
/********************************************************************************
* UPTIME CALCULATION AND UPDATION IN DISPLAY WIDGET CONNECTED TO V10
* Section also has LCD panel write to display important information
*******************************************************************************/
void update_uptime()
{
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;
String uptime=String(days)+"d:"+String(hours)+"h:"+String(minutes)+"m";
Blynk.virtualWrite(V10, uptime);
}
/*********************************************************************************
CONNECTION SECTION:
**********************************************************************************/
BLYNK_CONNECTED()
{
// Request the latest state from the server
Serial.print(msg_separator);
Serial.print("Connected to server");
Blynk.syncVirtual(V1, V2, V3, V4, V11, V12, V13, V14);
Serial.print("\nSyncAll done");
wifiLEDoff();
BlynkLEDon();
requestTime();
//Clear terminal
Blynk.virtualWrite(V9,clear_terminal,logotxt,"Ready\n");
Serial.println(msg_separator);
Blynk.setProperty(V4, "color", FUCHSIA);
update_uptime();
Serial.print("WiFI Strength: ");
Serial.print(WiFi.RSSI());
Serial.println("dB");
}
/**************************************************************************************
TERMINAL INTERACTION SECTION
Attached to Virtual Pin V9
Commands supported are help, info, time, upime, wifi, ver, ip, name, reboot, erase
Commands to change labels of widgets like buttons and timers are also supported.
Command format is sn "string" for switches and tn "string" for timer.
**************************************************************************************/
BLYNK_WRITE(V9)
{
int j = 0;
char command_txt[30];
char original_txt[40];
//convert keyed in text to lower case
strcpy(termtxt, param.asStr());
for (int i = 0; termtxt[i]; i++) {
termtxt[i] = tolower(termtxt[i]);
}
//Extract command and arguments and trimming the strings
strcpy(original_txt, termtxt);
String orig = String(original_txt);
orig.trim();
//Serial.print("Trimmed original: ");
//Serial.println(orig);
int spacepos = orig.indexOf(" ");
String arg = orig.substring(spacepos);
arg.trim();
//Serial.print("Argument: ");
//Serial.println(arg);
sscanf(termtxt, "%s", command_txt);
strcpy(termtxt, command_txt);
if (String("help") == termtxt) {
Blynk.virtualWrite(V9,"\nCommands are not case sensitive\n");
Blynk.virtualWrite(V9,"Supported commands: help, info, clear, time, uptime, wifi, ip, name, ver\n");
Blynk.virtualWrite(V9,"Can change switch/timer names eg. s1 name1\n");
j = 1;
strcpy(prevcmd, termtxt);
}
if (String("info") == termtxt) {
Blynk.virtualWrite(V9,device_type, "\n");
j = 1;
strcpy(prevcmd, termtxt);
}
if (String("time") == termtxt) {
terminal.print("\nTime: ");
rawtime = now();
ts = localtime ( &rawtime );
strftime (time_stamp, 80, timeformat, ts);
Blynk.virtualWrite(V9,time_stamp, "\n");
Serial.println(time_stamp);
j = 1;
strcpy(prevcmd, termtxt);
}
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;
Blynk.virtualWrite(V9,"\nUp since ",firstconnect_ts, "\n");
Blynk.virtualWrite(V9,"Uptime: ", days, "d:", hours,"h:", minutes,"m\n" );
j = 1;
strcpy(prevcmd, termtxt);
update_uptime();
}
if (String("wifi") == termtxt) {
Blynk.virtualWrite(V9,"\nSSID: ", WiFi.SSID(),"\nSignal: ", WiFi.RSSI(),"dB", "\n");
j = 1;
strcpy(prevcmd, termtxt);
}
if (String("ip") == termtxt) {
Blynk.virtualWrite(V9,"\nName: ", WiFi.hostname(), "\nDevice ip: ", WiFi.localIP().toString(), "\n");
j = 1;
strcpy(prevcmd, termtxt);
}
if (String("name") == termtxt) {
Blynk.virtualWrite(V9,"\nName: ",WiFi.hostname(), "\n");
j = 1;
strcpy(prevcmd, termtxt);
}
if (String("clear") == termtxt) {
Blynk.virtualWrite(V9,clear_terminal); // "clear screen" in app.
Blynk.virtualWrite(V9,logotxt);
j = 1;
strcpy(prevcmd, termtxt);
}
//Till the reboot commands, the next set of if statements will be used to
//set widget labels to suit the customer
if (String("s1") == termtxt) {
if (arg != "") {
Blynk.setProperty(V1, "label", arg);
Blynk.setProperty(V11, "label", (arg + " timer"));
Blynk.virtualWrite(V9,"Changed name for s1\n");
}
else {
Blynk.virtualWrite(V9,"No name given\n");
}
j=1;
strcpy(prevcmd, termtxt);
}
if (String("s2") == termtxt) {
if (arg != "") {
Blynk.setProperty(V2, "label", arg);
Blynk.setProperty(V12, "label", (arg + " timer"));
Blynk.virtualWrite(V9,"Changed name for s2\n");
}
else {
Blynk.virtualWrite(V9,"No name given\n");
}
j=1;
strcpy(prevcmd, termtxt);
}
if (String("s3") == termtxt) {
if (arg != "") {
Blynk.setProperty(V3, "label", arg);
Blynk.setProperty(V13, "label", (arg + " timer"));
Blynk.virtualWrite(V9,"Changed name for s3\n");
}
else {
Blynk.virtualWrite(V9,"No name given\n");
}
j=1;
strcpy(prevcmd, termtxt);
}
if (String("s4") == termtxt) {
if (arg != "") {
Blynk.setProperty(V4, "label", arg);
Blynk.setProperty(V14, "label", (arg + " timer"));
Blynk.virtualWrite(V9,"Changed name for s4\n");
}
else {
Blynk.virtualWrite(V9,"No name given\n");
}
j=1;
strcpy(prevcmd, termtxt);
}
// end of label definition section
if (String("reboot") == termtxt) {
Blynk.virtualWrite(V9,"\npassword:");
j = 1;
strcpy(prevcmd, termtxt);
}
if (String("erase") == termtxt) {
Blynk.virtualWrite(V9,"\npassword:");
j = 1;
strcpy(prevcmd, termtxt);
}
if ((String("mohan") == termtxt) && (String("reboot") == prevcmd)) {
pinMode(0, OUTPUT);
pinMode(2, OUTPUT);
digitalWrite(0,1);
digitalWrite(2,1);
ESP.restart();
}
if (String("ver") == termtxt) {
Blynk.virtualWrite(V9,"\nVer: ",firmware_ver_date,"\nSDK Ver: ",ESP.getSdkVersion(),"\n");
j = 1;
strcpy(prevcmd, termtxt);
} else {
if (!j) {
Blynk.virtualWrite(V9,"\nInvalid command\n");
}
}
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(sw1, OUTPUT);
pinMode(sw2, OUTPUT);
pinMode(sw3, OUTPUT);
pinMode(sw4, OUTPUT);
pinMode(BlynkLED, OUTPUT);
pinMode(wifiLED, OUTPUT);
Serial.println(msg_separator);
Serial.print("Booting firmware ");
Serial.println(firmware_ver_date);
Serial.println(device_type);
Serial.print("Modified by Mohan Sundaram\nCopyright Maveric Automations Pvt Ltd.");
Serial.print(msg_separator);
Serial.print("Setup done");
wifiLEDon();
BlynkProvisioning.begin();
//tries to connect to last known settings
//if it does not connect it starts an access point with the specified name
//here "MPL4W-xxxxxx" with no password
//and goes into a blocking loop awaiting configuration
Serial.println(msg_separator);
Serial.println("Wifi Connection phase");
Serial.println("~~~~~~~~~~~~~~~~~~~~~");
wifiLEDoff();
//check schedule every 30 seconds
timer.setInterval(30000L, schedule_check);
//Sync time every hour
timer.setInterval(3600000L, requestTime);
//Update uptime in value display widget every ten minutes
timer.setInterval(600000L, update_uptime);
Serial.println("Timers set for Blynk connection (1sec), time schedule checks(30sec), time sync(1hr) and uptime updation(10m)");
}
void loop()
{
BlynkProvisioning.run();
timer.run();
}