IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

Wemos - problème en sortie de sommeil


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    973
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 973
    Par défaut Wemos - problème en sortie de sommeil
    Bonjour à Tous

    J'expérimente une liaison MQTT ( Thingspeak)
    ( source : https://github.com/ni-c/ESPtemp/tree/main )
    avec un Wemos + BMP680 + DS18B20

    La programme se compile malgré tout mais avec plusieurs problèmes :

    1) il démarre, transmet les infos MQTT puis se met en sommeil (#define SLEEPTIME 30e6 => 30s) mais après il ne redémarre plus
    2) l'entrée ADC qui mesure la batterie ( R1 = 220k et R2 = 68k ) me donne en calcul 4.1v alors que l'entrée est branchée directement sur le 3.3v (?)
    3) J'ai branché l'alimentation du BMP680 sur une entrée GPIO15 ( D8) que je force à 1 via le setup par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    #ifndef BMP680_VCC_GPIO
    #define BMP680_VCC_GPIO 15 /*D6 *< VCC for BMP680 sensor */
    #endif
     
    .../...
    pinMode(BMP680_VCC_GPIO, OUTPUT);
    digitalWrite(BMP680_VCC_GPIO, HIGH);
    mais celle-ci reste désespérément à zéro

    Je mets ici le croquis complet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
     
    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <EEPROM.h>
    #include <ESP8266WebServer.h>
    #include <functional>
    #include <OneWire.h>
    #include <ArduinoOTA.h>
    #include <Arduino.h>
    #include <ArduinoJson.h>
    #include <Adafruit_Sensor.h>
    #include "Adafruit_BME680.h"
    #include <PubSubClient.h>
    #include <DallasTemperature.h>
    #include "config.h"
    #include <MQTT.h>
     
     
    char server[] = "mqtt3.thingspeak.com";
     
    //*******************************************************************
     
    #if DEBUG
    #define D_SerialBegin(...) Serial.begin(__VA_ARGS__)
    #define D_print(...) Serial.print(__VA_ARGS__)
    #define D_write(...) Serial.write(__VA_ARGS__)
    #define D_println(...) Serial.println(__VA_ARGS__)
    #define D_printf(...) Serial.printf(__VA_ARGS__)
    #define D_timestamp() Serial.printf("[%lu] ", millis())
    #else
    #define D_SerialBegin(bauds)
    #define D_print(...)
    #define D_write(...)
    #define D_println(...)
    #define D_printf(...)
    #define D_timestamp()
    #endif
     
    #ifndef ESPTEMP_VERSION
    #define ESPTEMP_VERSION "v1.1" /**< The current version of the ESPtemp firmware*/
    #endif
     
    #ifndef BMP680_VCC_GPIO
    #define BMP680_VCC_GPIO 15 /*D6 *< VCC for BMP380 sensor */
    #endif
     
    #ifndef SLEEPTIME
    #define SLEEPTIME 30e6 /**< Time in deepsleep */
    #endif
     
    #ifndef SLEEPTIME_EXTENDED
    #define SLEEPTIME_EXTENDED 21600e6 /**< Temps en sommeil profond si une erreur s'est produite en essayant de se connecter au wifi (pour éviter le drainage de la batterie).) */
    #endif
     
    #ifndef DEBUG
    #define DEBUG 0 /**< Régler à 1 pour déboguer en série */
    #endif
     
    const byte  ONE_WIRE_BUS = 12;  // D6 pin used for Temperature sensor bus  
    const byte Board_SDA = 5;
    const byte Board_SCL = 4;  
     
    unsigned long startMillis;
     
    float humidity;
    float temperature;
    float batteryVoltage;
    int8_t batteryPercentage;
    uint_fast16_t adcValue;
    char error[15];
     
    uint8_t wifiRetries = 0;
    uint8_t ledState = HIGH;
     
    bool isBMP680ready = false;
    bool isADCReady = false;
    bool isWifiStarted = false;
    bool isWifiReady = false;
    bool isRegularWifi = false;
    bool isMQTTStarted = false;
    bool isMQTTReady = false;
    bool isRtcValid = false;
    bool isOTAEnabled = false;
     
    //*********** Init **************************
    WiFiClient  wifiClient;
    ESP8266WebServer serverAP(80);
    PubSubClient pubSubclient(wifiClient);
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    Adafruit_BME680 bmp;
     
    struct
    {
        uint32_t crc32;    // 4 bytes
        uint8_t channel;   // 1 byte,   5 in total
        uint8_t ap_mac[6]; // 6 bytes, 11 in total
    } rtcData;
     
    // the CRC routine
    uint32_t calculateCRC32(const uint8_t *data, size_t length)
    {
        uint32_t crc = 0xffffffff;
        while (length--)
        {
            uint8_t c = *data++;
            for (uint32_t i = 0x80; i > 0; i >>= 1)
            {
                bool bit = crc & 0x80000000;
                if (c & i)
                {
                    bit = !bit;
                }
     
                crc <<= 1;
                if (bit)
                {
                    crc ^= 0x04c11db7;
                }
            }
        }
     
        return crc;
    }
     
    //*******************************************
    void setup() {
       D_SerialBegin(115200);
       Serial.println( "Start" );
       Wire.begin(Board_SDA,Board_SCL); 
     
       D_println();
       D_timestamp();
       D_printf("CpuFreqMHz: %u MHz\n", ESP.getCpuFreqMHz());
       D_timestamp();
       D_print("MAC Address: ");
       D_println(WiFi.macAddress()); 
     
        // *******
        pinMode(ONE_WIRE_BUS,INPUT_PULLUP); 
        sensors.begin();    // ------- DS18B20 Temperature sensor --------- 
     
        pinMode(BMP680_VCC_GPIO, OUTPUT);
        digitalWrite(BMP680_VCC_GPIO, HIGH);
        bmp.begin();
     
        // Wait minimum sampling period
        startMillis = millis();
     
        if (ESP.rtcUserMemoryRead(0, (uint32_t *)&rtcData, sizeof(rtcData)))
        {
            // Calculez le CRC de ce que nous venons de lire dans la mémoire du RTC, mais sautez les 4 premiers octets car c'est la somme de contrôle elle-même.
            uint32_t crc = calculateCRC32(((uint8_t *)&rtcData) + 4, sizeof(rtcData) - 4);
            if (crc == rtcData.crc32)
            {
                isRtcValid = true;
            }
        }
     
       int status = WL_IDLE_STATUS; // Set temporary Wi-Fi status
     
     
    }
     
     
    //**********************************************
    void loop() {
     
        /*
         * Step 1:
         * Read temperature and humidity from HTU21DF
         */
        if (!isBMP680ready)
        {
            // Read sensors
    		humidity = bmp.readHumidity();
            temperature = bmp.readTemperature();
     
            D_timestamp();
            D_println("BMP680 Reading ready");
            D_timestamp();
            D_printf("Temperature: %.1f, Humidity: %.1f", temperature, humidity);
            D_println();
     
            isBMP680ready = true;
            digitalWrite(BMP680_VCC_GPIO, LOW);
        } 
     
         /*
         * Step 2:
         * Start WiFi connection
         */
        if (!isWifiStarted)
        {
            D_timestamp();
            D_println("Démarrage du WiFi");
     
            WiFi.forceSleepBegin();
            delay(1);
            WiFi.forceSleepWake();
            delay(1);
     
            // Désactivez la persistance du WiFi.  L'ESP8266 ne chargera pas et n'enregistrera pas inutilement les paramètres WiFi dans la mémoire flash..
            WiFi.persistent(false);
     
            // Affichez la connexion WiFi
            WiFi.mode(WIFI_STA);
            WiFi.config(ip, dns, gateway, subnet);
            //WiFi.hostname(MQTT_CLIENT);
     
            if (isRtcValid)
            {
                // The RTC data was good, make a quick connection
                D_timestamp();
                D_println("RTC OK, initier une connexion rapide");
                WiFi.begin(WLAN_SSID, WLAN_PASSWD, rtcData.channel, rtcData.ap_mac, true);
                isRegularWifi = false;
            }
            else
            {
                // Les données RTC n'étaient pas valides, il faut donc établir une connexion régulière.
                D_timestamp();
                D_println("RTC BAD, initier une connexion régulière");
                WiFi.begin(WLAN_SSID, WLAN_PASSWD);
                isRegularWifi = true;
            }
     
            isWifiStarted = true;
        }
     
        /*
         * Step 3:
         * Read battery voltage from ADC
         */
        if (!isADCReady)
        {
            adcValue = analogRead(A0);
            isADCReady = true;
            batteryVoltage = adcValue * 0.004;
            batteryPercentage = (int8_t)((adcValue - 863) / 1.6);
     
            if (batteryVoltage <= 3.3)
            {
                D_timestamp();
                D_println("Batterie faible. Sommeil profond.");
                ESP.deepSleep(0);
            }
     
            D_timestamp();
            D_println("ADC Reading ready");
            D_timestamp();
            D_printf("Battery voltage: %.1f V, Battery Percentage: %i", batteryVoltage, batteryPercentage);
            D_println();
        }
     
        /*
         * Step 4:
         * Si le WiFi est prêt : Initialiser le client MQTT
         * OR
         * Démarrage de la boucle d'attente OTA si OTA_ENABLE_GPIO est tiré vers le HAUT
         */
        if (!isWifiReady)
        {
            if (WiFi.status() == WL_CONNECTED)
            {
                D_timestamp();
                D_print("WiFi connected (");
                D_print(WiFi.localIP());
                D_println(")");
                pubSubclient.setServer(server, 1883);
                isWifiReady = true;
     
                if (isOTAEnabled)
                {
                    D_timestamp();
                    D_println("Démarrage de l'OTA");
                    ArduinoOTA.setHostname(MQTT_CLIENT);
                    ArduinoOTA.begin();
                }
            }
            else if (((millis() - startMillis) > 5000) && (!isRegularWifi))
            {
                // Essayer une connexion régulière
                D_timestamp();
                D_println("Délai d'attente pour le WiFi, réessayer une connexion régulière");
                WiFi.disconnect();
                delay(5);
                WiFi.forceSleepBegin();
                delay(1);
                WiFi.forceSleepWake();
                delay(1);
                WiFi.begin(WLAN_SSID, WLAN_PASSWD);
                isRtcValid = false;
                isRegularWifi = true;
            }
            else if ((millis() - startMillis) > 20000)
            {
                // Échec de la connexion Wifi, mise en veille prolongée
                WiFi.disconnect(true);
                D_timestamp();
                D_println("Échec de la connexion au réseau WiFi, mise en veille prolongée");
                ESP.deepSleep(SLEEPTIME_EXTENDED, WAKE_RF_DISABLED);
            }
        }   
     
        /*
         * Step 5:
         * Connect to MQTT broker
         */
        else if (!isMQTTStarted)
        {
            if (!pubSubclient.connected())
            {
                D_timestamp();
                D_println("Connexion au courtier MQTT");
                pubSubclient.connect(MQTT_CLIENT, MQTT_USER, MQTT_PASSWORD);
                delay(10);
            }
            else
            {
                D_timestamp();
                D_println("MQTT connected");
    			//Serial.println( "Connected with Client ID:  " + String(MQTT_CLIENT) + " User "+ String(MQTT_USER) + " Pwd "+String(MQTT_PASSWORD) );
                isMQTTStarted = true;
            }
        }
     
         /*
         * Step 5:
         * Si tous les relevés sont effectués et que le WiFi est prêt, transmettez les données MQTT.
         */
        if (isMQTTStarted && isWifiReady && isBMP680ready && !isMQTTReady)
        {
            DynamicJsonDocument doc(1024);
            doc["temperature"] = (int)roundf(10 * temperature) / 10.0;
            doc["humidity"] = (int)roundf(10 * humidity) / 10.0;
            doc["batteryVoltage"] = (int)roundf(100 * batteryVoltage) / 100.0;
            //doc["batteryPercentage"] = batteryPercentage;
            //doc["firmwareVersion"] = ESPTEMP_VERSION;
     
            char json[128];
            serializeJson(doc, json);
     
            D_timestamp();
            D_print("MQTT Publish: ");
            D_print(MQTT_TOPIC);
            D_print(" ");
            D_println(json);
     
            pubSubclient.loop();
    		String topicString ="channels/" + String(MQTT_TOPIC) + "/publish";
    		String dataString = String("field1=" + String(temperature) + "&field2=" + String(humidity) + "&field3=" + String(batteryVoltage));
            pubSubclient.publish(topicString.c_str(),dataString.c_str());
            delay(100);
     
            isMQTTReady = true;
        }
     
        if (!isOTAEnabled)
        {
            /*
             * Step 6:
             * Sauvegarde des données WiFi dans le RTC et retour au sommeil profond
             */
            if (isMQTTReady)
            {
                // Écriture des informations sur la connexion actuelle dans le RTC
                if (!isRtcValid)
                {
                    rtcData.channel = WiFi.channel();
                    memcpy(rtcData.ap_mac, WiFi.BSSID(), 6); // Copy 6 bytes of BSSID (AP's MAC address)
                    rtcData.crc32 = calculateCRC32(((uint8_t *)&rtcData) + 4, sizeof(rtcData) - 4);
                    ESP.rtcUserMemoryWrite(0, (uint32_t *)&rtcData, sizeof(rtcData));
                }
     
                WiFi.disconnect(true);
     
                D_timestamp();
                D_println("C'est fait, je vais dormir");
                ESP.deepSleep(SLEEPTIME, WAKE_RF_DISABLED);
            }
            else if ((millis() - startMillis) > 25000)
            {
                WiFi.disconnect(true);
                D_timestamp();
                D_println("TEMPS D'INTERRUPTION, dormir");
                ESP.deepSleep(SLEEPTIME, WAKE_RF_DISABLED);
            }
        }
     
    }
    Si vous avez quelques conseils ....je suis preneur ..

  2. #2
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    973
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 973
    Par défaut
    1) il démarre, transmet les infos MQTT puis se met en sommeil (#define SLEEPTIME 30e6 => 30s) mais après il ne redémarre plus
    Le problème est résolu par le bouclage de GPIO0 sur D0 qui permet de redémarrer l'µC

    2) l'entrée ADC qui mesure la batterie ( R1 = 220k et R2 = 68k ) me donne en calcul 4.1v alors que l'entrée est branchée directement sur le 3.3v (?)
    Logique semble-t-il si on considère la particularité de l'ESP8266 , l'entrée ADC (A0) n’accepte que 1V max pour 1023
    comme l'entrée était à 3.3v il indiquait d'après le log => le max soit 4.1V
    j'ai pour l'instant simuler en forçant la lecture adcValue = 1000;
    et çà indique correctement 4.0v

    3) J'ai branché l'alimentation du BMP680 sur une entrée GPIO15 ( D8) que je force à 1 via le setup par :
    Là je cherche mais ne trouve pas la raison

  3. #3
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 638
    Par défaut
    Bonjour,

    J'ai branché l'alimentation du BMP680 sur une entrée GPIO15 ( D8) ...
    La phrase qui annonce la déclaration n'est pas en phase avec celle-ci au niveau de l'identification des broches. D'ici là à ce qu'un changement de broche règle le problème...

    #define BMP680_VCC_GPIO 15 /* D6 *< VCC for BMP680 sensor */
    Salutations

  4. #4
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    973
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 973
    Par défaut
    Bonjour Guesset

    La phrase qui annonce la déclaration n'est pas en phase avec celle-ci au niveau de l'identification des broches. D'ici là à ce qu'un changement de broche règle le problème..
    c'est exact , je l'ai corrigée mais malgré cela et après plusieurs tentatives çà a fonctionné mais de façon aléatoire
    je suis revenu à une alimentation directement sur 3.3v
    ce n'est pas glorieux mais je n'ai pas trouvé d'explication, le capteur concerné ( BMP680) était ( je l'ai changé depuis) en I2C
    c'était peut-être incompatible avec ce type de raccordement

  5. #5
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    973
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 973
    Par défaut
    Bonjour à tous ,

    J'ai corrigé les erreurs mais je souhaiterai au final faire une dernière modification software si c'est possible
    "avoir la possibilité au bout quelques minutes d'effectuer un "reset à chaud" de l'ESP8266 à partir du croquis ci-joint

    car le sommeil profond est recommandé à juste titre en cas de faible batterie,
    en cas de perte de Wifi, le programme devrait pouvoir relancer une reconnexion automatique au bout de quelques minutes
    et ce n'est pas la cas ici

    comment puis-je faire ?
    j'ai lu qu'il existait une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void(* resetFunc) (void) = 0;
    comment la mettre "en musique" svp dans ce croquis ?
    il fonctionne, et envoie les données toutes les 5 mn
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
     
    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>
    #include <functional>
    #include <OneWire.h>
    #include <ArduinoOTA.h>
    #include <Arduino.h>
    #include <PubSubClient.h>
    #include <DallasTemperature.h>
    #include "config.h"
     
    #include "DHTesp.h"
    #include <MQTT.h>
     
     
    char server[] = "mqtt3.thingspeak.com";
     
    //*******************************************************************
     
    #if DEBUG
    #define D_SerialBegin(...) Serial.begin(__VA_ARGS__)
    #define D_print(...) Serial.print(__VA_ARGS__)
    #define D_write(...) Serial.write(__VA_ARGS__)
    #define D_println(...) Serial.println(__VA_ARGS__)
    #define D_printf(...) Serial.printf(__VA_ARGS__)
    #define D_timestamp() Serial.printf("[%lu] ", millis())
    #else
    #define D_SerialBegin(bauds)
    #define D_print(...)
    #define D_write(...)
    #define D_println(...)
    #define D_printf(...)
    #define D_timestamp()
    #endif
     
    #ifndef ESPTEMP_VERSION
    #define ESPTEMP_VERSION "v1.1" /**< The current version of the ESPtemp firmware*/
    #endif
     
    #ifndef SLEEPTIME
    #define SLEEPTIME 300e6 /**< Time in deepsleep */
    #endif
     
    #ifndef SLEEPTIME_EXTENDED
    #define SLEEPTIME_EXTENDED 21600e6 /**< Temps en sommeil profond si une erreur s'est produite en essayant de se connecter au wifi (pour éviter le drainage de la batterie).) */
    #endif
     
    #ifndef DEBUG
    #define DEBUG 0 /**< Régler à 1 pour déboguer en série */
    #endif
     
    const byte  ONE_WIRE_BUS = 12;  // D6 pin used for Temperature sensor bus
    unsigned long startMillis;
     
    float humidity;
    float temperature;
    float piscine;
    float batteryVoltage;
    int8_t batteryPercentage;
    uint_fast16_t adcValue;
    char error[15];
     
     
    uint8_t wifiRetries = 0;
     
    bool isDS18B20ready = false;
    bool isDHTready = false;
    bool isADCReady = false;
    bool isWifiStarted = false;
    bool isWifiReady = false;
    bool isRegularWifi = false;
    bool isMQTTStarted = false;
    bool isMQTTReady = false;
    bool isRtcValid = false;
    bool isOTAEnabled = false;
     
    //*********** Init **************************
    WiFiClient  wifiClient;
    ESP8266WebServer serverAP(80);
    PubSubClient pubSubclient(wifiClient);
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    DHTesp dht;
     
     
    struct
    {
        uint32_t crc32;    // 4 bytes
        uint8_t channel;   // 1 byte,   5 in total
        uint8_t ap_mac[6]; // 6 bytes, 11 in total
    } rtcData;
     
    // the CRC routine
    uint32_t calculateCRC32(const uint8_t *data, size_t length)
    {
        uint32_t crc = 0xffffffff;
        while (length--)
        {
            uint8_t c = *data++;
            for (uint32_t i = 0x80; i > 0; i >>= 1)
            {
                bool bit = crc & 0x80000000;
                if (c & i)
                {
                    bit = !bit;
                }
     
                crc <<= 1;
                if (bit)
                {
                    crc ^= 0x04c11db7;
                }
            }
        }
     
        return crc;
    }
     
    //*******************************************
    void setup() {
       D_SerialBegin(115200);
       Serial.println( "Start" );
     
       /*    
       D_println();
       D_timestamp();
       D_printf("CpuFreqMHz: %u MHz\n", ESP.getCpuFreqMHz());
       D_timestamp();
       D_print("MAC Address: ");
       D_println(WiFi.macAddress()); 
       */
     
        // *** DS18B20 Temperature sensor ****
        pinMode(ONE_WIRE_BUS,INPUT_PULLUP); 
        sensors.begin();     
     
        // *** AM2301A Temperature sensor ****
        dht.setup(13, DHTesp::DHT22); // D7 Connect DHT sensor to GPIO 13
     
        // Wait minimum sampling period
        startMillis = millis();
     
        if (ESP.rtcUserMemoryRead(0, (uint32_t *)&rtcData, sizeof(rtcData)))
        {
            // Calculez le CRC de ce que nous venons de lire dans la mémoire du RTC, mais sautez les 4 premiers octets car c'est la somme de contrôle elle-même.
            uint32_t crc = calculateCRC32(((uint8_t *)&rtcData) + 4, sizeof(rtcData) - 4);
            if (crc == rtcData.crc32)
            {
                isRtcValid = true;
            }
        }
     
    }
     
     
    //**********************************************
    void loop() {
     
        /*
         * Step 0:
         * Read temperature from DS18B20
         */ 
        if (!isDS18B20ready)
        { 
           sensors.requestTemperatures(); 
           piscine = sensors.getTempCByIndex(0);
     
           D_timestamp();
           D_println("DS18B20 Reading ready");
           D_timestamp();
           D_printf("Piscine: %.1f", piscine);
           D_println();
     
           isDS18B20ready = true;
        }  
     
         /*
         * Step 1:
         * Read temperature and humidity from HTU21DF
         */
        if (!isDHTready)
        {
            humidity =  dht.getHumidity();       // Humidite Air  
            temperature = dht.getTemperature(); // temperature Air
     
            D_timestamp();
            D_println("AM2301A Reading ready");
            D_timestamp();
            D_printf("Temperature: %.1f, Humidity: %.1f ", temperature, humidity);
            D_println();
     
            isDHTready = true;
        }
     
         /*
         * Step 2:
         * Start WiFi connection
         */
        if (!isWifiStarted)
        {
            D_timestamp();
            D_println("Démarrage du WiFi");
     
            WiFi.forceSleepBegin();
            delay(1);
            WiFi.forceSleepWake();
            delay(1);
     
            // Désactivez la persistance du WiFi.  L'ESP8266 ne chargera pas et n'enregistrera pas inutilement les paramètres WiFi dans la mémoire flash..
            WiFi.persistent(false);
     
            // Affichez la connexion WiFi
            WiFi.mode(WIFI_STA);
            WiFi.config(ip, dns, gateway, subnet);
            //WiFi.hostname(MQTT_CLIENT);
     
            if (isRtcValid)
            {
                // The RTC data was good, make a quick connection
                D_timestamp();
                D_println("RTC OK, initier une connexion rapide");
                WiFi.begin(WLAN_SSID, WLAN_PASSWD, rtcData.channel, rtcData.ap_mac, true);
                isRegularWifi = false;
            }
            else
            {
                // Les données RTC n'étaient pas valides, il faut donc établir une connexion régulière.
                D_timestamp();
                D_println("RTC BAD, initier une connexion régulière");
                WiFi.begin(WLAN_SSID, WLAN_PASSWD);
                isRegularWifi = true;
            }
     
            isWifiStarted = true;
        }
     
        /*
         * Step 3:
         * Read battery voltage from ADC
         */
        if (!isADCReady)
        {
            adcValue = analogRead(A0); //<============
    		    //adcValue = 1022;  // <=== test
            batteryVoltage = adcValue * 0.00410; // 4.2v / 1023 = 0.00410
    		    batteryPercentage = (int8_t)((adcValue - 780) / 2.43); // 1023 - 780 = 243 pour 0 - 100% soit 4.2v à 3.2v
     
            if (batteryVoltage <= 3.3)
            {
                D_timestamp();
                D_println("Batterie faible. Sommeil profond.");
                ESP.deepSleep(0);
            }
     
            D_timestamp();
            D_println("ADC Reading ready");
            D_timestamp();
            D_printf("Battery voltage: %.1f V, Battery Percentage: %i", batteryVoltage, batteryPercentage);
            D_println();
            isADCReady = true;
        }
     
        /*
         * Step 4:
         * Si le WiFi est prêt : Initialiser le client MQTT
        */
        if (!isWifiReady)
        {
            if (WiFi.status() == WL_CONNECTED)
            {
                D_timestamp();
                D_print("WiFi connected (");
                D_print(WiFi.localIP());
                D_println(")");
                pubSubclient.setServer(server, 1883);
                isWifiReady = true;
     
                if (isOTAEnabled)
                {
                    D_timestamp();
                    D_println("Démarrage de l'OTA");
                    ArduinoOTA.setHostname(MQTT_CLIENT);
                    ArduinoOTA.begin();
                }
            }
            else if (((millis() - startMillis) > 5000) && (!isRegularWifi))
            {
                // Essayer une connexion régulière
                D_timestamp();
                D_println("Délai d'attente pour le WiFi, réessayer une connexion régulière");
                WiFi.disconnect();
                delay(5);
                WiFi.forceSleepBegin();
                delay(1);
                WiFi.forceSleepWake();
                delay(1);
                WiFi.begin(WLAN_SSID, WLAN_PASSWD);
                isRtcValid = false;
                isRegularWifi = true;
            }
            else if ((millis() - startMillis) > 20000)
            {
                // Échec de la connexion Wifi, mise en veille prolongée
                WiFi.disconnect(true);
                D_timestamp();
                D_println("Échec de la connexion au réseau WiFi, mise en veille prolongée");
                ESP.deepSleep(SLEEPTIME_EXTENDED, WAKE_RF_DISABLED);
            }
        }   
     
        /*
         * Step 5:
         * Connect to MQTT broker
         */
        else if (!isMQTTStarted)
        {
            if (!pubSubclient.connected())
            {
                D_timestamp();
                D_println("Connexion au courtier MQTT");
                pubSubclient.connect(MQTT_CLIENT, MQTT_USER, MQTT_PASSWORD);
                delay(10);
            }
            else
            {
                D_timestamp();
                D_println("MQTT connected");
    			      //Serial.println( "Connected with Client ID:  " + String(MQTT_CLIENT) + " User "+ String(MQTT_USER) + " Pwd "+String(MQTT_PASSWORD) );
                isMQTTStarted = true;
            }
        }
     
         /*
         * Step 5:
         * Si tous les relevés sont effectués et que le WiFi est prêt, transmettez les données MQTT.
         */
        if (isMQTTStarted && isWifiReady && isDHTready && !isMQTTReady  && isDS18B20ready)
        {
     
            D_timestamp();
            D_print("MQTT Publish: ");
            D_println(MQTT_TOPIC);
     
            pubSubclient.loop();
    	    	String topicString ="channels/" + String(MQTT_TOPIC) + "/publish";
    		    String dataString = String("field1=" + String(temperature) + "&field2=" + String(humidity) + "&field3=" + String(batteryPercentage) + "&field4=" + String(piscine));
            pubSubclient.publish(topicString.c_str(),dataString.c_str());
            delay(100);
     
            isMQTTReady = true;
        }
     
        if (!isOTAEnabled)
        {
            /*
             * Step 6:
             * Sauvegarde des données WiFi dans le RTC et retour au sommeil profond
             */
            if (isMQTTReady)
            {
                // Écriture des informations sur la connexion actuelle dans le RTC
                if (!isRtcValid)
                {
                    rtcData.channel = WiFi.channel();
                    memcpy(rtcData.ap_mac, WiFi.BSSID(), 6); // Copy 6 bytes of BSSID (AP's MAC address)
                    rtcData.crc32 = calculateCRC32(((uint8_t *)&rtcData) + 4, sizeof(rtcData) - 4);
                    ESP.rtcUserMemoryWrite(0, (uint32_t *)&rtcData, sizeof(rtcData));
                }
     
                WiFi.disconnect(true);
     
                D_timestamp();
                D_println("C'est fait, je vais dormir");
                ESP.deepSleep(SLEEPTIME, WAKE_RF_DISABLED);
     
            }
    		    else if ((millis() - startMillis) > 25000)
            {
                WiFi.disconnect(true);
                D_timestamp();
                D_println("TEMPS D'INTERRUPTION, dormir");
                ESP.deepSleep(SLEEPTIME, WAKE_RF_DISABLED);
            }
     
        }
     
    }
    Grand merci par avance

  6. #6
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 914
    Par défaut
    il suffit d'appeler ESP.restart(); quand vous voulez rebooter

    testez un truc comme cela (je n'ai pas d'ESP8266 sous la main pour tester)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    int decompte=5;
     
    void setup() {
      Serial.begin(115200);
    }
     
    void loop() {
     
      Serial.println(decompte--);
     
      if(decompte  <= 0){
        Serial.println("Reset.."); Serial.flush(); // flush pour s'assurer que le texte est envoyé avant le reboot
        ESP.restart();
      }
     
      delay(1000);
    }

  7. #7
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    973
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 973
    Par défaut
    il suffit d'appeler ESP.restart(); quand vous voulez rebooter
    Ok , merci Jay M je vais modifier pour incorporer çà dans le croquis

    J'ai une autre requête concernant le suivi de la tension batterie
    j'ai mis ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    if (!isADCReady)
        {
            adcValue = analogRead(A0); //<============
    		    //adcValue = 1022;  // <=== test
            batteryVoltage = adcValue * 0.00410; // 4.2v / 1023 = 0.00410
    		    batteryPercentage = (int8_t)((adcValue - 780) / 2.43); // 1023 - 780 = 243 pour 0 - 100% soit 4.2v à 3.2v
     
            if (batteryVoltage <= 3.3)
            {
                D_timestamp();
                D_println("Batterie faible. Sommeil profond.");
                D_printf("Battery voltage: %.1f V, Battery Percentage: %i", batteryVoltage, batteryPercentage);
                ESP.deepSleep(0);
            }
     
            D_timestamp();
            D_println("ADC Reading ready");
            D_timestamp();
            D_printf("Battery voltage: %.1f V, Battery Percentage: %i", batteryVoltage, batteryPercentage);
            D_println();
            isADCReady = true;
        }
    en espérant suivre la tension de ma batterie
    mais en mettent en service :
    - Tension batterie mesurée = 4,13v
    - % Batterie = 79%
    - Voltage = 1,1v (?) ( ce qui finit par me faire "Batterie faible" )

    Ma question :
    c'est bien 1023 octets pour 1v que l'on mesure à l'entrée A0 sur le ESP8266 ?
    aurais-je fait une bêtise dans mes calculs ?

  8. #8
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 914
    Par défaut
    l'ADC d'un ESP8266 est bien sur 10 bits, donc vous lisez une valeur entre 0 et 1023

    l'ADC en lui même ne sait traiter les valeurs que entre 0 et 1V mais les cartes du commerce incluent un pont diviseur de tension adapté à 3.3V ==> à voir si votre carte en a un.
    Si c'est le cas une lecture échantillonnée à 0 vaudra 0V et une lecture à 1023 vaudra 3.3V. Il ne faudra pas envoyer plus de 3.3V cependant pour ne pas endommager votre ESP. Je ne pense pas qu'il faille envoyer les 4.2V de votre batterie directement donc sur la pin A0 (sans doute au max 3.6V environ - après vous risquez d'endommager l'ESP)

    Sinon on a donc bien la formule float tension = (echantillon * 3.3) / 1023; mais au lieu de faire des maths en nombre à virgule dans le code pour comparer des tensions et potentiellement perdre en précision, utilisez des constantes parlantes en valeur échantillonnée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    constexpr int seuilTensionBruteBasse = 930 ; // 3.0V ==> calculé par (3.0V * 1023) / 3.3V
    ...
     
      int tensionBrute = analogRead(A0); 
      if (tensionBrute <= seuilTensionBruteBasse) {
        ...
      }

  9. #9
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    973
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 973
    Par défaut
    Il semble qu'il y ait bien un pont diviseur à l'entrée A0
    je confonds souvent ADC et A0
    j'ai préalablement mis un pont diviseur de 220k et 68k pour avoir 4,2v -> 1v
    mais là çà ne marche plus
    il faut donc que je trouve comment adapter 4,2v vers -> A0 = 3.3v A pour avoir enfin 1v pour une batterie à 100%
    c'est çà ?
    Images attachées Images attachées

  10. #10
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 638
    Par défaut
    Bonjour,

    il suffit de lettre une 82 k sur l'entrée A0 : 100/(220 + 100 + 82) ~ 1/4.

    Salutations

  11. #11
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    973
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 973
    Par défaut
    Bonjour Guesset

    il suffit de lettre une 82 k sur l'entrée A0 : 100/(220 + 100 + 82) ~ 1/4.
    ok c'est mis
    merci encore

  12. #12
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    973
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 973
    Par défaut
    Bonjour à tous

    Je voudrais avoir votre avis d'expert pour savoir si j'ai vraiment tout compris
    j'ai donc fait un petit schéma pour visualiser la particularité du ESP8266

    on m'a dit de rajouter une résistance de 82k ce qui fait que R1 devient égal ici à 302 k (R1 = 220k en interne)
    ne serait-ce pas plutôt 100k à rajouter pour avoir 1v sur ADC
    votre avis ?
    Images attachées Images attachées  

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Carte WEMOS D1 : sortie série non lisible
    Par wd_newbie dans le forum Arduino
    Réponses: 2
    Dernier message: 10/04/2020, 17h17
  2. Comment rediriger la sortie vers /dev/null
    Par dclink dans le forum C
    Réponses: 4
    Dernier message: 24/06/2003, 18h23
  3. [LG]Entrées et sorties redirigée
    Par Lady dans le forum Langage
    Réponses: 17
    Dernier message: 10/05/2003, 18h33
  4. Rediriger le plux de sortie
    Par Groove dans le forum C
    Réponses: 5
    Dernier message: 17/04/2003, 17h16
  5. récupérer la valeur de sortie d'un thread
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 31/07/2002, 11h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo