Liste des composants nécessaires pour la réalisation du circuit :
Schéma du montage électronique :
Pour les amateurs d'impression 3D, j'ai fait quelques templates qui permettent d'imprimer divers boitiers pouvant accueillir les divers composants utilisés dans mes tutoriels.
- Pour un composant PIR, vous trouverez le boitier à imprimer ici.
Il faut compter environ 4h pour imprimer les composants de ce boitier.
- Pour un relais, vous trouverez le boitier à imprimer ici.
Il faut compter environ 2h pour imprimer les composants de ce boitier.
L'ensemble des impressions 3D a été réalisé sur une imprimante Creality3D Ender-3 pro avec les réglages standards suivants:
Pour les personnes possédant Fritzing, voici le schéma électronique.
Voici le code à télécharger dans votre Arduino:
#include <SoftwareSerial.h>
#include <SFE_BMP180.h>
#include <Wire.h>
//*****************************************************************************************//
#define build 1
#define revision 1
//*****************************************************************************************//
// ##################################
// Useful Constants
// ##################################
#define SECS_PER_MIN (60UL)
#define SECS_PER_HOUR (3600UL)
#define SECS_PER_DAY (SECS_PER_HOUR * 24L)
// ##################################
// Useful Macros for getting elapsed time
// ##################################
#define numberOfSeconds(_time_) (_time_ % SECS_PER_MIN)
#define numberOfMinutes(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN)
#define numberOfHours(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)
#define elapsedDays(_time_) ( _time_ / SECS_PER_DAY)
// ##################################
// Useful Macros for debugging
// ##################################
// Comment this line if you need to activate debugging
//#define DEBUG
#ifdef DEBUG
#define SERIAL_PRINTLN(x) Serial.println (x)
#else
#define SERIAL_PRINTLN(x)
#endif
#ifdef DEBUG
#define SERIAL_PRINT(x) Serial.print (x)
#else
#define SERIAL_PRINT(x)
#endif
#ifdef DEBUG
#define SERIAL_WRITE(x) Serial.write (x)
#else
#define SERIAL_WRITE(x)
#endif
// ##################################
// Constantes
// ##################################
#define BUFFER_SIZE 64
#define DELAY_WEBSERVER_DIE 60000
#define ALTITUDE 192.0
#define DELAY_ASK_SENSOR 30000
// ##################################
// ##################################
// Broches utilisées par les capteurs
// ##################################
#define DHT11_PIN 5 // Broche "DATA" du DHT11
#define PHOTORESISTANCE_PIN 0; // Broche "DATA" de la photorésistance
#define RESET_ESP8266_PIN 13
#define ALIM_ESP8266_PIN 6
// ##################################
// Mes objets
// ##################################
SoftwareSerial ESP8266(10,11); // defines arduino pin 10 as RX and 11 as TX
HardwareSerial & dbgSerial = Serial; // serial monitor
SFE_BMP180 pressure;
// ##################################
// ##################################
// ID des composants de la sonde
// ##################################
#define SERVER_ID 2
// ##################################
// ##################################
// ID des composants de la sonde
// ##################################
#define INTERRUPTEUR_ID 18
#define HUMIDITE_ID 19
#define TEMPERATURE_ID 20
#define PRESSION_ID 21
#define LUMINOSITE_ID 22
// ##################################
// ##################################
// Variables de stockages des capteurs
// ##################################
boolean _b_ledValue_18 = 0; //off by default
int _i_valeur1_19 = 0;
int _i_valeur1_19_last = 0;
int _i_valeur2_21 = 0;
int _i_valeur4_20 = 0;
int _i_valeur5 = 0;
byte _b_compteurReboot = 0;
// ##################################
// ##################################
// Variables globales
// ##################################
unsigned long _il_tempsDepart = 0;
unsigned long _ii_tempsLastQueryingWebServer = 0;
unsigned int _ii_counterWebServer=0;
unsigned int _ii_counterResetESP8266=0;
char buffer[BUFFER_SIZE]; // Don't touch
boolean lb_HomePage = 0;
// ##################################
// Code d'erreur de la fonction readDHT11()
enum
{
DHT11_SUCCESS, //!< Pas d'erreur
DHT11_TIMEOUT_ERROR, //!< Temps d'attente dépassé
DHT11_CHECKSUM_ERROR //!< Données reçues erronées
};
/****************************************************************/
/* INIT */
/****************************************************************/
void setup()
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// En cas de reboot
// Penser à réinitialiser toutes les IO utilisées
digitalWrite(7, LOW);
digitalWrite(4, LOW);
pinMode(RESET_ESP8266_PIN, OUTPUT);
digitalWrite(RESET_ESP8266_PIN, HIGH);
pinMode(ALIM_ESP8266_PIN, OUTPUT);
digitalWrite(ALIM_ESP8266_PIN, LOW);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Serial.begin(9600);
delay(10);
Serial.println();
Serial.println();
Serial.println(F("Startup"));
ESP8266.begin(115200);
pinMode(7, OUTPUT);
digitalWrite(7, HIGH);
delay(1000);
Serial.println(F("*************************************************************************"));
Serial.print(F("ESP8266 : Serveur Web "));
Serial.println(SERVER_ID);
Serial.println(F("****************************************"));
Serial.print(F("File: ")); Serial.println(__FILE__);
Serial.print(F("Build: ")); Serial.print(build); Serial.print(F(".")); Serial.println(revision);
Serial.print(F("Compile: ")); Serial.print(__TIME__); Serial.print(F(", ")); Serial.println(__DATE__);
Serial.print(F("Free RAM: ")); Serial.print(freeRam()); Serial.println(F("B\r\n"));
Serial.println(F("*************************************************************************"));
Serial.print(F("Pause "));
for (int i=0;i<30;i++)
{
Serial.print(F("."));
delay(1000);
}
Serial.println(F("."));
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
if (pressure.begin())
Serial.println(F("BMP180 init success"));
else
{
// Oops, something went wrong, this is usually a connection problem,
// see the comments at the top of this sketch for the proper connections.
Serial.println(F("BMP180 init fail\n\n"));
return;
}
int _i_pression=0, _i_altitude=0, _i_temperature=0;
readPressure(&_i_pression, &_i_altitude, &_i_temperature);
Serial.print(F("Pression : "));
Serial.println((int) _i_pression);
Serial.print(F("i_altitude: "));
Serial.println((int) _i_altitude);
Serial.print(F("Temperature (^C): "));
Serial.println((int) _i_temperature);
_i_valeur2_21 = (int) _i_pression;
_i_valeur4_20 = (int) _i_temperature;
// Lecture de la température et de l'humidité + gestion des erreurs
byte _b_DHT11_temperature=0,_b_DHT11_humidity=0;
switch (readDHT11(DHT11_PIN, &_b_DHT11_temperature, &_b_DHT11_humidity))
{
case DHT11_SUCCESS:
// Affichage de la température et du taux d'humidité
Serial.print(F("Humidite (%): "));
Serial.println((int) _b_DHT11_humidity);
Serial.print(F("Temperature (^C): "));
Serial.println((int) _b_DHT11_temperature);
if (_i_valeur1_19!=0) _i_valeur1_19_last = _i_valeur1_19;
_i_valeur1_19 = (int) _b_DHT11_humidity;
break;
case DHT11_TIMEOUT_ERROR:
Serial.println(F("Temps d'attente depasse !"));
break;
case DHT11_CHECKSUM_ERROR:
Serial.println(F("Erreur de checksum !"));
break;
}
delay(3000);
Serial.println(F("Alimente ESP8266"));
envoieAuESP8266(F("AT+CIOBAUD=9600"));
recoitDuESP8266(3000, false);
ESP8266.begin(9600);
delay(2000);
initESP8266();
digitalWrite(4, HIGH);
digitalWrite(7, LOW);
//wdt_enable(WDTO_8S);
_ii_tempsLastQueryingWebServer = millis();
}
/****************************************************************/
/* BOUCLE INFINIE */
/****************************************************************/
void loop()
{
if (millis() - _il_tempsDepart<0)
{
_il_tempsDepart = millis();
_ii_tempsLastQueryingWebServer = millis();
}
if (millis() - _il_tempsDepart>= DELAY_ASK_SENSOR)
{
// Lecture de la température et de l'humidité + gestion des erreurs
byte _b_DHT11_temperature=0,_b_DHT11_humidity=0;
switch (readDHT11(DHT11_PIN, &_b_DHT11_temperature, &_b_DHT11_humidity))
{
case DHT11_SUCCESS:
// Affichage de la température et du taux d'humidité
SERIAL_PRINT(F("Humidite (%): "));
SERIAL_PRINTLN((int) _b_DHT11_humidity);
SERIAL_PRINT(F("Temperature (^C): "));
SERIAL_PRINTLN((int) _b_DHT11_temperature);
if (_i_valeur1_19!=0) _i_valeur1_19_last = _i_valeur1_19;
if (_i_valeur1_19_last>0)
_i_valeur1_19 = (int) _b_DHT11_humidity;
else
_i_valeur1_19 = ((int) _b_DHT11_humidity + _i_valeur1_19_last)/2;
break;
case DHT11_TIMEOUT_ERROR:
SERIAL_PRINTLN(F("Temps d'attente depasse !"));
break;
case DHT11_CHECKSUM_ERROR:
SERIAL_PRINTLN(F("Erreur de checksum !"));
break;
}
int _i_pression=0, _i_altitude=0, _i_temperature=0;
_b_compteurReboot = 0;
readPressure(&_i_pression, &_i_altitude, &_i_temperature);
_i_valeur2_21 = (int) _i_pression;
_i_valeur4_20 = (int) _i_temperature;
//_i_valeur5 = (int)analogRead(PHOTORESISTANCE_PIN);
SERIAL_PRINT(F("Pression : "));
SERIAL_PRINTLN((int) _i_pression);
SERIAL_PRINT(F("i_altitude: "));
SERIAL_PRINTLN((int) _i_altitude);
SERIAL_PRINT(F("Temperature (^C): "));
SERIAL_PRINTLN((int) _i_temperature);
if (_b_ledValue_18==1)
SERIAL_PRINTLN(F("Led : On"));
else
SERIAL_PRINTLN(F("Led : Off"));
SERIAL_PRINT(F("Reset : "));
SERIAL_PRINTLN(_ii_counterResetESP8266);
SERIAL_PRINT(F("Time remaining = "));
SERIAL_PRINT(elapsedDays(millis()/1000));
SERIAL_PRINT(F("d "));
SERIAL_PRINT(numberOfHours(millis()/1000));
SERIAL_PRINT(F(":"));
SERIAL_PRINT(numberOfMinutes(millis()/1000));
SERIAL_PRINT(F(":"));
SERIAL_PRINT(numberOfSeconds(millis()/1000));
_il_tempsDepart = millis();
}
// the program is alive...for now.
//wdt_reset();
ESP8266.readBytesUntil('\n', buffer, BUFFER_SIZE); //read until newline
// we expect a message like this "+IPD,ch,len:data"
if(strncmp(buffer, "+IPD,", 5)==0) //check if message starts with +IPD
{
int ch; // channel ID
int len; // message length
char *pb; // pointer inside the buffer
sscanf(buffer+5, "%d,%d", &ch, &len); //extract channel and length
if (len > 0) // if message not empty
{
_ii_tempsLastQueryingWebServer = millis();
// to find the data we must move the cursor after the colon
pb=buffer;
while(*pb!=':') pb++; // increase pointer until character is a colon
pb++; // +1 to move after the colon, not at the colon
clearESP8266SerialBuffer();
if (strstr(pb, "GET /?18=1"))
{
SERIAL_PRINTLN(F("********** led ON **********"));
_b_ledValue_18=1;
homepage(ch);
digitalWrite(7, HIGH);
}
else
{
if (strstr(pb, "GET /?18=0"))
{
SERIAL_PRINTLN(F("********** led OFF **********"));
_b_ledValue_18=0;
homepage(ch);
digitalWrite(7, LOW);
}
else
{
if (strstr(pb, "GET /?ALLSENSORS=1"))
{
SERIAL_PRINTLN(F("********** All sensors **********"));
homepage(ch);
}
else
{
if (strstr(pb, "GET /?RESET=1"))
{
SERIAL_PRINTLN(F("********** RESET **********"));
RebootESP8266();
}
else
if (strstr(pb, "GET /?INFO=1"))
{
SERIAL_PRINTLN(F("********** INFORMATION **********"));
homepageInfo(ch);
}
}
}
}
}
}
clearBuffer();
}
void clearBuffer(void)
{
for (int i =0;i<BUFFER_SIZE;i++ )
{
buffer[i]=0;
}
}
/*************************************************************
* FUNCTION : void clearESP8266SerialBuffer();(void)
* PURPOSE : read any remaining characters in espSerial buffer
*************************************************************/
void clearESP8266SerialBuffer()
{
SERIAL_PRINTLN("Flush Serial ESP8266=");
int li_i = 0;
while ( ESP8266.available() && li_i<36000) // while there are characters available
{
char a = ESP8266.read();
SERIAL_WRITE(a);
if (li_i++>=36000)
SERIAL_PRINTLN("Force End flushing");
}
SERIAL_PRINTLN("==============================");
}
/****************************************************************/
/* Fonction qui initialise l'ESP8266 */
/****************************************************************/
void initESP8266()
{
SERIAL_PRINTLN(F("**********************************************************"));
SERIAL_PRINTLN(F("**************** DEBUT DE L'INITIALISATION ***************"));
SERIAL_PRINTLN(F("**********************************************************"));
SERIAL_PRINTLN(F(""));
SERIAL_PRINTLN(F("https://github.com/espressif/ESP8266_AT/wiki/AT_Description"));
SERIAL_PRINTLN(F(""));
/*Serial.println(F("************************ AT+RST **************************"));
envoieAuESP8266("AT+RST");
recoitDuESP8266(5000, false);*/
SERIAL_PRINTLN(F("************************** AT ****************************"));
envoieAuESP8266(F("AT"));
if (!recoitDuESP8266(3000, true))
{
SERIAL_PRINTLN(F("--> Erreur initialisation. Reboot ..."));
return;
}
SERIAL_PRINTLN(F("************************** AT+GMR ****************************"));
envoieAuESP8266(F("AT+GMR"));
if (!recoitDuESP8266(5000, true))
{
SERIAL_PRINTLN(F("--> Erreur initialisation. Reboot ..."));
return;
}
//SERIAL_PRINTLN(F("********************* AT+CWMODE=3 ************************"));
//envoieAuESP8266(F("AT+CWMODE=3"));
SERIAL_PRINTLN(F("********************* AT+CWMODE=1 ************************"));
envoieAuESP8266(F("AT+CWMODE=1"));
if (!recoitDuESP8266(5000, true))
{
SERIAL_PRINTLN(F("--> Erreur initialisation. Reboot ..."));
return;
}
SERIAL_PRINTLN(F("********************** AT+CWLAP **************************"));
envoieAuESP8266(F("AT+CWLAP"));
if (!recoitDuESP8266(15000, true))
{
SERIAL_PRINTLN(F("--> Erreur initialisation. Reboot ..."));
return;
}
SERIAL_PRINTLN(F("************** AT+CWJAP=\"Livebox-17F6\" *****************"));
envoieAuESP8266("AT+CWJAP=\"MyBOX SSID\",\"My BOX Key\"");
if (!recoitDuESP8266(15000, true))
{
SERIAL_PRINTLN(F("--> Erreur initialisation. Reboot ..."));
return;
}
SERIAL_PRINTLN(F("*********************** AT+CIFSR **************************"));
envoieAuESP8266(F("AT+CIFSR"));
if (!recoitDuESP8266(3000, true))
{
SERIAL_PRINTLN(F("--> Erreur initialisation. Reboot ..."));
return;
}
SERIAL_PRINTLN(F("********************* AT+CIPMUX=1 *************************"));
envoieAuESP8266(F("AT+CIPMUX=1"));
if (!recoitDuESP8266(3000, true))
{
SERIAL_PRINTLN(F("--> Erreur initialisation. Reboot ..."));
return;
}
SERIAL_PRINTLN(F("*********************** AT+CIPSTA **************************"));
envoieAuESP8266(F("AT+CIPSTA=\"192.168.1.241\""));
if (!recoitDuESP8266(3000, true))
{
SERIAL_PRINTLN(F("--> Erreur initialisation. Reboot ..."));
return;
}
SERIAL_PRINTLN(F("******************* AT+CIPSERVER=1,80 *********************"));
envoieAuESP8266(F("AT+CIPSERVER=1,80"));
if (!recoitDuESP8266(5000, true))
{
SERIAL_PRINTLN(F("--> Erreur initialisation. Reboot ..."));
return;
}
SERIAL_PRINTLN(F("**********************************************************"));
SERIAL_PRINTLN(F("***************** INITIALISATION TERMINEE ****************"));
SERIAL_PRINTLN(F("**********************************************************"));
SERIAL_PRINTLN(F(""));
}
void software_Reset()
{
// Restarts program from beginning but does not reset the peripherals and registers
asm volatile (" jmp 0");
}
void RebootESP8266()
{
// Reboot ESP8266
// Reset de l'ESP8266
SERIAL_PRINTLN();
SERIAL_PRINTLN(F("ALIM ESP8266"));
SERIAL_PRINTLN();
SERIAL_PRINTLN(F("->ALIM OFF"));
digitalWrite(ALIM_ESP8266_PIN, LOW);
delay(2000);
SERIAL_PRINTLN(F("->ALIM ON"));
digitalWrite(ALIM_ESP8266_PIN, HIGH);
SERIAL_PRINTLN();
SERIAL_PRINTLN(F("RESET ESP8266"));
SERIAL_PRINTLN();
SERIAL_PRINTLN(F("->PIN RESET ESP8266 LOW"));
digitalWrite(RESET_ESP8266_PIN, LOW);
delay(200);
digitalWrite(RESET_ESP8266_PIN, HIGH);
recoitDuESP8266(5000, false);
// On relance
if (_b_compteurReboot == 5)
{
SERIAL_PRINTLN();
SERIAL_PRINTLN(F("RESET ARDUINO"));
SERIAL_PRINTLN();
software_Reset();
}
_b_compteurReboot++;
}
/****************************************************************/
/* Fonction qui envoie une commande à l'ESP8266 */
/****************************************************************/
void envoieAuESP8266(String commande)
{
SERIAL_PRINTLN(commande);
ESP8266.println(commande);
}
/****************************************************************/
/*Fonction qui lit et affiche les messages envoyés par l'ESP8266*/
/****************************************************************/
bool recoitDuESP8266(const int timeout, bool mustControl)
{
bool found = false;
long int time = millis();
char c_Old=' ';
while( (time+timeout) > millis() && !found)
{
while(ESP8266.available())
{
char c = ESP8266.read();
SERIAL_PRINT(c);
if (!found)
{
if (c_Old=='O' && c=='K')
{
// contains
SERIAL_PRINTLN(" -> Valide");
found = true;
//break;
}
c_Old = c;
}
}
}
if (!mustControl) found = true;
return found;
}
/**************************************************************
* FUNCTION : void homepage(int id)
* PURPOSE : send a web page and close connection
***************************************************************/
void homepage(int id)
{
String Header;
int li_lenContent = 0;
Header = F("HTTP/1.1 200 OK\r\n"); //bog standard stuff - should provide alternative headers
Header += F("Content-Type: text/html\r\n");
Header += F("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache\r\n");
Header += F("Connection: close\r\n");
//Header += F("Refresh: 30\r\n");
if (_ii_counterWebServer>=65535)
_ii_counterWebServer=0;
_ii_counterWebServer++;
li_lenContent = sendHTMLResponse(id, false);
Header += F("Content-Length: "); //ESP likes to know the length
Header += (int)(li_lenContent); //length determined here
Header += F("\r\n\r\n"); //blank line
SERIAL_PRINTLN(F("************ Prepare data **************"));
ESP8266.print(F("AT+CIPSEND=")); //send the web page
ESP8266.print(id);
ESP8266.print(F(","));
ESP8266.println(Header.length()+li_lenContent);
delay(10);
if (ESP8266.find(">"))
{
//prompt from ESP8266 indicating ready
SERIAL_PRINTLN(F("************ send Header **************"));
ESP8266.print(Header); //out it goes!!
SERIAL_PRINTLN(F("************ send Content **************"));
sendHTMLResponse(id, true);
delay(10);
}
ESP8266.print(F("AT+CIPCLOSE="));
ESP8266.print(id);
ESP8266.print(F("\r\n"));
SERIAL_PRINTLN(F("************ Close connexion **************"));
clearESP8266SerialBuffer();
}
int sendHTMLResponse(int id, boolean lb_vrai)
{
int li_lenContent = 0;
String Content;
// ########################
// Capteur de pression
// ########################
Content = PRESSION_ID;
Content += F("=");
Content += String(_i_valeur2_21);
li_lenContent += Content.length();
if (lb_vrai)
{
ESP8266.print(Content);
SERIAL_PRINTLN(Content);
}
// ########################
// Capteur de temperature
// ########################
Content = F(";");
Content += TEMPERATURE_ID;
Content += F("=");
Content += String(_i_valeur4_20);
li_lenContent += Content.length();
if (lb_vrai)
{
ESP8266.print(Content);
SERIAL_PRINTLN(Content);
}
// ########################
// Interrupteur
// ########################
Content = F(";");
Content += INTERRUPTEUR_ID;
if(_b_ledValue_18 == 0)
Content += F("=0");
else
Content += F("=1");
li_lenContent += Content.length();
if (lb_vrai)
{
ESP8266.print(Content);
SERIAL_PRINTLN(Content);
}
// ########################
// Capteur d'humidité
// ########################
Content = F(";");
Content += HUMIDITE_ID;
Content += F("=");
Content += String(_i_valeur1_19);
li_lenContent += Content.length();
if (lb_vrai)
{
ESP8266.print(Content);
SERIAL_PRINTLN(Content);
}
// ########################
// Compteur
// ########################
Content = F(";0=");
Content += String(_ii_counterWebServer);
li_lenContent += Content.length();
if (lb_vrai)
{
ESP8266.print(Content);
SERIAL_PRINTLN(Content);
}
return li_lenContent;
}
/**************************************************************
* FUNCTION : void homepage(int id)
* PURPOSE : send a web page and close connection
***************************************************************/
void homepageInfo(int id)
{
String Header;
int li_lenContent = 0;
Header = F("HTTP/1.1 200 OK\r\n"); //bog standard stuff - should provide alternative headers
Header += F("Content-Type: text/html\r\n");
Header += F("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache\r\n");
Header += F("Connection: close\r\n");
//Header += F("Refresh: 30\r\n");
if (_ii_counterWebServer>=65535)
_ii_counterWebServer = 0;
_ii_counterWebServer++;
li_lenContent = sendHTMLInfoResponse(id, false);
Header += F("Content-Length: "); //ESP likes to know the length
Header += (int)(li_lenContent); //length determined here
Header += F("\r\n\r\n"); //blank line
SERIAL_PRINTLN(F("************ Prepare data **************"));
ESP8266.print(F("AT+CIPSEND=")); //send the web page
ESP8266.print(id);
ESP8266.print(F(","));
ESP8266.println(Header.length()+li_lenContent);
delay(10);
if (ESP8266.find(">"))
{
//prompt from ESP8266 indicating ready
SERIAL_PRINTLN(F("************ send Header **************"));
ESP8266.print(Header); //out it goes!!
SERIAL_PRINTLN(F("************ send Content **************"));
sendHTMLInfoResponse(id, true);
delay(10);
}
ESP8266.print(F("AT+CIPCLOSE="));
ESP8266.print(id);
ESP8266.print(F("\r\n"));
SERIAL_PRINTLN(F("************ Close connexion **************"));
clearESP8266SerialBuffer();
}
int sendHTMLInfoResponse(int id, boolean lb_vrai)
{
int li_lenContent = 0;
String Content;
Content = F("<title> Server ");
Content += SERVER_ID;
Content += F(" </title>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<HTML><body bgcolor=\"#99ff99\" alink=\"#EE0000\" link=\"#0000EE\" text=\"#000000\"vlink=\"#551A8B\">");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<H1>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("ESP8266 Web Server Info Page, Reloads = ");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = String(_ii_counterWebServer);
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<BR><BR>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("</H1>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<H2>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("Number of reset(s) = ");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = String(_ii_counterResetESP8266);
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<br>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("Time remaining = ");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = String(elapsedDays(millis()/1000));
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("d ");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = String(numberOfHours(millis()/1000));
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F(":");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = String(numberOfMinutes(millis()/1000));
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F(":");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = String(numberOfSeconds(millis()/1000));
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<br>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("This is channel ");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = String(id);
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F(" of 0-4 available channels");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<BR><BR></H2>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<H3>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("Pressure [");
Content += PRESSION_ID;
Content += F("]=");
Content += String(_i_valeur2_21);
Content += F(" Pa<BR>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("Temperature [");
Content += TEMPERATURE_ID;
Content += F("]=");
Content += String((float)_i_valeur4_20/100, 2);
Content += F(" °c<BR>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("Humidite [");
Content += HUMIDITE_ID;
Content += F("]=");
Content += String(_i_valeur1_19);
Content += F(" %<BR>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("Relais [");
Content += INTERRUPTEUR_ID;
Content += F("]=");
if(_b_ledValue_18 == 0)
Content += F("OFF");
else
Content += F("ON");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<br><br><br>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("<i><a href=\"mailto:ludovic_gauthier@yahoo.fr?subject=ESP8266%20Webserver\">Ludovic GAUTHIER 2016</a></i><br>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
Content = F("</H3></BODY></HTML>");
li_lenContent += Content.length();
if (lb_vrai) ESP8266.print(Content);
return li_lenContent;
}
/**
* Lit la température et le taux d'humidité capté par un capteur DHT11
*
* @param pin Broche sur laquelle est câblé le capteur
* @param temperature Pointeur vers la variable stockant la température
* @param humidity Pointeur vers la variable stockant le taux d'humidité
* @return DHT11_SUCCESS si aucune erreur, DHT11_TIMEOUT_ERROR en cas de timeout, ou DHT11_CHECKSUM_ERROR en cas d'erreur de checksum
*/
byte readDHT11(byte pin, byte* temperature, byte* humidity)
{
// data[] -> buffer contenant les données du cpateur
// counter -> compteur permettant de savoir quel bit est reçu (bitwise)
// index -> compteur permettant de savoir quel octet est reçu (bitwise)
// timeout -> compteur pour le timeout
//
byte data[5] = { 0 }, counter = 7, index = 0;
unsigned int timeout;
// Conversion du numéro de broche Arduino en ports/masque binaire "bas niveau"
// Utiliser les registres du microcontrôleur est bien plus rapide que digitalWrite()
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *ddr = portModeRegister(port); // Registre MODE (INPUT / OUTPUT)
volatile uint8_t *out = portOutputRegister(port); // Registre OUT (écriture)
volatile uint8_t *in = portInputRegister(port); // Registre IN (lecture)
// Réveil du capteur
*ddr |= bit; // OUTPUT
*out &= ~bit; // LOW
delay(18); // Temps d'attente à LOW causant le réveil du capteur
*out |= bit; // HIGH
delayMicroseconds(40);
*ddr &= ~bit; // INPUT
// Attente de la réponse du capteur
timeout = 0;
while(!(*in & bit))
// Attente d'un état LOW
if (++timeout == 10000)
{
SERIAL_PRINTLN("Time out 1 !");
return DHT11_TIMEOUT_ERROR;
}
timeout = 0;
while(*in & bit)
// Attente d'un état HIGH
if (++timeout == 10000)
{
SERIAL_PRINTLN("Time out 2 !");
return DHT11_TIMEOUT_ERROR;
}
// Lecture des données du capteur (40 bits)
for (byte i = 0; i < 40; ++i)
{
// Attente d'un état LOW
timeout = 0;
while(!(*in & bit))
{
//delayMicroseconds(10);
if (++timeout == 10000)
{
SERIAL_PRINTLN("Time out 3 !");
return DHT11_TIMEOUT_ERROR;
}
}
// Mise en mémoire du temps courant
unsigned long t = micros();
// Attente d'un état HIGH
timeout = 0;
while(*in & bit)
{
//delayMicroseconds(10);
if (++timeout == 10000)
{
SERIAL_PRINTLN("Time out 4 !");
return DHT11_TIMEOUT_ERROR;
}
}
// Si le delta Temps est supérieur à 40µS c'est un "1", sinon c'est un "0"
// Le tableau data[] est initialisé à "0" par défaut
if ((micros() - t) > 40)
data[index] |= (1 << counter); // "1"
// Si le compteur de bits atteint zéro
if (counter-- == 0)
{
// On passe à l'octet suivant
counter = 7;
++index;
//break;
}
}
// Format des données :
// [0] = humidité en %
// [1] = zéro
// [2] = température en degrés Celsius
// [3] = zéro
// [4] = checksum (humidité + température)
//
*humidity = data[0];
*temperature = data[2];
// Vérifie la checksum
if (data[4] != (data[0] + data[2]))
return DHT11_CHECKSUM_ERROR; // Erreur de checksum
else
return DHT11_SUCCESS; // Pas d'erreur
}
void readPressure(int* _i_pression, int* _i_altitude, int* _i_temperature)
{
char status;
double T,P,p0,a;
// Loop here getting pressure readings every 10 seconds.
// If you want sea-level-compensated pressure, as used in weather reports,
// you will need to know the altitude at which your measurements are taken.
// We're using a constant called ALTITUDE in this sketch:
SERIAL_PRINTLN();
SERIAL_PRINT("provided altitude: ");
#ifdef DEBUG
Serial.print(ALTITUDE,0);
#endif
SERIAL_PRINT(" meters, ");
#ifdef DEBUG
Serial.print(ALTITUDE*3.28084,0);
#endif
SERIAL_PRINTLN(" feet");
// If you want to measure altitude, and not pressure, you will instead need
// to provide a known baseline pressure. This is shown at the end of the sketch.
// You must first get a temperature measurement to perform a pressure reading.
// Start a temperature measurement:
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = pressure.startTemperature();
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed temperature measurement:
// Note that the measurement is stored in the variable T.
// Function returns 1 if successful, 0 if failure.
status = pressure.getTemperature(T);
if (status != 0)
{
// Print out the measurement:
SERIAL_PRINT("temperature: ");
#ifdef DEBUG
Serial.print(T,2);
#endif
*_i_temperature = (int)(T*100);
SERIAL_PRINT(" deg C, ");
#ifdef DEBUG
Serial.print((9.0/5.0)*T+32.0,2);
#endif
SERIAL_PRINTLN(" deg F");
// Start a pressure measurement:
// The parameter is the oversampling setting, from 0 to 3 (highest res, longest wait).
// If request is successful, the number of ms to wait is returned.
// If request is unsuccessful, 0 is returned.
status = pressure.startPressure(3);
if (status != 0)
{
// Wait for the measurement to complete:
delay(status);
// Retrieve the completed pressure measurement:
// Note that the measurement is stored in the variable P.
// Note also that the function requires the previous temperature measurement (T).
// (If temperature is stable, you can do one temperature measurement for a number of pressure measurements.)
// Function returns 1 if successful, 0 if failure.
status = pressure.getPressure(P,T);
if (status != 0)
{
// Print out the measurement:
SERIAL_PRINT("absolute pressure: ");
#ifdef DEBUG
Serial.print(P,2);
#endif
*_i_pression = (int)P;
SERIAL_PRINT(" mb, ");
#ifdef DEBUG
Serial.print(p0*0.0295333727,2);
#endif
SERIAL_PRINTLN(" inHg");
// The pressure sensor returns abolute pressure, which varies with altitude.
// To remove the effects of altitude, use the sealevel function and your current altitude.
// This number is commonly used in weather reports.
// Parameters: P = absolute pressure in mb, ALTITUDE = current altitude in m.
// Result: p0 = sea-level compensated pressure in mb
p0 = pressure.sealevel(P,ALTITUDE); // we're at 1655 meters (Boulder, CO)
SERIAL_PRINT("relative (sea-level) pressure: ");
#ifdef DEBUG
Serial.print(p0,2);
#endif
*_i_pression = (int)p0;
SERIAL_PRINT(" mb, ");
#ifdef DEBUG
Serial.print(p0*0.0295333727,2);
#endif
SERIAL_PRINTLN(" inHg");
// On the other hand, if you want to determine your altitude from the pressure reading,
// use the altitude function along with a baseline pressure (sea-level or other).
// Parameters: P = absolute pressure in mb, p0 = baseline pressure in mb.
// Result: a = altitude in m.
a = pressure.altitude(P,p0);
SERIAL_PRINT("computed altitude: ");
#ifdef DEBUG
Serial.print(a,0);
#endif
*_i_altitude = (int)a;
SERIAL_PRINT(" meters, ");
#ifdef DEBUG
Serial.print(a*3.28084,0);
#endif
SERIAL_PRINTLN(" feet");
}
else SERIAL_PRINTLN("error retrieving pressure measurement\n");
}
else SERIAL_PRINTLN("error starting pressure measurement\n");
}
else SERIAL_PRINTLN("error retrieving temperature measurement\n");
}
else SERIAL_PRINTLN("error starting temperature measurement\n");
}
// ********************************************************************************** //
// OPERATION ROUTINES
// ********************************************************************************** //
// FREERAM: Returns the number of bytes currently free in RAM
int freeRam(void)
{
extern int __bss_end, *__brkval;
int free_memory;
if((int)__brkval == 0) {
free_memory = ((int)&free_memory) - ((int)&__bss_end);
}
else {
free_memory = ((int)&free_memory) - ((int)__brkval);
}
return free_memory;
}