Example sketches for the new Arduino IDE for ESP8266

Moderator: igrr

User avatar
By cocco
#42474 Hi, i'm not able to create a properly working connection maganger.

I want to turn on the esp8266 and look for ssid & password saved on the device.
If those values are not present or the timeout reaches it's limit i want to create an Access Point where i can insert the needed information then reset the module to connect to the new network..obviosly this should be done ine the "setup()" part of the code.

I can't find a proper example. I'm using the arduino IDE.

EDIT

Look down 2 posts
Last edited by cocco on Mon Mar 07, 2016 4:52 pm, edited 3 times in total.
User avatar
By cocco
#42564 So, i was finally able to get it working .... it's not perfect but it works... (btw the code is much shorter than all other ones)
I need something simple and mosty i use only websockets to talk with the esp8266 modules, so the loop needs to be empty.
I didn't wanted to slow down everything using one of those already existing libs.
Most of them handle the connection inside the loop() ????. SPEED, i need SPEED!!!!!!!
Also some libs fill the whole memory... just to connect the device.
Some need switches to reenter the credentials...
I also learned the hard way that in AP mode the esp totally sucks.
thats why i wrote this code

Info about the code
1. Creates an Access Point (AP) if no Infrastructure (STA) connection or credentials are aviable.
2. It uses the EEPROM to store the credentials.
3. Default (but changeable) values:
-AP-
SSID : wave
Host : http://wave.local/
IP: http://192.168.4.1/
-STA-
Host : http://wave.local/


What does this code:
1. Reads the EEPROM
2. If no credentials are aviable it creates an AP
-2a. After connecting to the AP with the default IP or Host it scans the aviable networks
-2b. And responds with a simple form to connect to the desidered one.
-2c. By selecting your ssid from a dropdown list and setting the password you'r now rdy to submit
-2d. The ESP will store your credentials in the EEPROM and reset after 30 seconds
3. If credentials are aviable but they are wrong or your in a different location and cannot connect
-3a. It tries to connnect to the stored network for 30 seconds.
-3b. If it is not able to connect it creates an AP and from there the steps are the same as in 2a to 2d
4. If credentials are aviable and the stored network exists NOTHING HAPPENS ... you need to write what you want in the loop


Code: Select all#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266mDNS.h>
#include <EEPROM.h>
MDNSResponder mdns;
WiFiServer server(80);
char s[32];
char p[64];
boolean apDone(){
 mdns.update();
 WiFiClient client=server.available();
 if(!client)return false;
 while(client.connected()&&!client.available());
 if(client.readStringUntil(' ')=="GET"){
  String b="";
  if(uint8_t a=WiFi.scanNetworks()){
   b+="<select name=\"ssid\">";
   while(a--){
    b+="<option>";
    b+=WiFi.SSID(a);
    b+="</option>";
   }
   b+="</select>";
  }else{
   b+="<input name=\"ssid\" length=\"32\">";
  }
  client.print("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!doctype html><html><body><form method=\"post\">"+b+"<input name='pass' length=64><input type='submit'></form></body></html>\r\n\r\n");
  client.flush();
 }else{
  String header=client.readString();
  header=header.substring(header.indexOf("ssid=")+5);
  String ssid=header.substring(0,header.indexOf("&pass="));
  String pass=header.substring(header.indexOf("&pass=")+6);
  for(uint8_t a=0;a<96;a++)EEPROM.write(a,a<32?ssid[a]:pass[a-32]);
  EEPROM.commit();
  client.print("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!doctype html><html><body>Restarting in 30 seconds</body></html>\r\n\r\n");
  client.flush();
  delay(30000);
  ESP.restart();
 }
 return false;
}
void setup(){
 EEPROM.begin(512);
 for(uint8_t a=0;a<96;a++)(a<32?s[a]:p[a-32])=EEPROM.read(a);
 if(s[0]){
  WiFi.mode(WIFI_STA);
  WiFi.begin(s,p);
  while(millis()<30000){
   delay(100);
   if(WiFi.status()==WL_CONNECTED){
    mdns.begin("wave",WiFi.localIP());
    //server.begin();
    /*YOU ARE CONNECTED TO A FAST NETWORK*/
    /*WRITE YOUR SETUP HERE*/
    return;
   }
  }
 }
 WiFi.disconnect();
 WiFi.mode(WIFI_AP);
 WiFi.softAP("wave");
 mdns.begin("wave",WiFi.softAPIP());
 server.begin();
 while(!apDone());
 return;
}
void loop(){
}


Now the code works nicely on my esp8266 and also prolly on yours but there are some things i want to change
I'm not a c++ programmer, i mostly wrtie in webbased languages.

I need to find an elegant way to minimize this whole code further.

Most of all i hate this part:

Code: Select all  String header=client.readString();
  header=header.substring(header.indexOf("ssid=")+5);
  String ssid=header.substring(0,header.indexOf("&pass="));
  String pass=header.substring(header.indexOf("&pass=")+6);


I'm using lots of functions and variables(STRINGS!!!!!!!) to extract the post data from the header.

Please tell me that there is something simple,maybe faster(without adding another lib) ... i want to do things properly

Another thing is
Code: Select allclient.flush();
... did i put it in the correct place?
Some people put that before they send the data to the client.

What about the
Code: Select allEEPROM.commit();
.. is that necessary only when writing?

I added almost no delays ... just the really necessary ones... would you add more? why?


Should the following vars
Code: Select allchar s[32];
char p[64];

changed to
Code: Select allconst char* s;const char* p;
?

i could not get it work the other way.

Also thos are doubles of ssid & pass inside the apDone function.
it would be nice to remove one of those duplicates... obviously avoiding complex conversions between strings or whatever.
Last edited by cocco on Sun Mar 06, 2016 1:05 pm, edited 4 times in total.