Monday, November 27, 2017

WEMOS wifi manager.

WEMOS or ESP8622v12 switch

This project is simple upload and switch stuff on and off over your own wifi network. Switching is limited to your own personal choice. WEMOD D1 have 9 pins you can use as switches. Yes there are many code doing that. 
Why use this one code. 
To start with, you dont have to hard code password and settings. Recompile if something change. It is all handled by access point mode.
With new ESP if will write default settings once to EEPROM. Then restart again into access point mode for you to select you access point you want to connect to. Setup your password. Then you restart it. 
If your details were correctly entered, you will be connected to your network. 
Now you in client mode where you click buttons to switch stuff on. 
Second
This is the full version. 2 modes access point and client mode. 
Proses the data you received. Even rwplace special characters with really characters. 
Get and Set EEPROM. SAVING LONG STRING VALUES. 
Lots off fun to get to know the code. I added comments to about everything. 

Software 
Arduino IDE with ESP8622 libraries installed. 
Look at this tutorial Esp8266 to install all you need. I see no point copying his work and add it to my work. 

What you will need:
1 x WEMOS D1 mini or ESP8622-01 or 12 WEMOS is just easier. 

1 x 8 port relay or smaller
1 x 12 volt power supply 

Lots of some  colorful wires to hook up WEMOS to you relay module. 

Intro:
This is fully working wi-fi switch. By using relay to switch on stuff over you network using the WEMOS. But it will work on ESP-v12 and ESP-v1. With some small changes. Like pin outs. 

This is just my code. I did use lots of other people work to finish this project. Wish I remembered all of them for credits. Most is the examples that came with esp libraries, just mixed into code to work. The electronics is simple enough. I used a 8 port relay module and a WEMOS D1 MINI.

Connection:
Notice the relays green jumper! Remove it. The JD-VCC PIN is 12 Volt to pull relay in. Check this pin with the module you have.
Wemos D1 miniRelay Module
GNDGND
VCC 5 Volt from WemosVCC
D1Pin1
D2Pin 2
D3Pin 3
D4Pin 4
D5Pin 5
D6Pin 6
D7Pin 7
D8Pin 8
A0 not used yet. Want to use it to monitor battery power. 

Short Explain
The WEMOS have 9 digital pins. D0 to D 8 used to  switching relays on and off.

AP is use to setup the WEMOS to go on your home WIFI network.
 Client mode login to your network and you can operate switched anywhere where you have wifi access to you network. 

 Short code explaining
Step 1
The code start by checking if there are default settings in EEPROM. Like new esp8622 dont come all setup so we do it automatically in code. 
 - Yours will need it. Also if you make use of old esp. Please clean out EEPPROM first. So now code will write defaults in the EEPROM. 

Step 2
ESP will restart automatically and start up again in access point mode. 
- Now you can search for a access point WIFIcreations. Select it and Connect. Use password 0987654321. 
- Open browser. Type in address bar 192.168.4.1 this is the ESP8622 access point hard coded IP! 
- You should see this. But it can change anytime as i do updates. 

- This is the access point setup page. Like you can see. No need to explain much. 
- In the drop down list, select you access point. Put you password in password field. Password 8 char long and no longer than 20 char. Click save. If its successful it will say so under the save button. 
- Change page name of the page on top. No more than 20 char. Now you can Click restart on the top. 
 - After restart and WEMOS will connect to the your WIFI. If it all goes well. 

Step 3

To get IP for the ESP on your network. 
- To get WIFI IP for ESP8266. Check in your router for the IP address. Open browser, add IP in address bar and it should open the page. 
 - If your phone is setup as hotspot to connect ESP8266 to. Check under hotspot on phones Hotspot Connected devices. IP will show there. 
- You should see something like this. 


- Click button and it will switch on something. 
YOU DONE

 Error wrong AP or password 
 - If ESP8266 cant connect to your AP or hotspot, it will restart automatically to AP again. Else.... 
