Go Down

Topic: Capteur WiFi "clé en main" (ESP8266) (Read 572 times) previous topic - next topic

papeyeku

Jun 20, 2015, 03:06 pm Last Edit: Jun 20, 2015, 06:20 pm by papeyeku
Bonjour,

Je post ici un de mes premiers projets (ou surtout le premier que j'ai mené à terme...).
Rien de bien révolutionnaire, il s'agit simplement d'un capteur DHT22 (humidité+température) contrôlé par un ESP8266 et programmer via l'Arduino IDE.
Le petit côté "novateur" c'est la possibilité d'indiquer les identifiants du réseau wifi a utiliser :
- Si l'ESP8266 n'arrive pas à se connecter à un réseau, il se met en point d'accès.
- Les identifiants sont saisis via le navigateur (192.168.4.1/info) et stocké dans l'EEPROM
- Les infos du capteurs sont récupérable au format jsonp  (192.168.4.1/jsonp , utile pour les requetes ajax cross-domain en javascript)

Je pense que ca peut être utile pour beaucoup de projet domotiques.

N'hésitez pas à m'en faire part si vous avez des suggestions ou commentaires  :)

Code: [Select]
#include <dht.h>
#include <WiFiUdp.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <ESP8266WiFi.h>
#include <EEPROM.h>


dht DHT;

WiFiServer server(80);

const char* APssid="ESP_TempHum01";
char ssid[32];
char pass[64];
byte mac[6];

unsigned int cpt=0;
boolean takeRqte=false;
String requete="";

unsigned long delay_connect=0;

void setup() {
  delay(3000);
   Serial.begin(9600);
  delay(10);
  pinMode(2,INPUT);
 
  //Lecture de la EEPROM
    //0 taille du ssid, 1 taille du passowrd

    EEPROM.begin(512);
   
    byte ssidSize = EEPROM.read(0);
    byte passSize = EEPROM.read(33);
   

     for(int i = 1; i<ssidSize+1;i++)
      {
        ssid[cpt]=EEPROM.read(i);
        cpt++;
      }
      cpt=0;
    for(int i = 34; i<34+passSize;i++)
    {
       pass[cpt]=EEPROM.read(i);
      cpt++;       
    }
    cpt=0;
   
  EEPROM.end();
   
   
  WiFi.mode(WIFI_STA);

  WiFi.macAddress(mac);
  WiFi.disconnect(); 
 
  Serial.print("Attempting to connect to SSID: ");
  Serial.println(ssid);
  Serial.println(pass);
  WiFi.begin(ssid, pass);
  delay(5000);
  if(WiFi.status() != WL_CONNECTED)
  {
     Serial.println("Connection impossible, mode AP");
     WiFi.mode(WIFI_AP_STA);
     WiFi.softAP(APssid);
  }else{
     Serial.print("Connected to ");
     Serial.println(WiFi.SSID());
     Serial.println(WiFi.localIP());

 
  }

  server.begin();

}

void loop() {
   WiFiClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (cpt == 4 && c == '/'){takeRqte=true;}
        if (c==' '){takeRqte=false;}
       
        if(takeRqte==true && cpt!=4)
        {
         requete=requete+c;
        }
       
        cpt++;
        //Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
       
        //fin de la requete
        if (c == '\n' && currentLineIsBlank) {
         
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          //client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
         
          if(requete=="jsonp"){ //lecture du capteurs
            DHT.read22(2);
            client.print("arduino({\"temperature\":");
            client.print(DHT.temperature);
            client.print(", \"humidite\":");
            client.print(DHT.humidity);
            client.println("})");
                       
          }else if(requete=="scan") //Scan des réseaux
          {
           
          getWifiInfo(client);
          getWifiScan(client);
        }else if(requete=="info") //info (sans scan)
        {
          getWifiInfo(client);
          client.print("<br>");
          client.print("<form action=\"set\"><input type=text name=\"s\"><input type=password name=\"p\"><input type=submit value=\"OK\"></form>");
                 
        }else if(requete[0]=='s' && requete[1]=='e' && requete[2]=='t') // 192.168.x.x/set?s=
        {
           byte ssid_start=requete.indexOf('=')+1;
           byte ssid_stop=requete.indexOf('&');
           String new_ssid = requete.substring(ssid_start,ssid_stop);
           
           byte pass_start=requete.indexOf('=',ssid_start)+1;
           byte pass_stop=requete.length();
           String new_pass = requete.substring(pass_start,pass_stop);
           
           client.print("Nouveau SSID : ");
           client.print(new_ssid);
           stringToEEPROM(new_ssid,0);
           
           new_ssid.toCharArray(ssid,32);
           delay(100);
           WiFi.disconnect();
           client.println("</html>");
        }

          client.println("</html>");
         
           break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
   
    // close the connection:

    client.stop();
    Serial.println(requete);
    Serial.println("client disonnected");
    requete="";
    takeRqte=false;
    cpt=0;
  }
 
  if(millis()-delay_connect > 10000 || delay_connect>millis())
  {
    if(WiFi.status() != WL_CONNECTED){
      WiFi.mode(WIFI_AP_STA);
      WiFi.softAP(APssid);
      Serial.print("Tentative de reconnection a ");
      Serial.println(ssid);
      WiFi.begin(ssid, pass);
     
    }else{
       WiFi.mode(WIFI_STA);
       Serial.println("Connection OK");
    }
    delay_connect=millis();
  }
}

