#include <EEPROM.h>
#include "ESP8266WiFi.h"
#include <ESP8266mDNS.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp8266.h>
#include<SimpleTimer.h>
#include <DHT.h>
#include <SPI.h>
#include <PubSubClient.h>
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
byte spiDat =0; // spi data to send
DHT dht(4, DHT11,11);
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;
int slidV20val;
WidgetBridge bridge1(V20);
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();}
bridge1.setAuthToken("e32670c7d9b1417ab0b10638223222bd");
eepromRead();
int count=0;
SPI.begin();
WiFi.begin(mysid,mypass); // gets from eeprom read.
Serial.println(" trying wifi begin");
//*****************************************************************
pinMode(5,OUTPUT);
pinMode(2,OUTPUT);
digitalWrite(2,HIGH);
pinMode(16,OUTPUT);
digitalWrite(16,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);}
client.setServer("192.168.1.162", 1883);
client.setCallback(callback);
}
return;
}
//****************************************************************
// otherwise, set up an access point to input SSID and password
else
{ Serial.println("");
Serial.println("Connect timed out, opening AP");
setupAP(); }
dht.begin();
//********** end of setup
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
//*** if ((char)payload[0] == '1') {
//*** digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
// but actually the LED is on; this is because
// it is acive low on the ESP-01)
//*** } else {
//*** digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH
// }
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("ESP8266Client")) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
// ... and resubscribe
client.subscribe("inTopic");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
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(V30){
// hopefully will read slider 3;
String pinData = param.asStr(); // data comingin
slidV20val = param.asInt()/4;
const char* slid_dat = pinData.c_str();
client.publish("outTopic", slid_dat);
SPI.beginTransaction(SPISettings(1000000,MSBFIRST,SPI_MODE0));
byte spidata = slidV20val; //133;
Serial.print(spidata);
byte spiback;
int numdata=0;
digitalWrite(16,LOW); //chip select low
SPI.transfer(0);
SPI.transfer(spidata);
digitalWrite(16,HIGH);
Serial.print("");
digitalWrite(16,LOW);
SPI.transfer(1);
SPI.transfer(spidata);
SPI.endTransaction();
digitalWrite(16,HIGH); //chip cs high and transfer data
}
BLYNK_WRITE(V0)
{
spiDat=1;
spiSEND();
}
BLYNK_WRITE(V1)
{
spiDat=2;
spiSEND();
}
BLYNK_WRITE(V2)
{
spiDat=3;
spiSEND();
}
BLYNK_WRITE(V3)
{
spiDat=4;
spiSEND();
}
BLYNK_WRITE(V4)
{
spiDat=5;
spiSEND();
}
BLYNK_WRITE(V5)
{
spiDat=6;
spiSEND();
}
BLYNK_WRITE(V6)
{
spiDat=7;
spiSEND();
}
BLYNK_WRITE(V7)
{
spiDat=8;
spiSEND();
}
BLYNK_WRITE(V8)
{
spiDat=9;
spiSEND();
}
BLYNK_WRITE(V9)
{
spiDat=10;
spiSEND();
}
BLYNK_WRITE(V10)
{
spiDat=11;
spiSEND();
}
BLYNK_WRITE(V11)
{
spiDat=12;
spiSEND();
}
BLYNK_WRITE(V12)
{
spiDat=13;
spiSEND();
}
BLYNK_WRITE(V13)
{
spiDat=2;
spiSEND();
}
BLYNK_WRITE(V20)
{
int slidV20val = param.asInt();
Serial.print("slider val = ");
Serial.println(slidV20val);
bridge1.virtualWrite(20,slidV20val);
}
void spiSEND(){
SPI.beginTransaction(SPISettings(1000000,MSBFIRST,SPI_MODE0));
Serial.print(" spiDat = ");
Serial.println(spiDat);
digitalWrite(16,LOW); //chip select low
// SPI.transfer(123 );
SPI.transfer(spiDat);
digitalWrite(16,HIGH);
SPI.endTransaction();
}
void loop() {
// put your main code here, to run repeatedly:
Blynk.run();
yield();
// if (server_ip[0]!=1 && server_ip[1]!=1 && server_ip[2]!=1 && server_ip[3]!=1)
// {
// if (!client.connected()) {
// reconnect();
// }
// client.loop();
// }
}