- To go back to AP mode Switch your router OFF. Restart the ESP8266 and wait 10 seconds for ESP8266 to automatically restart to AP mode. Go into AP mode set up AP and click restart button. Before that switch your Router ON again. 
 - Else clear the EEPROM
 - Default EEPROM setting is at end of the code. Change it there to yours. Clear EEPROM and it should write your default in EEPROM. 

Upload code 
Simple and easy project.
Don't upload code if relay module is connected.

The Version 1.4

The Code:

/*
   This code is for WEMOS D1 ESP8266 version 2.0

   - The code start by checking if settings is in EEPROM
   - If not it will write defaults in. Then connect to the Access Point to setup for your WIFI
   - If you do not see the AP name WIFIcreations. Restart WEMOS
   - In browser address bar type 194.168.4.1 this is AP IP
   - After setup WiFi and password click save!! Click restart and WEMOS will connect to the your WIFI
   - WIFI IP check in router for the IP. Open browser, add IP and it should open the page
   - Click button and it will switch on something

   - To go back to AP mode Switch your router OFF. restart WEMOS wait 10 seconds. Go into AP mode. Router ON
   - Else clear the EEPROM

   - default EEPROM is at end of the code.
*/

#include <ESP8266WiFi.h>
#include <EEPROM.h>


#define PAYLOAD_SIZE 7  // Number of switches to turn on
int nodePayload [PAYLOAD_SIZE];
// Name your switches here
String btnNames[] = {"Light 1", "Light 2", "Light 3", "Light 4", "Relay 1", "Relay 2"
                     , "Relay 3", "Relay 4", "Relay 5", "Relay 6"
                    };

// Pin Definitions
int  btnPins[] = {D0, D2, D3, D4, D5, D6, D7, D8 };

// WiFi Definitions for clientmode. Leave as is.
// SEE END OF CODE TO CHANGE THIS VALUES
String ssid = "";
String pass = "";

// ***** ACCESS POINT NAME AND PASSWORD ***** AP definitions
// SEE END OF CODE TO CHANGE THIS VALUES
#define AP_SSID "ADJ Creations"     // YOUR SSID FOR AP
String AP_PASSWORD = "0987654321";  // YOUR PASSWORD FOR AP
String nameConfig = "";             // PAGE NAME THAT WILL SHOW ON PAGE.

// Create an instance of the server
// specify the port to listen on as an argument
WiFiServer server(80);
IPAddress myIP = WiFi.softAPIP();

// Definitions
long lastDebounceTime = 0;  // Use to switch led on only
long debounceDelay = 1000;  // Normal operations

