//* A simplified version of work begun by Tzapu and chriscook8
//*for saving local WiFi SSID and Passwords to the ESP8266.
//*This is further adaption of this to include server and auth code input.
// ok... working from start reading flash.
// need a pin pull down at startup to set into ap mode for new variables input.
// pull pin2 low just after a reset (not at same time but within one second to clear ssid etc and start ap)
// entering server ip on ap webpage as 1.1.1.1 will connect to Blynk cloud.
// ap address is standard 192.168.4.1
// any other will be a local server connection.
// copy and paste auth code from Blynk project.
// reset after done to re-connect
//
// working now that data is pulled from flash rather than relying on global variables.
// following just for info.
//IPAddress server_ip (10, 0, 0, 10);
// ///Mac address should be different for each device in your LAN
//byte arduino_mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
//IPAddress arduino_ip ( 10, 0, 0, 20);
//IPAddress dns_ip ( 8, 8, 8, 8);
//IPAddress gateway_ip ( 10, 0, 0, 1);
//IPAddress subnet_mask(255, 255, 255, 0);
//void setup()
//{
// Serial.begin(9600);
// Blynk.begin(auth, server_ip, 8442, arduino_ip, dns_ip, gateway_ip, subnet_mask, arduino_mac);
// Or like this:
//Blynk.begin(auth, "cloud.blynk.cc", 8442, arduino_ip, dns_ip, gateway_ip, subnet_mask, arduino_mac);
// problem with parsing server ip overcome using the above method
#include <EEPROM.h>
#include "ESP8266WiFi.h"
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp8266.h>
MDNSResponder mdns;
WiFiServer server(80);
//char auth[] = "47e420915db74a2a90439a60b71a7cf8"; // local server token
//char auth[] = "88b810d70d8444b080666ee1928bc955"; // Blynk token "YourAuthToken"
const char* APssid = "ESP8266"; // Name of access point
const char* servAuth;
const char* servi ;
const char* mypass;
const char* mysid;
//const char* mysid1;
String st;
String rsid;
String rpass;
String rserv;
String rkey;
String epsid;
String eppass;
String epserv;
String epauth;
boolean newSSID = false;
String key;
int checkV0= 0;
WidgetLED led1(0);
WidgetLCD lcd(6);
int pos = 0;
IPAddress server_ip (0, 0, 0, 0);
void setup() {
Serial.begin(115200);
delay(10);
Serial.println("Startup");
EEPROM.begin(512);
delay(1000);
if (digitalRead(2)==0){eepromClearSid();}
eepromRead();
int count=0;
WiFi.begin(mysid,mypass); // gets from eeprom read.
Serial.println(" trying wifi begin");
//*****************************************************************
pinMode(5,OUTPUT);
pinMode(2,OUTPUT);
digitalWrite(2,HIGH);
if ( testWifi()) {
//****************************************
// string epserv in the form of xxx#xxx$xxx%xxx*
//need to extract each number string, convert to value, and put into server_ip
String ip_one;
String ip_two;
String ip_three;
String ip_four;
ip_one=epserv.substring(0,epserv.indexOf('#'));
ip_two=epserv.substring(epserv.indexOf('#')+1,epserv.indexOf('$'));
ip_three=epserv.substring(epserv.indexOf('$')+1,epserv.indexOf('%'));
ip_four=epserv.substring(epserv.indexOf('%')+1,epserv.indexOf('*'));
Serial.println(ip_one);
Serial.println(ip_two);
Serial.println(ip_three);
Serial.println(ip_four);
server_ip[0]= ip_one.toInt();
server_ip[1]= ip_two.toInt();
server_ip[2]= ip_three.toInt();
server_ip[3]= ip_four.toInt();
Serial.println ("Blynk begin?");
if (server_ip[0]==1 && server_ip[1]==1 && server_ip[2]==1 && server_ip[3]==1)
{
Serial.print("going Cloud");
Blynk.config(servAuth);
bool result = Blynk.connected();
Serial.print(result);
if (!result){digitalWrite(2,LOW);}
}
else
{
Serial.println("going local");
Serial.println(server_ip);
Blynk.begin(servAuth,mysid,mypass,server_ip);
bool result = Blynk.connected();
Serial.print(result);
if (!result){digitalWrite(2,LOW);}
}
return;
}
//****************************************************************
// otherwise, set up an access point to input SSID and password
else
{ Serial.println("");
Serial.println("Connect timed out, opening AP");
setupAP(); }
}
int testWifi(void) {
long Timeout = (millis() + 10000);
Serial.print("Waiting for Wifi to connect. ");
while (millis() < Timeout){
delay(500);
Serial.print(".");
if (WiFi.status() == WL_CONNECTED) {
Serial.println("");
Serial.println("WiFi connected.");
return(1);
}
}
return(0);
}
void launchWeb(int webtype) {
Serial.println("");
Serial.println("WiFi connected");
Serial.println(WiFi.localIP());
Serial.println(WiFi.softAPIP());
digitalWrite(2,LOW);
delay(1000);
digitalWrite(2,HIGH);
// Start the server
server.begin();
Serial.println("Server started");
int b = 20;
int c = 0;
while(b == 20) {
b = mdns1(webtype);
//If a new SSID and Password were sent, close the AP, and connect to local WIFI
if (newSSID == true){
newSSID = false;
Serial.println ("reading eeprom");
eepromRead();
Serial.println("Connecting to local Wifi"); //Close the AP and connect with new SSID and P/W
WiFi.softAPdisconnect(true);
delay(500);
Serial.println(epsid);
Serial.println(eppass);
Serial.println(epauth);
Serial.println(epserv);
mysid = epsid.c_str();
mypass =eppass.c_str();
servi = epserv.c_str();
servAuth = epauth.c_str();
WiFi.begin(mysid,mypass);
delay(3000);
// string epserv in the form of xxx#xxx$xxx%xxx*
//need to extract each number string, convert to value, and put into server_ip
String ip_one;
String ip_two;
String ip_three;
String ip_four;
ip_one=epserv.substring(0,epserv.indexOf('#'));
ip_two=epserv.substring(epserv.indexOf('#')+1,epserv.indexOf('$'));
ip_three=epserv.substring(epserv.indexOf('$')+1,epserv.indexOf('%'));
ip_four=epserv.substring(epserv.indexOf('%')+1,epserv.indexOf('*'));
Serial.println(ip_one);
Serial.println(ip_two);
Serial.println(ip_three);
Serial.println(ip_four);
server_ip[0]= ip_one.toInt();
server_ip[1]= ip_two.toInt();
server_ip[2]= ip_three.toInt();
server_ip[3]= ip_four.toInt();
if ( testWifi()) {
Serial.println ("Blynk begin?");
if (server_ip[0]==1 && server_ip[1]==1 && server_ip[2]==1 && server_ip[3]==1)
{
Serial.print("going Cloud");
Blynk.config(servAuth);}
bool result = Blynk.connected();
Serial.print(result);
if (!result){digitalWrite(2,LOW);}
else
{
Serial.println("going local");
Serial.println(server_ip);
Blynk.begin(servAuth,mysid,mypass,server_ip);
bool result = Blynk.connected();
Serial.print(result);
if (!result){digitalWrite(2,LOW);}
}
return;
}
else{
Serial.println("");
Serial.println("New SSID or Password failed. Reconnect to server, and try again.");
setupAP();
return;
}
}
}
}
void setupAP(void) {
WiFi.mode(WIFI_STA);
WiFi.disconnect();
delay(100);
int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n == 0)
Serial.println("no networks found");
else
{
Serial.print(n);
Serial.println(" networks found");
}
Serial.println("");
st = "<ul>";
for (int i = 0; i < n; ++i)
{
// Print SSID and RSSI for each network found
st += "<li>";
st += WiFi.SSID(i);
st += " (";
st += WiFi.RSSI(i);
st += ")";
st += (WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*";
st += "</li>";
}
st += "</ul>";
delay(100);
WiFi.softAP(APssid);
Serial.println("softAP");
Serial.println("");
launchWeb(1);
}
String urldecode(const char *src){ //fix encoding
String decoded = "";
char a, b;
while (*src) {
if ((*src == '%') && ((a = src[1]) && (b = src[2])) && (isxdigit(a) && isxdigit(b))) {
if (a >= 'a')
a -= 'a'-'A';
if (a >= 'A')
a -= ('A' - 10);
else
a -= '0';
if (b >= 'a')
b -= 'a'-'A';
if (b >= 'A')
b -= ('A' - 10);
else
b -= '0';
decoded += char(16*a+b);
src+=3;
}
else if (*src == '+') {
decoded += ' ';
*src++;
}
else {
decoded += *src;
*src++;
}
}
decoded += '\0';
return decoded;
}
int mdns1(int webtype){
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return(20);
}
Serial.println("");
Serial.println("New client");
// Wait for data from client to become available
while(client.connected() && !client.available()){
delay(1);
}
// Read the first line of HTTP request
String req = client.readStringUntil('\r');
// First line of HTTP request looks like "GET /path HTTP/1.1"
// Retrieve the "/path" part by finding the spaces
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(req);
return(20);
}
req = req.substring(addr_start + 1, addr_end);
Serial.print("Request: ");
Serial.println(req);
client.flush();
String s;
if ( webtype == 1 ) {
if (req == "/")
{
IPAddress ip = WiFi.softAPIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>";
s += "<font face='arial,helvetica' size='7'>";
s += "<b><label>Hello from ESP8266 at ";
s += ipStr;
s += "</label></b><p>";
s += st;
s += "<form method='get' action='a'><label>SSID: </label><input name='ssid' style='width:200px; height:60px; font-size:50px;'> ";
s += "<label>Password: </label><input name='pass*' style='width:200px; height:60px; font-size:50px;'>";
s += "<p><label>Server: </label><input name='serv+' style='width:200px; height:60px; font-size:50px;'>";
s += "<p><label>Token: </label><input name='key' style='width:300px;height:60px; font-size:50px;'>";
s += "<p><input type='submit' style='font-size:60px'></form>";
s += "</html>\r\n\r\n";
Serial.println("Sending 200");
}
else if ( req.startsWith("/a?ssid=") ) {
newSSID = true;
String qsid; //WiFi SSID
qsid = urldecode(req.substring(8,req.indexOf('&')).c_str()); //correct coding for spaces as "+"
Serial.println(qsid);
Serial.println("");
rsid = qsid;
String qpass; //Wifi Password
qpass = urldecode(req.substring(req.indexOf('*')+2,req.lastIndexOf('%')-5).c_str());//correct for coding spaces as "+"
Serial.println(qpass);
Serial.println("");
rpass = qpass;
String qserv; //Wifi server port
qserv = urldecode(req.substring(req.lastIndexOf('%')+4,req.lastIndexOf('&')).c_str());//correct for coding spaces as "+"
Serial.println(qserv);
Serial.println("");
rserv = qserv;
String qkey; //Wifi auth
qkey = urldecode(req.substring(req.lastIndexOf('=')+1).c_str());//correct for coding spaces as "+"
Serial.println(qkey);
Serial.println("");
rkey = qkey;
// conversion allocation of string to const char
// const char* conv_my_str = my_str.c_str();
mysid=qsid.c_str();
mypass=qpass.c_str();
servi=qserv.c_str();
servAuth = qkey.c_str();
Serial.print("at eeprom write stage");
Serial.println ( mysid);
Serial.println ( mypass);
Serial.println ( servi);
Serial.println ( servAuth);
String allintoEP;
allintoEP += qsid;
allintoEP += qpass;
allintoEP += qserv;
allintoEP += qkey;
char epssid[allintoEP.length()];
allintoEP.toCharArray(epssid, allintoEP.length());
int epcount=0;
while (epcount < allintoEP.length()){
if (allintoEP[epcount] == 0) {allintoEP[epcount]=42;} // puts a "*" between variables
EEPROM.write(epcount,allintoEP[epcount]);
epcount ++;
}
EEPROM.commit();
// const char* conv_my_str = my_str.c_str();
// servi= rserv.c_str();
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP8266 ";
s += "<p> New SSID and Password accepted</html>\r\n\r\n";
}
else
{
s = "HTTP/1.1 404 Not Found\r\n\r\n";
Serial.println("Sending 404");
}
}
else
{
if (req == "/")
{
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>Hello from ESP8266";
s += "<p>";
s += "</html>\r\n\r\n";
Serial.println("Sending 200");
}
else
{
s = "HTTP/1.1 404 Not Found\r\n\r\n";
Serial.println("Sending 404");
}
}
client.print(s);
Serial.println("Done with client");
return(20);
}
void eepromClearSid(){
byte value=0;
int count=0;
int len = 61;
int addr;
while (addr < len){
value= 65;
if (count ==15 || count ==30 || count == 45 || count == 60){ value=42;}
EEPROM.write(addr,value);
addr++;
count++;
}
EEPROM.commit();
}
void eepromRead() {
epsid="";
eppass="";
epserv="";
epauth="";
String llit;
int len = 200;
int addr=0;
int count=0;
byte value;
byte marker=35; // "#"
while (count < len) {
value= EEPROM.read(addr);
if (value != 42){
epsid += char(value);}
count++;
addr++;
if (value == 42){ break; }
}
Serial.print("epsid =");
Serial.println(epsid);
while (count < len) {
value= EEPROM.read(addr);
if (value != 42){
eppass += char (value);}
count++;
addr++;
if (value == 42){ break; }
}
Serial.print("eppass =");
Serial.println(eppass);
//epserv = char(34); //"
while (count < len) {
value= EEPROM.read(addr);
if (value != 42){ // *
if (value == 46){ value = marker;marker++;} //46 = . marker starts with # then $ then %
epserv += char(value);}
count++;
addr++;
if (value == 42){ break; }
}
epserv += char(42); //*
Serial.print("epserv =");
Serial.println(epserv);
while (count < len) {
value= EEPROM.read(addr);
if (value != 42){
epauth += char(value);}
count++;
addr++;
if (value == 42){ break; }
}
Serial.print("epauth =");
Serial.println(epauth);
// mysid= fill.c_str(); assign string to const char
// const char* conv_my_str = my_str.c_str();
mysid = epsid.c_str();
mypass =eppass.c_str();
servi = epserv.c_str();
servAuth = epauth.c_str();
Serial.print("mysid=");
Serial.println(mysid);
Serial.print("mypass=");
Serial.println(mypass);
Serial.print("servi=");
Serial.println(servi);
Serial.print("servAuth=");
Serial.println(servAuth);
}
BLYNK_WRITE(V1)
{
lcd.clear();
int pinData = param.asInt();
Blynk.virtualWrite(5,millis()/1000);
digitalWrite(5,pinData);
Blynk.virtualWrite(V0,pinData);
Serial.print("Virtualport = ");
Serial.println(pinData);
if (pinData == 0)
{
led1.off();
}
else
{
led1.on() ;
}
lcd.print(pos,1,"uptime");
+pos;
Blynk.notify("switch has been used");
}
BLYNK_WRITE(V5)
{
lcd.print(4,1,"uptime");
}
void loop() {
// put your main code here, to run repeatedly:
Blynk.run();
yield();
}