Table des matières

Installation sur Arduino

Lancer Arduino, puis dans Fichier→Preferences→Url pour cartes: copier coller:

https://arduino.esp8266.com/stable/package_esp8266com_index.json

puis dans Outils→Type de cartes→Gestionnaire de cartes taper dans la zone de recherche:

esp8266

puis selectionner la version la plus récente et installer

puis dans Outils→Type de cartes→ choisir NodeMCU 1.0

Informations générales sur les modules ESP8266

documentation du composant: https://www.espressif.com/sites/default/files/documentation/esp8266-technical_reference_en.pdf

https://cdn-shop.adafruit.com/product-files/2471/0A-ESP8266__Datasheet__EN_v4.3.pdf

https://nurdspace.nl/ESP8266

Utilisation comme modem

Liste des commandes AT: https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf

https://nurdspace.nl/ESP8266#AT_Commands

Utilisation comme carte microcontroleur

http://esp8266.github.io/Arduino/versions/2.0.0/doc/reference.html

http://esp8266.github.io/Arduino/versions/2.0.0/doc/libraries.html

http://esp8266.github.io/Arduino/versions/2.0.0/doc/installing.html

http://esp8266.github.io/Arduino/versions/2.0.0/doc/filesystem.html

http://www.instructables.com/id/Getting-Started-with-the-ESP8266-ESP-12/

https://www.fais-le-toi-meme.fr/fr/electronique/tutoriel/programmes-arduino-executes-sur-esp8266-arduino-ide

https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/using-the-arduino-addon

https://thearduinoandme.wordpress.com/tutorials/esp8266-send-receive-binary-data/

carte nodemcu

https://iotbytes.wordpress.com/nodemcu-pinout/

http://nodemcu.readthedocs.io/en/master/

carte additionnelle: https://www.ebay.com/itm/ESP8266-CH340G-NodeMcu-V3-Lua-NodeMCU-Breakout-Expansion-Board-Development-Board/382289678553?hash=item59023d90d9:m:mr8WAds9AlYpGsklGO_Lxmw

carte blynk: https://opensource.com/article/18/2/diy-blynk-board-esp8266

alimentation carte node mcu

alimenter via vin en 5V à 9V: https://www.botnroll.com/en/arduino-boards/2147-esp-12e-nodemcu-lua-wifi-development-board.html

https://www.reddit.com/r/esp8266/comments/nnig49/nodemcu_v3_vin_requires_7v/

schematique: https://fr.aliexpress.com/item/1005001636634198.html?spm=a2g0o.productlist.0.0.540c585bg83z5X&ad_pvid=202206190218386853771574783480004638954_4&s=p

module ESP 01

http://www.microchip.ua/wireless/esp01.pdf

utilisation de toutes les broches du module E01 en E/S: http://www.instructables.com/id/How-to-use-the-ESP8266-01-pins/

Brochage du module E12

http://www.alselectro.com/esp8266---e12-module.html

Carte format uno R3

https://www.ebay.fr/itm/ESP8266-ESP-12E-UART-WIFI-Wireless-Shield-TTL-Converter-R3-Meg-tr/132865454632?_trkparms=aid%3D555018%26algo%3DPL.SIM%26ao%3D1%26asc%3D20170831090034%26meid%3D3051f484f96842b0953ad0776c41a0da%26pid%3D100005%26rk%3D1%26rkt%3D12%26sd%3D332947871611%26itm%3D132865454632&_trksid=p2047675.c100005.m1851&autorefresh=true

http://www.priceminister.com/offer/buy/1347954200/hot-esp8266-esp-12e-wifi-wireless-dev-board-for-arduino-ide-uno-wemos-d1-te482.html

https://www.lightinthebox.com/fr/esp8266-module-de-carte-de-developpement-wi-fi-esp-12e_p5806485.html?prm=1.3.5.10

controle via wifi

http://www.instructables.com/id/Universal-Remote-Using-ESP8266Wifi-Controlled/

https://www.youtube.com/watch?v=YV8Mx1qvH4A

