A place users can post their projects. If you have a small project and would like your own dedicated place to post and have others chat about it then this is your spot.

User avatar
By ffaheem
#41805 Im a newbie to these forums..first time posting.

The following code enables multiple Esp to be controlled( for now simple led on/off on PIn14) through simple mesh technique...I would like some feedback and if some users could try it and see where i am going wrong or not.

I have tested this code on 3 esps and each esp can be controlled from any one in the group.

The concept is that the wherever you are located, if you have even one node near you, you can may control any other node even if the wifi is not in range(through multiple other esps in the middle).

I am using a transaction id that should be randomly generated every time a request is made to each node.

The transmission may take a little time, but the message gets through! :D

Much appreciate any comments!

Code: Select all//Logical Steps:
//Go to AP MODE and Wait for signal
//
//if id is same as own id then transmit else
//
//SAVE signal and ID and Transact id And Restart to search mode
//
//check if ID is avalable,if true then save SSID to EEPROM,else search and save wifi with no Transact ID in last 4 digits too EEPROM, if no wifi found, skip to AP mode
//
//restart to connect mode
//
//Connect to saved Wifi and Send IR and ID and Transact ID
//
//Go back to AP mode and add transact ID to AP



#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
extern "C" {
#include "user_interface.h"
}

int SetupMode = 0; //0-AP,1-Search,2-Wifi


const char* host = "192.168.4.1";
ESP8266WebServer server(80);

char trans[8]; //TransactId
char buf2[8]; //EspID
char buf3[1]; //State
char buf4[15]; //AP to connect to
char buf1[4];
const char WiFiAPPSK[] = "12345678";


const int EEPROM_MIN_ADDR = 0;
const int EEPROM_MAX_ADDR = 511;


boolean eeprom_is_addr_ok(int addr) {
return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR));
}



boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) {
// counter
int i;

if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) {
return false;
}

for (i = 0; i < numBytes; i++) {
EEPROM.write(startAddr + i, array[i]);
}
EEPROM.commit();
return true;
}


boolean eeprom_write_string(int addr, const char* string) {
int numBytes; // actual number of bytes to be written

//write the string contents plus the string terminator byte (0x00)
numBytes = strlen(string) + 1;

return eeprom_write_bytes(addr, (const byte*)string, numBytes);
}




boolean eeprom_read_string(int addr, char* buffer, int bufSize) {
byte ch; // byte read from eeprom
int bytesRead; // number of bytes read so far

if (!eeprom_is_addr_ok(addr)) {
return false;
}

if (bufSize == 0) {
return false;
}


if (bufSize == 1) {
buffer[0] = 0;
return true;
}

bytesRead = 0; // initialize byte counter
ch = EEPROM.read(addr + bytesRead); // read next byte from eeprom
buffer[bytesRead] = ch; // store it into the user buffer
bytesRead++; // increment byte counter


while ( (ch != 0x00) && (bytesRead < bufSize) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) {
ch = EEPROM.read(addr + bytesRead);
buffer[bytesRead] = ch; // store it into the user buffer
bytesRead++;
}

if ((ch != 0x00) && (bytesRead >= 1)) {
buffer[bytesRead - 1] = 0;
}

return true;
}
 
void handleRoot() {
  if(server.args()==3){
  String TransactID = server.arg(0);
  String EspID = server.arg(1);
  String State = server.arg(2);
Serial.println("Got Values:");
Serial.println("TID: "+TransactID);
Serial.println("EspID: "+EspID);
Serial.println("State: "+State);

  if(EspID==String(ESP.getChipId())){
     EEPROM.write(50,State.toInt());
    EEPROM.commit();
    digitalWrite(14,State.toInt());
    server.send(200, "text/html", "Thats me!, Changed State to "+ State);
  }else{
   
    TransactID.toCharArray(trans, 4); //convert string to char array
    eeprom_write_string(2, trans);
    EspID.toCharArray(buf2, 9); //convert string to char array
    eeprom_write_string(7, buf2);
    State.toCharArray(buf3, 2); //convert string to char array
    eeprom_write_string(16, buf3);
    EEPROM.write(0,1);
    EEPROM.commit();
    server.send(200, "text/html", "Signal Passed On");
    system_restart();
  }
 }else{
  server.send(200, "text/html", "Welcome to the MESH");
 }
   
}