void getWifiScan(WiFiClient client)
{
    client.print("Reseaux visibles : ");
    for(int i=0; i<=WiFi.scanNetworks();i++)
    {
      client.print("<br>#");
      client.print(i);
      client.print(" : ");
      client.println(WiFi.SSID(i));
      client.print(" (");
      client.print(WiFi.RSSI(i));
      client.print(")");
    }
}
void getWifiInfo(WiFiClient client)
{
   client.print("Status : ");
   client.print(WiFi.status());
   client.print("<br>");
   client.print("SSID : ");
   client.print(WiFi.SSID());
   client.print("  -  ");
   client.println(WiFi.localIP());
   client.print("  -  ");;
   for(int i = 0; i<=6;i++)
   {
     client.print(mac[i],HEX);
     client.print(";");
   }
 
 

  client.print("<br><br>AP :");
  client.print(APssid);
  client.print("  -  ");
  client.print(WiFi.softAPIP());
  client.print("<br>");
}
void stringToEEPROM(String data, int adress)
{
  EEPROM.begin(512);
  EEPROM.write(adress,data.length());
  for(int i=adress+1;i<=adress+data.length();i++)
  {
    EEPROM.write(i,data[i-adress-1]);
  }
  EEPROM.commit();
 
}

vidal11

Bonjour, votre projet m'intéresse, pouvez vous nous donner plus d'info sur ce projet?
J'ai notamment des difficultés à télécharger la librairie ESP8266WiFi.h.

fdufnews

La librairie en question est installé avec la chaîne de développement ESP8266 (voir là).

vidal11

Vous avez pas la librairie de dht.h,j'ai trouvé que DHT.h?
En effet je souhaiterai vous poser des questions plus intéressantes.

achess

#4
Jul 31, 2015, 09:33 am Last Edit: Jul 31, 2015, 10:08 am by achess
Bonjour,
Quelle est la portée qu'on peut espérer de ce module wifi ?
C'est comme un téléphone sans fil ou une box, ou beaucoup moins ?
Peux-on y ajouter une antenne extérieure ?

fdufnews

Pour la portée, je n'ai pas trouvé d'info. Mais cela reste du WiFi donc c'est très lié à l'environnement (mur par exemple)
Il y a des variantes. Certaines possèdent une prise pour une antenne extérieure. Voir là

achess

Merci fdufnews,
il y a bien des versions avec prise antenne (ESP02 et ESP05) permettant d'y raccorder une antenne à gain. Comme il est destiné à des liaisons de fixe à fixe, c'est vraiment une option importante permettant d'augmenter grandement la portée.

titankamon

Pour tester la programmation du ESP8266 (NODEMCU 1.0), j'ai commenter les lignes dht (je n'ai pas trouver la lib, et je n'ai pas le capteur..).
L'EEPROM n'est pas initialisé la première fois, alors la récupération du SSID/PASS au début faisait crasher le module.. du coup j'ai commenter du EEPROM.begin => EEPROM.end
Et ca marche !! enfin, j'ai accéder à la page Web en 192.168.4.1, entré mon SSID / PASS de chez moi. Tout a marché !
Merci pour le tuto et le code
Je vais trouver une autre utilité à ma UNO puisque le module se programme comme un adruino, génial !

Go Up