prise toute intégrée: https://www.geekbuying.com/item/Geekbes-EPS-15-Smart-Wifi-Socket-White-EU-Plug-391182.html?utm_source=newsletter&utm_medium=EDM&utm_content=&utm_campaign=DMCAH_holiday_20180222

carte intégrée avec relai: https://www.banggood.com/fr/ESP8266-12V-WiFi-Relay-Networking-Smart-Home-Phone-APP-Remote-Control-Switch-p-1172687.html?currency=EUR&utm_source=criteo&utm_medium=cpc&utm_content=all&utm_campaign=electronics-FR&cur_warehouse=CN

monitoring batteries

http://www.instructables.com/id/WIFI-Battery-Monitor-System-ESP8266/

télécommande

http://www.instructables.com/id/Using-an-ESP8266-As-a-WiFi-Enabled-Universal-Remot/

Utilisation comme modem WIFI depuis un PC

Utilisation d'un point d'accès WIFI avec serveur DHCP. L'adresse IP 192.168.1.65 est attribuée au module ESP et l'adresse IP 192.168.1.64 est attribuée à l'interface WIFI du PC.

Lancer un terminal pour dialoguer avec le module ESP via un adaptateur USB-Série:

miniterm.py /dev/ttyUSB0 115200

Les commandes affichées en doivent être saisie dans un second terminal .

Pour redémarrer le module:

AT+RST

Pour obtenir la version du firmware:

AT+GMR

Pour obtenir le mode: (1= Station, 2= Access Point, 3=both)

AT+CWMODE?
  +CWMODE:2   
  
  

Pour lister les points d'accès à portée, il faut que le module soit en mode Station:

AT+CWMODE=1
AT+CWLAP
  +CWLAP:(0,"78BF39",-36,"00:26:44:05:62:e7",1,-36)
  +CWLAP:(3,"ESPap",-81,"1a:fe:34:9b:ce:c9",11,-161)

Pour passer en mode client du point d'accès thomson “78BF39”:

AT+CWMODE=1
AT+CWJAP="78BF39","6D842DAE4B"
  WIFI CONNECTED
  WIFI GOT IP

Pour vérifier les paramètres du Access Point auquel le module est connecté:

AT+CWJAP?
  +CWJAP:"78BF39","00:26:44:05:62:e7",1,-43

Pour obtenir les adresses IP et MAC du module:

AT+CIFSR
  +CIFSR:STAIP,"192.168.1.65"
  +CIFSR:STAMAC,"18:fe:34:e5:f4:a7"

Tester si la carte répond au ping

ping 192.168.1.65

Pour pinger depuis le module ESP

AT+PING="192.168.1.64"

Pour déterminer le status (2 The ESP8266 Station is connected to an AP and its IP is obtained. 3 The ESP8266 Station has created a TCP or UDP transmission. 4 The TCP or UDP transmission of ESP8266 Station is disconnected. 5 The ESP8266 Station does NOT connect to an AP. )

AT+CIPSTATUS
  STATUS:4

Pour déterminer le nombre de connexions: single connection (AT+CIPMUX=0), multiple (AT+CIPMUX=1), le module supporte jusqu'à 4 connexions

AT+CIPMUX?
  +CIPMUX:0