void setup() {
  Serial.begin(115200);
  Serial.println();
   EEPROM.begin(512);
   pinMode(14,OUTPUT);
  SetupMode=EEPROM.read(0);
  digitalWrite(14,EEPROM.read(50));
  if (SetupMode>2){
      SetupMode=0;
  }
 
  delay(500);
  eeprom_read_string(16, trans, 2);
 
  eeprom_read_string(7, buf2, 9);

  eeprom_read_string(16, buf3, 2);
 
  eeprom_read_string(201, buf4, 16);
 
  eeprom_read_string(2, buf1, 4);
 
 
  Serial.println("Setup Mode: "+String(SetupMode));
  Serial.println("Transaction ID: "+String(buf1));
  Serial.println("ESP ID: "+String(buf2));
  Serial.println("State: "+String(buf3));
  Serial.println("WifiSSID: "+String(buf4));

  if (SetupMode==0){

   //Enter AP mode
   WiFi.mode(WIFI_AP);
  String AP_NameString = "VIS"+String(ESP.getChipId())+String(buf1);

  char AP_NameChar[AP_NameString.length() + 1];
  memset(AP_NameChar, 0, AP_NameString.length() + 1);

  for (int i=0; i<AP_NameString.length(); i++)
    AP_NameChar[i] = AP_NameString.charAt(i);

  WiFi.softAP(AP_NameChar, WiFiAPPSK);
  server.on("/SendIR", handleRoot);
  server.begin();
  Serial.println("BRAODCAST SSID: ");
Serial.println(AP_NameString);
 
  }else if(SetupMode==1){
   
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
  Serial.println("scan start");
  int n = WiFi.scanNetworks();
  Serial.println("scan done");
  if (n == 0){
    Serial.println("no networks found");
    SetupMode=0;
  }  else
  {
    Serial.print(n);
    Serial.println(" networks found");
    //VIS111111110000
    for (int i = 0; i < n; ++i)
    {     
     if(String(WiFi.SSID(i)).substring(0,3)=="VIS"){
        if(String(WiFi.SSID(i)).substring(3,11)==String(buf2)){
           
          Serial.println("Found Target: "+ String(WiFi.SSID(i)));
         
          String(WiFi.SSID(i)).toCharArray(buf4, 15);
           delay(500);
            eeprom_write_string(201, buf4);
            EEPROM.write(0,2);
            EEPROM.commit();
         
            system_restart();
            return;
        }
        if(String(WiFi.SSID(i)).substring(11,15)!=String(buf1)){
          Serial.println("Next Available Target: "+ String(WiFi.SSID(i)));
         
          String(WiFi.SSID(i)).toCharArray(buf4, 15);
            delay(500);
            eeprom_write_string(201, buf4);
            EEPROM.write(0,2);
            EEPROM.commit();
            system_restart();
            return;
        }
         
     }
     
    }
     Serial.println("No device Available...Going back to AP mode");
      EEPROM.write(0,0);
      EEPROM.commit();
      system_restart();
     
  }
  }else if(SetupMode==2){
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  Serial.print("Reading WifiAP: ");
  Serial.println(buf4);
  WiFi.begin(buf4,WiFiAPPSK);
  Serial.print("Connecting");
  int check_count = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(200);
    Serial.print(".");
    check_count++;
    if(check_count>15){
   
    Serial.println("Connection Timeout...Going back to AP mode");
      EEPROM.write(0,0);
      EEPROM.commit();
      system_restart();
    }
  }

Serial.println("WiFi connected"); 
Serial.print("connecting to ");
Serial.println(host);
 
  // Use WiFiClient class to create TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    Serial.println("Connection failed...Going back to AP Mode");
    EEPROM.write(0,0);
    EEPROM.commit();
    system_restart();
  }
 
 
  String url = "/SendIR?tid="+String(buf1)+"&esp="+String(buf2)+"&state="+String(buf3);
 
  Serial.print("Requesting URL: ");
  Serial.println(url);
 
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
     
               "Host: " + host + "\r\n" +
     
               
               "Connection: close\r\n\r\n");
 
  // Read all the lines of the reply from server and print them to Serial
  while(client.available()){
    String line = client.readStringUntil('\r');
   
    Serial.println("Response: " + line);

  }
 
  Serial.println();
  Serial.println("closing connection");
   Serial.println("Send Succesful...Will wait for 5s and then Go back to AP Mode");
   EEPROM.write(0,0);
   EEPROM.commit();
   delay(5000);
   system_restart();

  }
}

void loop() {
   server.handleClient();
}
User avatar
By ffaheem
#41823
danbicks wrote:Hi Buddy this is a nice webserver example but not a Mesh configuration.
Good attempt though.

Dans


Thanks Dan! But what is essentially the mesh example if not the same concept? I'm using the chip ID as identifiers and waiting for signal to be recieved. :?
User avatar
By Menox
#42448 Why aren't you using the mesh network class??

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMesh.h>

unsigned int request_i = 0;
unsigned int response_i = 0;

String manageRequest(String request);

/* Create the mesh node object */
ESP8266WiFiMesh mesh_node = ESP8266WiFiMesh(ESP.getChipId(), manageRequest);

/**
* Callback for when other nodes send you data
*
* @request The string received from another node in the mesh
* @returns The string to send back to the other node
*/
String manageRequest(String request)
{
/* Print out received message */
Serial.print("received: ");
Serial.println(request);

/* return a string to send back */
char response[60];
sprintf(response, "Hello world response #%d from Mesh_Node%d.", response_i++, ESP.getChipId());
return response;
}

void setup()
{
Serial.begin(115200);
delay(10);

Serial.println();
Serial.println();
Serial.println("Setting up mesh node...");

/* Initialise the mesh node */
mesh_node.begin();
}

void loop()
{
/* Accept any incoming connections */
mesh_node.acceptRequest();

/* Scan for other nodes and send them a message */
char request[60];
sprintf(request, "Hello world request #%d from Mesh_Node%d.", request_i++, ESP.getChipId());
mesh_node.attemptScan(request);
delay(1000);
}