int wifi_AP = 0;            // pick between AP(for setup shit) or WIFI client
bool DEBUG = 1;             // 0 for no Serial output
int checkAP = 0;            // Check if AP mode is enabled. Because of error connection
int defaultsRead = 0;       // is there default values in EEPROM
//****************************************************************************//
// SETUP
//****************************************************************************//
void setup() {
  Serial.begin(9600);
  if (DEBUG) Serial.println("\n");
  initHardware();   // Setup pins and serial port
  initConfig();     // Setup page strings
  delay(5000);

  // Check(defaultsRead) if its new ESP with no Default Values else add Values
  // Check if client mode is setup, else restart and go to call AP(checkAP) mode
  Serial.print("Default is set as: ");  Serial.println(defaultsRead);
  Serial.print("AP or WIFI Mode is set as: ");  Serial.println(checkAP);
  if (checkAP && defaultsRead) {
    if (DEBUG) Serial.println("CLIENT MODE");
    setupWiFi();    // Enable for server
    wifi_AP = 1;
  }
  else { // Error conecting to client mode so go to AP mode.
    if (DEBUG) Serial.println("STARTING ACCESS POINT MODE");
    setupAP();      // Enable for AP
    wifi_AP = 0;
    if (!checkAP) {
      EEPROM.begin(512);
       EEPROM.write(203, 1); // Write default values to EEPROM
      EEPROM.end();
    }
  }
}
//****************************************************************************//
// SETUP YOUR HARDWARE HERE. PINS, MODULES ECT
//****************************************************************************//
void initHardware() {
  //ESP01=GPIO0-GPIO15 can be INPUT, OUTPUT, INPUT_PULLUP, and INPUT_PULLDOWN.
  //maximum output current is 12mA(R=V/I so 3.3V at 12mA = 275Ω min)
  Serial.begin(115200);
  delay(1000);
  for (int x = 0; x < PAYLOAD_SIZE; x++) {
    pinMode(btnPins[x], OUTPUT);
    delay(50);
    digitalWrite(btnPins[x], HIGH);
    delay(50);
  }
  if (DEBUG) Serial.println("Hardware setup done.");
  delay(200);
}
//****************************************************************************//
// CONFIGARATION PART. SET EEPROM AND GET EEPROM
//****************************************************************************//
void initConfig() {
  if (DEBUG) Serial.println("Reading EEPROM");
  EEPROM.begin(512);
  defaultsRead = EEPROM.read(201);    // Check if there are any default values written in EEPROM
  checkAP = EEPROM.read(203);   // if 0 then wifi mode not connecting to setting given
  EEPROM.end();

// If you restrat AP with no changes. It will fall back to AP  mode
  if (!defaultsRead || defaultsRead > 1) { // If higher than 1 its old eeprom data
    // If save successfull in CallAP function, disable this AP mode and restart
    if (DEBUG) Serial.println("*** SET DEFAULT VALUES TO EEPROM ***");
    defaultValues();  // Set values
    // THERE WAS NO DEFAULT VALUES IN EEPROM.
    // ESP MUST BE FORCED TO RESTART ELSE YOU WILL GET ERRORS
    EEPROM.begin(512);
    EEPROM.write(201, 1); // To get it back into Access point mode
    EEPROM.end();
    Serial.print("DEFAULTS SET. WILL RESTART NOW....");
    delay(4000);
    ESP.restart();
  }
  else {  // If defaults is set. Read it for use as new settings
    ssid = getEEPROMString(0, 20);         // SSID name of Client mode
    pass = getEEPROMString(20, 20);        // Password for Client mode
    AP_PASSWORD = getEEPROMString(40, 20); // Access Point Password
    nameConfig = getEEPROMString(60, 20);  // Top Page Name
    if (DEBUG) Serial.println(ssid);
    if (DEBUG) Serial.println(pass);
    if (DEBUG) Serial.println(AP_PASSWORD);
    if (DEBUG) Serial.println(nameConfig);
  }
  delay(200);
}
//****************************************************************************//
// THE MAIN LOOP
//****************************************************************************//
void loop() {
  if (wifi_AP) {
    CallSTA();
  }
  else {
    CallAP();
  }
}
//****************************************************************************//
// CLIENT MODE HTML
//****************************************************************************//
void CallSTA() {
  int x = 0;
  String switchPostion;
  String btnNu;
  int len;
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  while (!client.available()) {
    x++;                    // Time out
    if (x == 3000) return;
    delay(1);
  }
  if (DEBUG) Serial.println("\nStation Mode Connected");
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  client.flush();

  Serial.println(req);

  if (req.length() > 15) {//error corection
    //strip away received string
    req = req.substring(req.indexOf("/") + 1, req.indexOf(" HTTP/1.1"));
    if (DEBUG) Serial.println(req);

    switchPostion = req.substring( 0, 1);// Get button N for ON/F for OFF
    if (DEBUG) Serial.println(switchPostion);
    if (switchPostion == "N" || switchPostion == "F") {
      len = req.length();
      if (DEBUG) Serial.println(len);
      btnNu = req.substring(1, len);  //  Get button number pressed
      if (DEBUG) Serial.println(btnNu);
      //change the N/F to 1/0.
      //Then write a 0 or 1 to the position in the array
      if (switchPostion == "N")   nodePayload[btnNu.toInt()] = 1;
      else nodePayload[btnNu.toInt()] = 0;
    } else {
      if (DEBUG) Serial.println("Input error");
    }
    for (int x = 0; x < PAYLOAD_SIZE; x++) {
      digitalWrite(btnPins[x], nodePayload[x]);
      if (DEBUG) {
        Serial.print("Switch: ");
        Serial.print(btnPins[x]);
        Serial.print(" is ");
        Serial.print(nodePayload[x]);
        Serial.println("\n****************************");
      }
    }
  }
  client.flush();

  // Prepare the response. Start with the common header:
  String s = "HTTP/1.1 200 OK\r\n";
  s += "Content-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE HTML>\r\n<html><head>";
  s += "<meta name=\"viewport\" content=\"width=devide-width, initial-scale=1\">";

  // Color in the page and buttons
  s += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}";
  s += "body { background-color: #000;}";
  s += "th, td{ text-align: center; border: 1px solid #000099;}";
  s += "p { color: red; font-size: 3; }";
  s += "H1 { font-size: 40px;}";
  s += "H5 { color: white; font-size: 10px;}";
  s += ".button { background-color: #00aa00; color: #ffffff; font-size: 25px; font-weight: bolder; text-shadow: 5px 5px 8px #000000;";
  s += "padding: 10px 30px 10px 30px; border-radius: 1px 20px 1px 20px; ; box-shadow: 4px 5px 0px #000000;";
  s += "border 0px solid #000;}";
  s += ".button2 { background-color: #aa0000; color: #ffffff; font-size: 25px; font-weight: bolder; text-shadow: 5px 5px 8px #000000;";
  s += "padding: 10px 30px 10px 30px; border-radius: 20px 1px 20px 1px; ; box-shadow: 4px 5px 0px #000000;";
  s += "border 0px solid #000;}";
  s += ".button3 { background-color: #dddddd; color: #0000aa; font-size: 30px; font-weight: bolder; text-shadow: 5px 5px 8px #000000;";
  s += "padding: 15px 10px 15px 10px; border-radius: 20px 20px 20px 20px; ; box-shadow: 5px 5px 10px #cc0000;";
  s += "}</style>";
  s += "<title>Wifi Creations</title></head>";
  s += "<body bgcolor=#777><center>";
  s += "<table style=\"width: 100%;border: 1px solid #000099;\"><tr><td>";
  s += "<h1><center><button class=\"button3\">&#127744;&emsp;";  s += nameConfig;  s += "</button></center></h1>";

  s += "</td></tr><tr><td>";
  //create buttons on page
  for (int z = 0; z <= PAYLOAD_SIZE; z++) {
    delay(2);
    if (nodePayload[z] == 1) {
      s += "<p>&emsp;&emsp;<A HREF='/F";
      s += String(z);
      s += "'><button class=\"button\">";
      s += btnNames[z];
      s += "</button></A>&emsp;</p>";
    }
    else if (nodePayload[z] == 0) {
      s += "<p>&emsp;<A HREF='/N";
      s += String(z);
      s += "'><button class=\"button2\">";
      s += btnNames[z];
      s += "</button></A>&emsp;</p>";
    }
  }

  int emoji = random(8986, 129510);
  s += "</center></td></tr></table><br /><br /><br />";
  s += "<a href=http://github.com/ADJ7WTB/ESP8622_setup_manager><h5>&#127798;&emsp;Code for this project</h5></a>";
  s += "<a href=http://adjwtb.blogspot.com><h5>&#128149;&emsp;Other project with WEMOS</h5></a>";
  s += "<a href=https://www.w3schools.com/charsets/ref_emoji.asp><h5>&#";
  s += emoji;
  s += ";&emsp;School HTML & Emoji's</h5></a>";
  s += "</center></body></html>";

  // Send the response to the client
  client.print(s);
  delay(20);
  if (DEBUG) Serial.println("*** Client disonnected ***");

  // The client will actually be disconnected
  // when the function returns and 'client' object is detroyed
}
//****************************************************************************//
// ACCESS POINT MODE HTML
// AP only used to setup CLIENT MODE - SSID and PASSWORD and PAGE NAME
//****************************************************************************//
void CallAP() {
  int x = 0;
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  initConfig(); // Read configs before changes
  // Wait until the client sends some data
  while (!client.available()) {
    x++;
    if (x == 5000) return;
    delay(1);   ///hang
  }
  if (DEBUG) Serial.println("\nAccess Point Connected");
  // Read the first line of the request
  String req = client.readStringUntil('\r'); // Read req received
  client.flush();

  // Some EEPROM checks to see if you did save
  bool saveEEPROM = false;
  bool saveAPEEPROM = false;
  bool configEEPROM = false;

  if (req.substring(0, 13) == "GET /msg?ssid") {
    saveEEPROM = prossessForm(req);   //proccess data received. save it to the EEPROM
  }  //save AP password
  else if (req.substring(0, 15) == "GET /msg?APpass") {
    saveAPEEPROM = prossessForm(req); //proccess data received. save it to the EEPROM
  }  //config names
  else if  (req.substring(0, 12) == "GET /default") {
    configEEPROM = prossessForm(req); //proccess data received. save it to the EEPROM
  }
  else if  (req.substring(0, 12) == "GET /RESTART") {
    if (DEBUG) Serial.println("Restart to AP mode in 10 seconds.............");
    delay(10000);  // Restart button clicked
    ESP.restart();
  }

  delay(10);
  initConfig(); //get the new values

  client.flush();

  // Prepare the response. Start with the common header:
  String s = "HTTP/1.1 200 OK\r\n";
  s += "Content-Type: text/html\r\n\r\n";
  s += "<!DOCTYPE HTML>\r\n<html><head>";
  s += "<meta name=\"viewport\" content=\"width=devide-width, initial-scale=1\">";
  // Color in the page and buttons
  s += "<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}";
  s += "body { background-color: #ab631d;}";
  s += "th, td{ text-align: center; border: 1px solid #000099;}";
  s += "p { color: black; font-size: 10; }";
  s += "H1 { font-size: 40px;}";
  s += "H5 { color: white; font-size: 20px;}";
  s += ".button { background-color: #00aa00; color: #ffffff; font-size: 15px; font-weight: bolder; text-shadow: 5px 5px 8px #000000;";
  s += "padding: 5px 5px 5px 5px; border-radius: 1px 20px 1px 20px; box-shadow: 4px 5px 0px #000000;";
  s += "border 0px solid #000;}";
  s += ".button3 { background-color: #dddddd; color: #0000aa; font-size: 30px; font-weight: bolder; text-shadow: 5px 5px 8px #000000;";
  s += "padding: 15px 10px 15px 10px; border-radius: 20px 20px 20px 20px; ; box-shadow: 5px 5px 10px #cc0000;";
  s += "}</style>";
  s += "<title>SERVER</title></head><body>";
  // Starting page tables
  s += "<table style=\"width: 100%;border: 1px solid #000099;\"><tr><th>";
  s += "<h1><center><button class=\"button3\">&#127744;&emsp;";  s += nameConfig;  s += "</button></center></h1>";

  s += "</th></tr></table><table style=\"width: 100%;border: 1px solid #000099;\"><tr><td>";
  // Button to restart AP
  s += "<p>Restart after setting up your WIFI details. It will auto-connect if your WIFI password is correct.</p><br />";
  s += "<center><a href=RESTART><button class=\"button\">RESTART</button></a></center><br>";
  //scan for hotspots
  //************************
  s += "</td></tr><tr><td>";
  int n = WiFi.scanNetworks();
  delay(10);
  if (n == 0)  {
    if (DEBUG) Serial.println("Scan found no WIFI hotspot.");
    s += "<b>NO WIFI-HOTSPOT FOUND, REFRESH PAGE AGAIN.</b>";
  }
  else  {
    if (DEBUG) Serial.println("Scan found WIFI hotspot.");
    s += "<form action='msg'><b>WIFI NETWORKS FOUND</b><br><select name='ssid' width='40'> ";
    for (int i = 0; i < n; i++)
    {
      // Print SSID and RSSI for each network found
      if (n == 0) {
        s += "<option selected name='ssid' value'";
      }
      else {
        s += "<option name='ssid' value'";
      }
      if (DEBUG) Serial.print(i);
      if (DEBUG) Serial.print("\t");
      if (DEBUG) Serial.println(WiFi.SSID(i));
      s += WiFi.SSID(i);
      s += "'>";
      s += WiFi.SSID(i);
      s += "</option>";
      delay(2);
    }
    s += "</select>";
    s += "<p>Password rules. No special char!! No More than 20 char. no less than 8 char</p>";
    s += "<p><b>Password No special char!!</b><br><input type='password' name='pass' size=20 ><br><input type='submit' value='SAVE'></form>";
    if (saveEEPROM) s += "<p>SSID and Password saved to EEPROM.";
    else s += "<p>SSID and Password not saved to EEPROM. SSID should be 2 or more char. Password should be 10 and more ";
  }
  s += "</td></tr><tr><td>";
  //******* AP save password
  s += "<form action='msg'><b>Change Access Point Password.</b><br><br>If you dont want the default password.";
  s += "<input type='password' name='APpass' size=20 ><br>Repeat new password<br>";
  s += "<input type='password' name='repeatpass' size=20 >";
  s += "<br><input type='submit' value='SAVE AP'></form>";
  if (saveAPEEPROM) s += "<p>AP Password saved to EEPROM.";
  else s += "<p>AP Password not saved to EEPROM. Password need to be more than 8 char or must be the same. Dont use special char like =&?%";

  s += " </td></tr><tr><td>";
  s += "<form action='default'><b>Change Page Name. No spaces, and less than 20 char.</b>";
  s += "<br><input type='text' name='page' size=20 ><br>";
  s += "<input type='submit' value='SAVE'></form>";
  s += " </td></tr></table>";
  int emoji = random(8986, 129510);
  s += "</center></td></tr></table><br /><br /><br />";
  s += "<a href=http://github.com/ADJ7WTB/ESP8622_setup_manager><h5>&#127798;&emsp;Code for this project</h5></a>";
  s += "<a href=http://adjwtb.blogspot.com><h5>&#128149;&emsp;Other project with WEMOS</h5></a>";
  s += "<a href=https://www.w3schools.com/charsets/ref_emoji.asp><h5>&#";
  s += emoji;
  s += ";&emsp;School HTML & Emoji's</h5></a>";
  s += "</body></html>";

  // Send the response to the client
  client.print(s);
  delay(1);
  if (DEBUG) Serial.println("Client disconnected\n");
}
//****************************************************************************//
// DATA PROSSESS - DATA RECEIVED FROM AP IS STRIPPED INTO PARTS
// THEN SAVED TO EEPROM AS NEW DEFAULTS
//****************************************************************************//
bool prossessForm(String sReceived) {
  String str1 = "";
  String str2 = "";
  String str3 = "";
  String str4 = "";
  String temp = "";
  //Example: GET /msg?APpass=12345678&repeatpass=1234567 HTTP/1.1
  //Example: GET /msg?ssid=SSIDname&pass=PASSWORD HTTP/1.1
  //Example: GET /buttonNames?onname=ON&offname=OFF HTTP/1.1
  if (DEBUG) {
    Serial.println("*** START OF DATA PROCESSING ***");
    Serial.print("RECEIVED STRING: ");
    Serial.println(sReceived);
  }
  sReceived.replace("%25", "%");
  sReceived.replace("%40", "@");
  sReceived.replace("%23", "#");
  sReceived.replace("%26", "&");
  sReceived.replace("%2F", "/");
  sReceived.replace("%24", "$");
  sReceived.replace("%21", "!");
  sReceived.replace("%3F", "?");
  sReceived.replace("%D3", "=");
  sReceived.replace("%2B", "+");
  sReceived.replace("%28", "(");
  sReceived.replace("%29", ")");
  sReceived.replace("%27", "'");
  sReceived.replace("%3A", ":");
  sReceived.replace("%22", "\"");
  sReceived.replace("%2C", ",");
  sReceived.replace("%29", ")");
  sReceived.replace("%5B", "[");
  sReceived.replace("%5D", "]");
  sReceived.replace("%7B", "{");
  sReceived.replace("%7D", "}");
  sReceived.replace("%3C", "<");
  sReceived.replace("%3E", ">");
  sReceived.replace("%5E", "^");
  sReceived.replace("%7E", "~");
  int len = sReceived.length(); // You need the length of the incoming string
  if (DEBUG) {
    Serial.print("RECEIVED LENGTH: ");
    Serial.println(len);
    Serial.print("FILTER RECEIVED STRING: ");
    Serial.println(sReceived);
  }

  // RECEIVED -- GET /msg?APpass=12345678&repeatpass=1234567 HTTP/1.1
  // Get string between -- GET /msg? and HTTP/1.1
  temp = sReceived.substring(sReceived.indexOf("?") + 1, sReceived.indexOf(" HTTP/1.1"));
  // temp value = APpass=12345678&repeatpass=1234567
  if (DEBUG) {
    Serial.print("Temp string: ");
    Serial.println(temp);
    Serial.println("***********************************");
  }
  str1 = temp.substring(0, temp.indexOf("="));// Get string between -- 0 and =
  //str1 = APpass
  len = temp.length();// temp 33 = APpass=12345678&repeatpass=1234567
  temp = temp.substring(temp.indexOf("=") + 1, len);// Get string between -- GET /msg? and HTTP/1.1
  // temp value = 12345678&repeatpass=1234567
  str2 = temp.substring(0, temp.indexOf("&"));// Get string between -- 0 and &
  //str2 = 12345678
  len = temp.length();// temp 27 = 12345678&repeatpass=1234567
  temp = temp.substring(temp.indexOf("&") + 1, len);// Get string between -- & and toEnd
  // temp value = repeatpass=1234567
  str3 = temp.substring(0, temp.indexOf("="));// Get string between -- 0 and =
  len = temp.length();// temp 17 = repeatpass=1234567
  temp = temp.substring(temp.indexOf("=") + 1, len);// Get string between -- = and end
  // temp value = 1234567
  str4 = temp;

  if (DEBUG) {
    Serial.println("PROSSESSED DATA ");
    Serial.println("1: " + str1);  //HEADING (SSID or APPASS or PAGE NAME)
    Serial.println("2: " + str2);  //DATA(ssidName or apPassword)
    Serial.println("3: " + str3);  //HEADING(wifiPass or AP repeatpass)
    Serial.println("4: " + str4);  //DATA(wifiPASS or APpass)
    Serial.println("***********************************");
  }
  //Example: GET /msg?APpass=12345678&repeatpass=1234567 HTTP/1.1
  //Example: GET /msg?ssid=SSIDname&pass=PASSWORD HTTP/1.1
  if (str1 == "APpass" || str1 == "ssid") {
    int len1 = str2.length();
    int len2 = str4.length();
    if (len1 < 3 || len2 < 7) {
      if (DEBUG) {
        Serial.println("Length to short to save to EEPROM");
        Serial.print("SSID length: ");
        Serial.println(len1);
        Serial.print("PASSWORD length: ");
        Serial.println(len2);
        Serial.println("***********************************");
      }
      return false;
    }
    if (str2.indexOf(" ") >= 0) return false;
  }
  //  if (str2.indexOf("%") >= 0) return false;
  //  if (str4.indexOf("%") >= 0) return false;
  //  if (DEBUG) Serial.println("UNKNOWN SPECIAL CHAR USED AS PASSWORD.");
  if (str1 == "ssid") {
    if (DEBUG) Serial.println("SSID Save to EEPROM");
    //Function to save to EEPROM
    setEEPROMString(0, 20, str2);  //start at address 0 for SSID
    setEEPROMString(20, 20, str4); //start at address 20 for password
    return true;
  }
  else if (str1 == "APpass") {
    if (str2 == str4) {
      if (DEBUG) Serial.println("AP password saved.");
      //Function to save to EEPROM
      setEEPROMString(40, 20, str2); //start at address 20 for password
      return true;
    }
    else {
      if (DEBUG) Serial.println("AP password entered is not the same.");
      return false;
    }
  }
  else if (str1 == "page") {
    if (str2 == "") return false;
    if (DEBUG) Serial.println("Page Name Save to EEPROM");
    //Function to save to EEPROM
    setEEPROMString(60, 20, str2);
    return true;
  }
  if (DEBUG) Serial.println("*** END OF DATA PROCESSING ***");
}
//****************************************************************************//
// START AND SETUP CLIENT MADE
//****************************************************************************//
void setupWiFi() {
  //starting WIFI
  WiFi.mode(WIFI_STA);   //station modes enable
  WiFi.disconnect();
  delay(100);
  // Connect to WiFi network
  if (DEBUG) Serial.println("\nWaiting Connect to " + ssid);
  WiFi.begin(ssid.c_str(), pass.c_str());

  int xx = 0;
  while (WiFi.status() != WL_CONNECTED) {
    xx++;
    if (DEBUG) Serial.println(xx);
    delay(150);
    //LED_BUILTIN DISABLE. ITS USED FOR D4
    //digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    if (xx > 100) { //time out. go back to AP mode
      xx = 0;
      EEPROM.begin(512);
      EEPROM.write(203, 0);// 0 Set AP active in EEPROM
      EEPROM.end();
      if (DEBUG) Serial.println("ERROR TIME OUT. RESTARTING TO AP NOW.....");
      ESP.restart();
    }
  }
  if (DEBUG) Serial.println("");
  if (DEBUG) Serial.println("WiFi connected");

  // Start the server
  server.begin();
  if (DEBUG) Serial.println("Server started");

  // Print the IP address
  if (DEBUG) Serial.println(WiFi.localIP());
}
//****************************************************************************//
// START AND SETUP ACCESS POINT MODE
//****************************************************************************//
void setupAP() {
  WiFi.mode(WIFI_AP);   //AP modes enable
  if (DEBUG) Serial.println("\nStarting Access Point...");
  /* You can remove the password parameter if you want the AP to be open. */
  WiFi.softAP(AP_SSID, AP_PASSWORD.c_str());
  if (DEBUG) {
    Serial.println("HTTP server started");
    Serial.print("AP IP address: ");
    Serial.println(myIP);
    Serial.print("*****************************************\n");
    WiFi.printDiag(Serial);
    Serial.print("*****************************************\n");
  }
  server.begin();
}
//****************************************************************************//
// SET AND GET EEPROM
//****************************************************************************//
int eepromStart = 0;  //Location where to start saving to EEPROM
String getEEPROMString(int start, int len) {
  EEPROM.begin(512);  delay(10);  String string = "";
  for (int i = eepromStart + start; i < eepromStart + start + len; i++) {
    string += char(EEPROM.read(i));
    delay(2);
  }
  string = string.substring(0, string.indexOf(" "));
  string.replace("+", " ");
  EEPROM.end();
  return string;
}

void setEEPROMString(int start, int len, String string) {
  EEPROM.begin(512);
  delay(10);
  int si = 0;
  for (int i = eepromStart + start; i < eepromStart + start + len; i++) {
    char c;
    if (si < string.length()) {
      c = string[si];
    } else {
      c = 0;
    }
    Serial.print(i);
    Serial.println(c);
    EEPROM.write(i, c);
    delay(2);
    si++;
  }
  EEPROM.end();
}
//****************************************************************************//
// SET DEFAULT VALUES TO EEPROM
// NEW ESP HAVE NO SETTINGS, AP WILL NOT SHOW IF NO SSID IS SET IN EEPROM
//****************************************************************************//
void defaultValues() { // 20 CHAR IS USED. BUT YOU CAN MAKE IT MORE
  setEEPROMString(0, 20, "AndreWiFi");     //String ssid;
  setEEPROMString(20, 20, "Andre1234");   //String pass;
  setEEPROMString(40, 20, "0987654321"); //String AP_PASSWORD;
  setEEPROMString(60, 20, "ADJ Creations");  //String nameConfig;
}