Pour déterminer comment sont récupérées les données reçues: (0 - data received will be send to serial port with +IPD,<connection channel>,<length> format. (AT+CIPMUX=[0,1] )

AT+CIPMODE?
  +CIPMODE:0

Pour passer en mode transparent (les caractères envoyés au module via UART ne sont pas interprétés comme des commandes AT mais comme des données)

AT+CIPMODE=1

Pour ouvrir une socket UDP (ou TCP):

AT+CIPSTART=?
AT+CIPSTART="UDP","192.168.1.64",10000,10000

Lancer le script udp-client-emit.py pour que le module recoive un message

./udp-client-emit.py

Le terminal du module ESP doit afficher

  +IPD,20,192.168.1.64,57449:This is the message.

Pour que lors de la réception, le module n'inclue pas IP et Port distant:

AT+CIPDINFO=0
  +IPD,20:This is the message.

Pour que lors de la réception, le module inclue IP et Port distant:

AT+CIPDINFO=1
  +IPD,20,192.168.1.64,57449:This is the message.

Lancer le script udp-client-rec.py pour recevoir les données émises par le module.

./udp-client-emit.py

Pour envoyer un message de 10 octets:

AT+CIPSEND=10
> 123456abcd
  +IPD,18:echoed: 123456abcd
  OK
  

Le message doit s'afficher dans la fenêtre de udp-client-rec.py

  received "b'123456abcd'"

Pour fermer la socket:

AT+CIPCLOSE 

Lancer le script ./qt_esp8266.py pour dialoguer avec le module via une interface graphique. Cliquer sur les boutons Led, le module doit afficher les datagrammes correspondants. Pour que le module envoie un datagramme à l'application graphique.

AT+CIPSEND=35
> compteur= 123456 b1:0  b2:1  b3:0
AT+CIPSEND=35
> compteur= 123456 b1:0  b2:0  b3:0

TODO

Configuration passerelle et masque de sous réseau

AT+CIPSTA_DEF="192.168.6.100","192.168.6.1","255.255.255.0"

Scripts python

udp-client-emit.py
#!/usr/bin/python3 
#Bertrand Vandeportaele 2019
#https://pymotw.com/2/socket/udp.html
import socket
import sys
# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#server_address = ('localhost', 10000)
#esp8266 via AP thomson
server_address = ('192.168.1.65', 10000)
message = 'This is the message.'
try:
    # Send data
    print ('sending "%s"' % message)
    sent = sock.sendto(message.encode(), server_address)
finally:
    print ( 'closing socket')
    sock.close()
udp-client-rec.py
#!/usr/bin/python3 
#Bertrand Vandeportaele 2019
#https://pymotw.com/2/socket/udp.html
import socket
import sys
import fcntl,errno,os
# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#server_address = ('localhost', 10000)
#premier champ vide pour recevoir depuis n'importe quelle adresse,sinon IP en chaine de caractères
server_address = ('', 10000)
 
sock.bind(server_address)
#fcntl.fcntl(sock, fcntl.F_SETFL, os.O_NONBLOCK) #rend les appels non bloquants
print('Press CTRL+C to quit')
try:
  while(True):
    # Receive response
    print('waiting to receive')
    data, server = sock.recvfrom(4096)
    print ( 'received "%s"' % data)
finally:
    print ( 'closing socket')
    sock.close()

Application carte pour automatisme porte de garage

bvdp.inetdoc.net_files_garage_img_20180224_134416_crop.jpg

bvdp.inetdoc.net_files_garage_img_20180224_134359_crop.jpg

Programme pour porte garage

Blink_udp_8266_Bvdp.ino
//B. Vandeportaele 2018
 
//The blue LED on the ESP-01 module is connected to GPIO1
//(which is also the TXD pin; so we cannot use Serial.print() at the same time)
 
#define RELAY_OPEN 14
#define RELAY_CLOSE 12
#define RELAY_LIGHT 16
 
//inputs connected to button that connect the input to GND when pressed
//pin 5 erroneously numbered 4 on the PCB
#define BUTTON_OPEN 5
#define BUTTON_CLOSE 13
 
//pin 4 erroneously numbered 5 on the PCB
#define LASER_SENSOR 4
//The laser and the sensor can both work at 3.3V. The output of the sensor is at logic high level when it does not receive enough light
//disconnect from the sensor and connect this pin to GND to disable the laser barrier security
 
#include <ESP8266WiFi.h>
#include <WiFiClient.h> 
#include <WiFiUdp.h>
WiFiUDP Client;
 
// A UDP instance to let us send and receive packets over UDP
WiFiUDP udp;
// wifi connection variables
#include "wifidata.h"
//These values are set in "wifidata.h"
//unsigned int localPort = -----------; // local port to listen for UDP packets
//const char* ssid = "----------------";
//const char* password = "---------------------";
 
#ifdef TRANSMITOVERWIFI
String ip = "192.168.1.9"; // the remote IP address
IPAddress Ip;
#endif
 
 
//  /home/bvandepo/.arduino15/packages/esp8266/hardware/esp8266/2.3.0-rc2/libraries/ESP8266WiFi/src/ESP8266WiFi.h
//  /home/bvandepo/.arduino15/packages/esp8266/hardware/esp8266/2.3.0-rc2/cores/esp8266/IPAddress.h
 
//////////////////////////////////////////
void Debug(char * msg)
{
#if 1
    Serial.print(msg);
#endif
}
//////////////////////////////////////////
unsigned long computeDeltaTime(unsigned long  time_begin){
    unsigned long time_current;
    unsigned long time_delta;
    time_current=micros();
    if (time_current>time_begin)
        time_delta=time_current-time_begin;
    else //in case micros has rolled over 2^32, may happen approx. once each hour (3600000000us)
        time_delta=time_current-(time_begin-(unsigned long )4294967296);
    return time_delta;
}
//////////////////////////////////////////  
#define INACTIVE 0
#define SHORT_PRESS_DURATION_MIN_US 500000
#define SHORT_PRESS_DURATION_MAX_US 1000000
#define SHORT_PRESS 1
#define LONG_PRESS_DURATION_MIN_US 1500000
#define LONG_PRESS_DURATION_MAX_US 2000000
#define LONG_PRESS 2
//longer than LONG_PRESS_DURATION_MAX_US 
#define CONTINUOUS_LONG_PRESS 3
#define PRESSED 4
#define STOP_CONTINUOUS_LONG_PRESS 5
//////////////////////////////////////////  
class Button{
public:
    ////////////
    int fsm_state;
    int active_state;
    int pin;
    char *name;
    unsigned long time_begin;
    unsigned long duration; //for the current action
    ////////////
    Button(int pin_init,char * name_init, int active_state_init){
        pin=pin_init;
        name=name_init;
        active_state=active_state_init;
        if (active_state==0)
            pinMode(pin, INPUT_PULLUP);
        else
            pinMode(pin, INPUT); //_PULLDOWN not available, the pull down has to be attached physically to the pin
        fsm_state=INACTIVE; //TODO manage the case when the button is already active at startup....
    }
    ////////////
    void loop(){
        unsigned long time_delta=computeDeltaTime(time_begin);
        switch(fsm_state){
        case CONTINUOUS_LONG_PRESS:
            Debug("Button ");       Debug(name);      Debug(" is CONTINUOUS_LONG_PRESS        ");
            if (digitalRead(pin)!=active_state)  {
                fsm_state=STOP_CONTINUOUS_LONG_PRESS;
            }
            break;
        case PRESSED:
            Debug("Button ");       Debug(name);      Debug(" is PRESSED                      ");
            //check if the button is being realeassed
            if (digitalRead(pin)!=active_state)  {
                if (time_delta<SHORT_PRESS_DURATION_MIN_US)
                    fsm_state=INACTIVE; //may be a parasite pulse
                else if ( (time_delta>=SHORT_PRESS_DURATION_MIN_US) && (time_delta<=SHORT_PRESS_DURATION_MAX_US))
                    fsm_state=SHORT_PRESS;
                else if ( (time_delta>=LONG_PRESS_DURATION_MIN_US) && (time_delta<=LONG_PRESS_DURATION_MAX_US))
                    fsm_state=LONG_PRESS;
                //else  longer... the realesed is treated in fsm_state=CONTINUOUS_LONG_PRESS
            }
            else if (time_delta>LONG_PRESS_DURATION_MAX_US)
                fsm_state=CONTINUOUS_LONG_PRESS;
            break;
        case SHORT_PRESS:
            Debug("Button ");       Debug(name);      Debug(" is SHORT_PRESS  ");
            break;
        case LONG_PRESS:
            Debug("Button ");       Debug(name);      Debug(" is LONG_PRESS                   ");
            break;
        case STOP_CONTINUOUS_LONG_PRESS:
            Debug("Button ");       Debug(name);      Debug(" is STOP_CONTINUOUS_LONG_PRESS   ");
            break;
        case INACTIVE:
        default:
            Debug("Button ");       Debug(name);      Debug(" is INACTIVE                     ");
            //check if the button is being pressed
            if (digitalRead(pin)==active_state) {
                fsm_state=PRESSED;
                time_begin=micros();
            }
            break;
        }
    }
    ////////////
    bool isPressed(){
        return  (fsm_state==PRESSED);
        //this does not indicate that the button is currently pressed but that the fsm is in the pressed state. The button can be pressed and
        //the fsm be in one of these states:  || (fsm_state==CONTINUOUS_LONG_PRESS) || (fsm_state==SHORT_PRESS) || (fsm_state==LONG_PRESS) );
    }
    ////////////
    bool isShortPressed(){
        if (fsm_state==SHORT_PRESS){
            fsm_state=INACTIVE;
            return true;
        }else
            return false;
    }
    ////////////
    bool isLongPressed(){
        if (fsm_state==LONG_PRESS){
            fsm_state=INACTIVE;
            return true;
        }else
            return false;
    }
    ////////////
    bool isContinuousLongPressed(){
        return (fsm_state==CONTINUOUS_LONG_PRESS ); //don't change the state of the button
    }
    ////////////
    bool isStoppedContinuousLongPressed(){
        if (fsm_state==STOP_CONTINUOUS_LONG_PRESS){
            fsm_state=INACTIVE;
            return true;
        }else
            return false;
    }
};
//////////////////////////////////////////
Button buttonOpen(BUTTON_OPEN,"BUTTON_OPEN",0);
Button buttonClose(BUTTON_CLOSE,"BUTTON_CLOSE",0);
//////////////////////////////////////////
class SimpleInput{
public:
    ////////////
    int pin;
    char *name;
    int active_state;
    ////////////
    SimpleInput(int pin_init,char * name_init, int active_state_init){
        pin=pin_init;
        name=name_init;
        active_state=active_state_init;
        if (active_state==0)
            pinMode(pin, INPUT_PULLUP);
        else
            pinMode(pin, INPUT); //_PULLDOWN not available, the pull down has to be attached physically to the pin
    }
    ////////////
    bool isActive(){
        Debug(name);
        if (digitalRead(pin)==active_state)  {
            Debug(" input is ACTIVE\n");
            return true;
        }else{
            Debug(" input is INACTIVE\n");
            return false;
        }
    }
    ////////////
};
//////////////////////////////////////////
SimpleInput laserSensor(LASER_SENSOR,"LASER_SENSOR",0);
//////////////////////////////////////////
#define RELAY_LIGHT_OFF 1
#define RELAY_LIGHT_ON  0
 
#define DURATION_LIGHT_PULSE 500000
class LightPulseSwitch{
public:
    ////////////
    int pin;
    int state;
    unsigned long time_begin;
    ////////////
    LightPulseSwitch(int pin_init){
        pin=pin_init;
        digitalWrite(pin,RELAY_LIGHT_OFF);
        pinMode(pin, OUTPUT);
        state=RELAY_LIGHT_OFF;
    }
    ////////////
    void commute(){
        if (state==RELAY_LIGHT_OFF){
            Debug("commute RELAY_LIGHT_ON");
            time_begin=micros();
            state=RELAY_LIGHT_ON;
            digitalWrite(pin,RELAY_LIGHT_ON);
        }
    }
    ////////////
    void loop(){
        if (state==RELAY_LIGHT_ON){
            unsigned long time_delta=computeDeltaTime(time_begin);
            if (time_delta>=DURATION_LIGHT_PULSE)  {
                Debug("commute RELAY_LIGHT_OFF");
                state=RELAY_LIGHT_OFF;
                digitalWrite(pin,RELAY_LIGHT_OFF);
            }
        }
    }
};
//////////////////////////////////////////
LightPulseSwitch light(RELAY_LIGHT);
//////////////////////////////////////////
#define WAITING 0
#define OPENING 1
#define CLOSING 2
#define OPENED 3
#define CLOSED 4
 
#define DURATION_OPEN_US 60000000
#define DURATION_CLOSE_US DURATION_OPEN_US
#define DURATION_OPEN_SMALL_US 20000000
#define DURATION_CLOSE_SMALL_US (DURATION_CLOSE_US-DURATION_OPEN_SMALL_US)
#define RELAY_DOOR_OFF 1
#define RELAY_DOOR_ON  0
 
class Door{
public:
    ////////////
    int pin_open;
    int pin_close;
    unsigned long time_begin;
    unsigned long duration; //for the current action
    int fsm_state;
    ////////////
    Door( int pin_open_init, int pin_close_init)  {
        pin_open= pin_open_init;
        pin_close=pin_close_init;
        digitalWrite(pin_open,RELAY_DOOR_OFF);
        digitalWrite(pin_close,RELAY_DOOR_OFF);
        pinMode(pin_open, OUTPUT);
        pinMode(pin_close, OUTPUT);
        fsm_state=WAITING;
    }
    ////////////
    bool isOpening(){
        return (fsm_state==OPENING);
    }
    ////////////
    bool isClosing(){
        return (fsm_state==CLOSING);
    }
    ////////////
    bool isMoving(){
        return ( (fsm_state==OPENING) || (fsm_state==CLOSING));
    }
    ////////////
    void open(long int duration_init){
        Debug("open\n");
        time_begin=micros();
        duration=duration_init;
        fsm_state=OPENING;
        digitalWrite(pin_close,RELAY_DOOR_OFF);
        delay(100); //let time for the first relay to switch off
        digitalWrite(pin_open, RELAY_DOOR_ON);
    }
    ////////////
    void close(long int duration_init){
        Debug("close\n");
        time_begin=micros();
        duration=duration_init;
        fsm_state=CLOSING;
        digitalWrite(pin_open, RELAY_DOOR_OFF);
        delay(100); //let time for the first relay to switch off
        digitalWrite(pin_close,RELAY_DOOR_ON);
    }
    ////////////
    void pause(){
        Debug("pause\n");
        time_begin=micros();
        fsm_state=WAITING;
        digitalWrite(pin_open, RELAY_DOOR_OFF);
        digitalWrite(pin_close,RELAY_DOOR_OFF);
    }
    ////////////
    void loop(){
        unsigned long time_delta=computeDeltaTime(time_begin);
        switch (fsm_state){
        case OPENED:
        case CLOSED:
        case WAITING:
        default:
            Debug("waiting\n");
            digitalWrite(pin_open, RELAY_DOOR_OFF);
            digitalWrite(pin_close,RELAY_DOOR_OFF);
            break;
        case CLOSING:
            if (time_delta<duration) {
                Debug("closing");
                char msg[15];
                snprintf(msg,14," %d / %d s\n",time_delta/1000000,duration/1000000);
                Debug(msg);
            }
            else {
                Debug("closed\n");
                fsm_state=CLOSED;
            }
            break;
        case OPENING:
            if (time_delta<duration)  {
                Debug("opening");
                char msg[15];
                snprintf(msg,14," %d / %d s\n",time_delta/1000000,duration/1000000);
                Debug(msg);
            }
            else  {
                Debug("opened\n");
                fsm_state=OPENED;
            }
            break;
        }
    }
    ////////////
};
//////////////////////////////////////////
Door door(RELAY_OPEN,RELAY_CLOSE);
//////////////////////////////////////////
#ifdef TRANSMITOVERWIFI
void sendMessage(byte message[]) {
    //sprintf((char*)message,"Hello ca va la?");
    udp.beginPacket(Ip, 10000);
    udp.write(message, strlen((char*)message));
    udp.endPacket();
}
#endif
//////////////////////////////////////////
int getMessage(byte message[], int maxByte){
    int cb = udp.parsePacket();
    if (cb==0) return 0; //no dataavailable, quit
    if (cb>maxByte) cb=maxByte; //don't overrun the buffer, the remaining part of the message WILL BE LOST!!
    // We've received a packet, read the data from it
    udp.read(message, cb); // read the packet into the buffer
    message[cb]=0; //add a 0 after the content in the buffer
    return cb;
}
//////////////////////////////////////////
#define BUFFER_RX_MAX 100
#define ERROR -1
#define NOTHING 0
#define OPENTHEDOOR 1
#define CLOSETHEDOOR 2
#define STOPTHEDOOR 3
#define SWITCHTHELIGHT 4
#define STARTING 5
#define WAITINGFORCONNECTION 6
#define CONNECTED 7
 
class Communication{
public:
    int state; //last message received
    byte message[BUFFER_RX_MAX+1]; //+1 to add an additional 0 after the received bytes to ensure that the string is correctly finished, even if the sender sent some errors
    ////////////
    Communication()  {
        state=STARTING;
    }
    ////////////
    void loop(){
        //doc at https://www.arduino.cc/en/Reference/WiFiStatus
        if (state==STARTING){
            //Wifi Configuration
            Serial.println ( "Wifi Configuration" );
#ifdef TRANSMITOVERWIFI
            Ip.fromString(ip);
#endif
            WiFi.begin ( ssid, password );
            // Wait for connection
            state=WAITINGFORCONNECTION;
        } else if (state==WAITINGFORCONNECTION){
            if ( WiFi.status() != WL_CONNECTED ) {
                Serial.print ( "WAITINGFORCONNECTION\n" );
            }else{
                state=CONNECTED;
            }
        } else if (state==CONNECTED){
            Serial.println ( "" );
            Serial.print ( "Connected to " );
            Serial.println ( ssid );
            Serial.print ( "Local IP address: " );
            Serial.println ( WiFi.localIP() );
            Serial.println("Starting UDP socket");
            udp.begin(localPort);
            Serial.print("Local port: ");
            Serial.println(udp.localPort());
            state=NOTHING;
        }
        else{
            if ( WiFi.status()==WL_CONNECTION_LOST){
                Serial.print ( "WL_CONNECTION_LOST\n" );
                state=STARTING;
            } else if ( WiFi.status()==WL_DISCONNECTED){
                Serial.print ( "WL_DISCONNECTED\n" );
                state=STARTING;
            } else{
 
                int n=getMessage(message, BUFFER_RX_MAX);
                if (n==0)
                    Debug(".");
                else{
                    Debug("packet received, length=");
                    char msg[11];
                    snprintf(msg,10,"%d",n);
                    Debug(msg);
                    Debug(", content= ");
                    Debug((char*)message);
                    if (strcmp((char*)message,"OpenTheDoorCompletelyPlease")==0){
                        state=OPENTHEDOOR;
                        Debug(" -> Open The Door\n");
                    }
                    else if (strcmp((char*)message,"CloseTheDoorCompletelyPlease")==0){
                        state=CLOSETHEDOOR;
                        Debug(" -> Close The Door\n");
                    }
                    else if (strcmp((char*)message,"StopTheDoor")==0){
                        state=STOPTHEDOOR;
                        Debug(" -> StopTheDoor\n");
                    }
                    else if (strcmp((char*)message,"SwitchTheLight")==0){
                        state=SWITCHTHELIGHT;
                        Debug(" -> SwitchTheLight\n");
                    }
                    else{
                        state=ERROR;
                        Debug(" -> Error\n");
                    }
                }
            }
        }
    }
    ////////////
    bool isOpenTheDoor(){
        if (state==OPENTHEDOOR){
            state=NOTHING;
            return true;
        }else
            return false;
    }
    ////////////
    bool isCloseTheDoor(){
        if (state==CLOSETHEDOOR){
            state=NOTHING;
            return true;
        }else
            return false;
    }
    ////////////
    bool isStopTheDoor(){
        if (state==STOPTHEDOOR){
            state=NOTHING;
            return true;
        }else
            return false;
    }
    ////////////
    bool isSwitchTheLight(){
        if (state==SWITCHTHELIGHT){
            state=NOTHING;
            return true;
        }else
            return false;
    }
    ////////////
    bool isError(){
        if (state==ERROR){
            state=NOTHING;
            return true;
        }else
            return false;
    }
    ////////////
};
//////////////////////////////////////////
Communication communication;
//////////////////////////////////////////
//Be carefull, The Watchdog resets every 4 seconds if the loop function is not finished
//////////////////////////////////////////
void test_buttons_and_relays()
{
    int b_o,b_c;
    Serial.print( "test_buttons_and_relays(): " );
    b_o=digitalRead(BUTTON_OPEN);
    b_c=digitalRead(BUTTON_CLOSE);
    digitalWrite(RELAY_OPEN, b_o);
    digitalWrite(RELAY_CLOSE,b_c);
    Serial.print( "b_o: " );
    Serial.print(b_o);
    Serial.print( ", b_c: " );
    Serial.println(b_c);
    delay(100);
}
//////////////////////////////////////////
void setup() {
    //serial communication setup for debugging
    Serial.begin ( 115200 );
    delay(100);
    Serial.println ( "Serial Configuration Completed" );
    Serial.println( "Compiled: " __DATE__ ", " __TIME__ ", " __VERSION__);
    //GPIOs Configuration
    Serial.println ( "GPIOs Configuration (some already done through constructors)" );
    //Wifi Configuration done in first iterations of communication.loop
};
//////////////////////////////////////////
// the loop function runs over and over again forever
void loop() {
    //Serial.println(micros());
    //test_buttons_and_relays();
 
    //FSM Loops for buttons and communication have to be executed before using the state
    buttonOpen.loop();
    buttonClose.loop();
 
    communication.loop();
 
    if (laserSensor.isActive()){
        if( buttonOpen.isShortPressed())
            door.open(DURATION_OPEN_SMALL_US);
        if( buttonOpen.isLongPressed() || communication.isOpenTheDoor())
            door.open(DURATION_OPEN_US);
        if( buttonOpen.isContinuousLongPressed())
            door.open(DURATION_OPEN_US);
        if( buttonClose.isShortPressed())
            door.close(DURATION_CLOSE_SMALL_US);
        if( buttonClose.isLongPressed() || communication.isCloseTheDoor())
            door.close(DURATION_CLOSE_US);
        if( buttonClose.isContinuousLongPressed())
            door.close(DURATION_CLOSE_US);
    }
    else {
        //stop the door, there is an obstacle
        door.pause();
        //remove pending commands from buttons and communication to avoid unwanted starting when the laser sensor will be active again
        buttonOpen.isShortPressed();
        buttonOpen.isLongPressed();
        communication.isOpenTheDoor();
        buttonOpen.isContinuousLongPressed();
        buttonClose.isShortPressed();
        buttonClose.isLongPressed();
        communication.isCloseTheDoor();
        buttonClose.isContinuousLongPressed();
        Debug("Laser Barrier Sensor has detected an obstacle, the door is stopped\n");
    }
 
    if( buttonClose.isStoppedContinuousLongPressed() || buttonOpen.isStoppedContinuousLongPressed() || communication.isStopTheDoor())
        door.pause();
 
    if ( (door.isClosing() && buttonOpen.isPressed()) || (door.isOpening() && buttonClose.isPressed())  )
        door.pause();
 
    if (communication.isSwitchTheLight())
        light.commute();
 
    door.loop();
    light.loop();
 
    delay(100); //for debuging purposes, it slows the display
 
}
//////////////////////////////////////////

télécommande voiture pour marc

https://www.hackster.io/bryan_in_france/control-your-rc-car-with-your-android-tablet-acfe04

Carte marc Arduino D1 Mini

https://www.electro-info.ovh/premiers-pas-avec-arduino-d1-mini

https://www.aranacorp.com/fr/vue-densemble-du-microcontroleur-wemos-d1-mini/

Problème suite à upload

https://projetasgarddiy.fr/2018/05/31/flasher-wemos-d1-mini-avec-espeasy-mega/

https://projetasgarddiy.fr/2018/05/30/flasher-un-esp8266-nodemcu-avec-espeasy/

https://espeasy.readthedocs.io/en/latest/Reference/Flashing.html

sur cette page , ils parlent d'un fichier blank_4MB.bin a flasher pour remettre la carte en config initiale : https://letscontrolit.com/forum/viewtopic.php?p=57436

pour réparer: https://groups.google.com/g/openevse/c/yJ_PiVTAppo?pli=1