Capteur Température / humidité / pression / CO2 : Wemos D1 cjmcu 8128

Wemos ESP8266 puce WiFi ou genre

CJMCU-811 CCS811 Indoor air quality monitoring digital gas sensor

BMP280 température/ pression atmosphérique

HDC1080 température et humidité

relai sur l'alimentation des platines de capteurs (via transistor 2N2222 sur D8)

batterie 18650 , et son régulateur

Les mesures:

TVCO (Total Volatile Organic Compound)

eCO2 (équivalent CO2)

Humidité (SI702x)

Température (BMP280 & SI702x)

Pression (BMP280)

tension batterie

Évolutions:

suppression de la mesure batterie qui consomme trop. Il suffit d'ajouter un régulateur de batterie (BSR) pour éviter sa décharge et de penser que quans le capteur ne discute plus, c'est qu'il faut sans doute changer la batterie…

ajout de la possibilité de télécharger un nouveau firmware pour mise à jour si version différente. Cela permet de laisser le shunt RESET/D0 pour le réveil auto en place.

futures:

passage sur une autre platine esp8266 pour une alimentation soudée

test d'un autre capteur sans le eCO2 pour une serie température/humidité seule avec une consommation moindre, un mode sommeil ce qui permetrait de supprimer le relai/transistor

ajout d'enregistrement sur la flash pour un mode déconnecté avec téléchargement sur une commande

pistes :

http://www.esp8266learning.com/ccs811-digital-gas-sensor-and-esp8266-example.php

https://github.com/SFeli/ESP32_CJMCU-8128

Process

Sortie du mode veille

se connecte au reseau Wifi

se met en mode OTA pour d'éventuel mise à jour des programmes

actionne le relai de mise liaison Resistance 180k/A0 Wemos pour une mesure de la tension de la batterie

setup et initialisation des puces de mesure

si il y a des mesures envois les info au serveur MQTT

Se remet en mode sommeil pour 15min

Codes

Mode Arduino / ESP8266 https://github.com/esp8266/Arduino

V5

juste pour DHT12 , mais les définitions de présence des capteurs sont dans le code #define Capteur_CSS811 par ex…

/* // ESP_Wemos CCS811 + BMP280 + HDC1080 ou SI7021 Carbon Monoxide Temperature Humidity Air Gas Sensor DH12 V5 Fonction: vérification et prise de mesures connection sur un des reseau wifi present se connecte au serveur MQTT s'abonne a une possible mise a jour poste en mqtt deep sleep 2N2222 switch sur le - relai Omron g5v-1-3v GND -> 2N2222 C -- \ D8 -> 10k -> B --- |)2N2222 relai bobine -> E -- / | \-> CJMCU 3.3V-> relai bobine +-> relai entree contact 2N2222 E relai bobine relai sortie contact -> V CJMCU * */ #include <ESP8266WiFi.h> #include <ESP8266WiFiMulti.h> #include <ESP8266mDNS.h> #include <WiFiUdp.h> #include <ArduinoOTA.h> #include "EspMQTTClient.h" #include <Ticker.h> Ticker coucou; ESP8266WiFiMulti wifiMulti; //I2C address 0x40 HDC1080 //I2C address 0x5A CCS811 //I2C address 0x76 BMP280 //#define PMS5003 // ne option si capteur connecté //#define Capteur_SI702x #define Capteur_HDC1080 // CJMCU #define Capteur_BMP280 // CJMCU #define Capteur_CCS811 // .. //#define Capteur_DHT12 ////////////////////// #ifdef Capteur_SI702x #include "Adafruit_Si7021.h" #endif #ifdef Capteur_HDC1080 #include "ClosedCube_HDC1080.h" ClosedCube_HDC1080 hdc1080; #endif #ifdef Capteur_BMP280 #include "Adafruit_BMP280.h" Adafruit_BMP280 bmp; // I2C Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor(); Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor(); #endif #ifdef Capteur_CCS811 #include "ccs811.h" // include library for CCS811 - Sensor from martin-pennings https://github.com/maarten-pennings/CCS811 #endif #include <Wire.h> #ifdef Capteur_CCS811 #define CCS811_ADDR 0x5A //Alternate I2C Address CCS811 ccs811; #endif #ifdef Capteur_SI702x Adafruit_Si7021 SI702x = Adafruit_Si7021(); #endif #ifdef PMS5003 #include "pms.h" Pmsx003 pms(D4, D3); int rxPin = D3; // sds011 D1 D2 utilisé par DHT12 i2c int txPin = D4; #endif #ifdef Capteur_DHT12 #include <WEMOS_DHT12.h> DHT12 dht12; #endif String prog_version = "5"; String version_maj = "5"; const char* ssid1 = "kerminy"; const char* password1 = "pass1"; const char* ssid2 = "NORD"; const char* password2 = "pass2"; const char* ssid3 = "SUD"; const char* password3 = "pass3"; const char* ssid4 = "AUTRE"; const char* password4 = "pass4"; const char* mqtt_server = "192.168.1.13"; char host_c[20] = "ESP-12345678"; // = ausi nom client mqtt char host[20] = "ESP-12345678"; // maj au boot const char* mqtt_user = "kerminy"; const char* mqtt_pass = "password"; int mqtt_port = 1883; bool faire_maj = false; bool demande_maj = false; bool envoie_mqtt = false; bool connexion_prette = false; int donnees_prette = 0; int publie_ok = 0; int publie_max = 7; // METTRE NE NBR DE MQTT A POSTER !! float temps_milli = 30000; // temps milli entre 2 mesures 30s uint64_t minute_dodo = 15; // min ESP.deepSleep(1000000 * 60 * (uint64_t)min); /////////////////////////////////// valeurs du msq MQTT int retour_ok = 0; // retour du serveur float temp_bmp280 = 0; float press_bmp280 = 0; float humidite = 0; float temp_Si7021 = 0; float humid_Si7021 = 0; float temp_hdc1080 = 0; float humid_hdc1080 = 0; float temp_DHT12 = 0; float humid_DHT12 = 0; float pm_1 = 0; float pm_2_5 = 0; float pm_10 = 0; float pm_endessous_0_3 = 0; float pm_endessous_0_5 = 0; float pm_endessous_1 = 0; float pm_endessous_2_5 = 0; float pm_endessous_5 = 0; float pm_endessous_10 = 0; float eco2_CCS811 = 0; float etvoc_CCS811 = 0; auto lastRead = millis(); EspMQTTClient client(NULL, NULL, mqtt_server, mqtt_user, mqtt_pass, host_c, mqtt_port); void setup_wifi() { delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.print(ssid1); Serial.print(" "); Serial.print(ssid2); Serial.print(" "); Serial.print(ssid3); Serial.print(" "); Serial.println(ssid4); coucou.attach(1, flip); WiFi.mode(WIFI_STA); wifiMulti.addAP(ssid1, password1); wifiMulti.addAP(ssid2, password2); wifiMulti.addAP(ssid3, password3); wifiMulti.addAP(ssid4, password4); int boucle = 0; while (wifiMulti.run() != WL_CONNECTED) { delay(500); Serial.print("."); if (boucle++ > 30) dodo(); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void dodo() { digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH Serial.print("dodo min :"); Serial.println((float)minute_dodo); // Connect D0 to RST to wake up ! ESP.deepSleep(minute_dodo * 60 * 1000000); } int count = 0; void flip() { int state = digitalRead(LED_BUILTIN); // get the current state of GPIO1 pin digitalWrite(LED_BUILTIN, !state); // set pin to the opposite state ++count; // when the counter reaches a certain value, start blinking like crazy if (count == 20) { coucou.attach(0.1, flip); } // when the counter reaches yet another value, stop blinking else if (count == 120) { coucou.detach(); } } void setup() { temps_milli = millis(); pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output digitalWrite(LED_BUILTIN, LOW); // Turn the LED on (Note that LOW is the voltage level // Connect D0 to RST to wake up pinMode(D0, WAKEUP_PULLUP); Serial.begin(115200); coucou.attach(2, flip); pinMode(D8, OUTPUT); Serial.println(""); Serial.print("prog_version:"); Serial.println(prog_version); Serial.print("ChipID : "); Serial.println(ESP.getChipId(), HEX); sprintf(host, "ESP-%08X", ESP.getChipId()); setup_wifi(); Serial.println(host); strlcpy(host_c, host, sizeof(host_c)); /////////////// CAPTEURS //////////////// digitalWrite(D8, HIGH); // met sous tension les capteurs delay(200); Serial.println(); Wire.begin(); delay(1000); // temp de chauffe ? ////DHT12 #ifdef Capteur_DHT12 Serial.println("DHT12 test"); if (dht12.get() == 0) { Serial.print("Temperature in Celsius : "); Serial.println(dht12.cTemp); Serial.print("Temperature in Fahrenheit : "); Serial.println(dht12.fTemp); Serial.print("Relative Humidity : "); Serial.println(dht12.humidity); Serial.println(); } #endif //// CCS811 #ifdef Capteur_CCS811 Serial.println("CCS811 test"); /* --- SETUP CCS811 on 0x5A ------ */ ccs811.set_i2cdelay(50); // Needed for ESP8266 because it doesn't handle I2C clock stretch correctly if (!ccs811.begin()) { Serial.println("Failed to start sensor! Please check your wiring."); } bool ok = ccs811.start(CCS811_MODE_1SEC); if ( !ok ) Serial.println("setup: CCS811 start FAILED"); else Serial.println("ok"); #endif // BMP280 #ifdef Capteur_BMP280 delay(200); if (!bmp.begin(0x76)) { Serial.println(F("Could not find a valid BMP280 sensor, check wiring!")); } else Serial.println("ok"); /* Default settings from datasheet. */ bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */ Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */ Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */ Adafruit_BMP280::FILTER_X16, /* Filtering. */ Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */ bmp_temp->printSensorDetails(); #endif ////Si7021 #ifdef Capteur_SI702x Serial.println("Si7021 test!"); /* ---- SETUP SI702x ----- */ if (!SI702x.begin()) { Serial.println("Did not find Si702x sensor!"); } else Serial.println("ok"); #endif ////HDC1080 #ifdef Capteur_HDC1080 hdc1080.begin(0x40); #endif //// PMS5003 //// #ifdef PMS5003 Serial.println("PMS50031 test!"); /* ---- SETUP SI702x ----- */ pms.begin() ; pms.write(Pmsx003::cmdSleep); pms.write(Pmsx003::cmdWakeup); pms.waitForData(Pmsx003::wakeupTime); //pms.write(Pmsx003::cmdModeActive); // par defaut mode passive #endif Serial.println("fini"); } void onConnectionEstablished() { connexion_prette = true ; Serial.println("connexion MQTT PRETTE"); Serial.print(mqtt_server); Serial.print(" "); Serial.print(mqtt_port); Serial.print(" "); Serial.print(host); Serial.print(" "); Serial.print(mqtt_pass); Serial.print(" "); Serial.println(mqtt_user); // regarde si maj firmware String topic = "pgvrs/" ; topic += host; client.subscribe(String(topic).c_str(), [](const String & payload) { Serial.println(payload); version_maj = payload; }); coucou.attach(0.5, flip); } void loop() { unsigned long now = millis(); Serial.print("DEPUIS "); Serial.println((now - temps_milli) / 1000); if (version_maj != prog_version) { Serial.println("version_maj en attente "); Serial.println(version_maj); faire_maj = true; if (demande_maj != true ) client.enableHTTPWebUpdater(); // Enable the web updater. // User and password default to values of MQTTUsername and MQTTPassword. //These can be overrited with enableHTTPWebUpdater("user", "password"). demande_maj = true; } envoie_mqtt = false; //// DHT12 #ifdef Capteur_DHT12 if (dht12.get() == 0) { Serial.print("temp/DHT12 = "); Serial.print(dht12.cTemp); Serial.println(" °C, "); Serial.print("humid/DHT12 = "); Serial.println(dht12.humidity); temp_DHT12 = (float) dht12.cTemp; humid_DHT12 = (float) dht12.humidity; humidite = humid_DHT12; } #endif //// BMP280 #ifdef Capteur_BMP280 sensors_event_t temp_event, pressure_event; bmp_temp->getEvent(&temp_event); bmp_pressure->getEvent(&pressure_event); Serial.print(F("/temp/BMP_280 = ")); Serial.print(temp_event.temperature); Serial.println(" *C"); Serial.print(F("/Press/BMP_280 = ")); Serial.print(pressure_event.pressure); Serial.println(" hPa"); temp_bmp280 = (float)temp_event.temperature; press_bmp280 = (float)pressure_event.pressure; #endif //// HDC1080 #ifdef Capteur_HDC1080 Serial.print("temp/HDC180 = "); Serial.print(hdc1080.readTemperature()); Serial.println(" °C, "); Serial.print("humid/HDC180 = "); Serial.println(hdc1080.readHumidity()); temp_hdc1080 = (float) hdc1080.readTemperature(); humid_hdc1080 = (float) hdc1080.readHumidity(); humidite = humid_hdc1080; #endif //// Si7021 ///// #ifdef Capteur_SI702x Serial.print("temp/SI702x = "); Serial.print(SI702x.readTemperature(), 2); Serial.println(" °C, "); Serial.print("humid/SI702x = "); Serial.println(SI702x.readHumidity(), 2); temp_Si7021 = (float) SI702x.readTemperature(); humid_Si7021 = (float)SI702x.readHumidity(); humidite = humid_Si7021; #endif //// CCS811 ///// #ifdef Capteur_CCS811 uint16_t eco2, etvoc, errstat, raw; // Read CCS811 ccs811.set_envdata(temp_event.temperature, humidite); ccs811.read(&eco2, &etvoc, &errstat, &raw); int test = 0; while ( test++ < 20 ) { if ( errstat == CCS811_ERRSTAT_OK ) { Serial.print("co2/CCS811 = "); Serial.println(eco2); Serial.print("ppmTVOC/CCS811 = "); Serial.println(etvoc); eco2_CCS811 = (float) eco2; etvoc_CCS811 = (float) etvoc; if (eco2_CCS811 > 100) break; delay(1000); } } #endif #ifdef PMS5003 //// PMS5003 //// //pms.begin(); //pms.write(Pmsx003::cmdModeActive); //pms.write(Pmsx003::cmdModePassive); pms.write(Pmsx003::cmdWakeup); //pms.waitForData(Pmsx003::wakeupTime); delay(1000); const auto n = Pmsx003::Reserved; Pmsx003::pmsData data[n]; Pmsx003::PmsStatus status = pms.read(data, n); switch (status) { case Pmsx003::OK: { auto newRead = millis(); lastRead = newRead; // For loop starts from 3 // Skip the first three data (PM1dot0CF1, PM2dot5CF1, PM10CF1) for (size_t i = Pmsx003::PM1dot0; i < n; ++i) { Serial.print(data[i]); Serial.print("\t"); Serial.print(Pmsx003::dataNames[i]); Serial.print(" ["); Serial.print(Pmsx003::metrics[i]); Serial.print("]"); Serial.println(); } pm_1 = (float)data[3]; pm_2_5 = (float)data[4]; pm_10 = (float)data[5]; pm_endessous_0_3 = (float)data[6]; pm_endessous_0_5 = (float)data[7]; pm_endessous_1 = (float)data[8]; pm_endessous_2_5 = (float)data[9]; pm_endessous_5 = (float)data[10]; pm_endessous_10 = (float)data[11]; if (pm_1 > 0 || pm_2_5 > 0 || pm_10 > 0) envoie_mqtt = true; break; } case Pmsx003::noData: Serial.println("attend pms"); break; default: Serial.println("_________________"); Serial.println(Pmsx003::errorMsg[status]); } /* // capteur sds011 PmResult pm = sds.readPm(); if (pm.isOk()) { pm_2_5 = (float)pm.pm25; pm_10 = (float)pm.pm10; Serial.print("PM2.5 = "); Serial.println(pm_2_5); Serial.print("PM10 = "); Serial.println(pm_10); // Serial.println(pm.toString()); } else { // notice that loop delay is set to 5s (sensor sends data every 3 minutes) and some reads are not available //Serial.print("Probleme de lecture SDS011: "); //Serial.println(pm.statusToString()); Serial.print("PM2.5 : "); Serial.println(pm_2_5); Serial.print("PM10 : "); Serial.println(pm_10); } */ #else envoie_mqtt = true; #endif ///////// MQTT config //////////// if (envoie_mqtt == true && (temp_DHT12 > 0 || (press_bmp280 > 0 && humidite > 0 ))) { //EspMQTTClient client(NULL, NULL, mqtt_server, mqtt_user, mqtt_pass, host, mqtt_port); // client.enableDebuggingMessages(); // Enable debugging messages sent to serial output client.loop(); if (now - temps_milli > 60000) { Serial.println("pas d'acces au serveur MQTT , dodo min :"); dodo(); } if (now - temps_milli > 20000) { // attend 20s avant de faire Serial.print("ATTEND CLIENT MQTT...sur "); if ( faire_maj == true) Serial.println(WiFi.localIP()); if (connexion_prette == true && publie_ok < 5) { Serial.println("PUBLIE"); coucou.attach(0.3, flip); String topic = "pgvrs/"; topic += host; if ( client.publish(String(topic).c_str(), String(prog_version).c_str() ) ) publie_ok++; #ifdef Capteur_BMP280 topic = "temp/BMP280/" ; topic += host; if ( client.publish(String(topic).c_str(), String(temp_bmp280).c_str() ) ) publie_ok++; topic = "press/BMP280/" ; topic += host; if ( client.publish(String(topic).c_str(), String(press_bmp280).c_str() ) ) publie_ok++; #endif #ifdef Capteur_HDC1080 topic = "temp/HDC1080/" ; topic += host; if ( client.publish(String(topic).c_str(), String(temp_hdc1080).c_str() ) ) publie_ok++; topic = "humid/HDC1080/" ; topic += host; if ( client.publish(String(topic).c_str(), String(humid_hdc1080).c_str() ) ) publie_ok++; #endif #ifdef Capteur_DHT12 topic = "temp/DHT12/" ; topic += host; if ( client.publish(String(topic).c_str(), String(temp_DHT12).c_str() ) ) publie_ok++; topic = "humid/DHT12/" ; topic += host; if ( client.publish(String(topic).c_str(), String(humid_DHT12).c_str() ) ) publie_ok++; publie_max = 2; #endif #ifdef Capteur_SI702x topic = "temp/SI7021/" ; topic += host; if ( client.publish(String(topic).c_str(), String(temp_Si7021).c_str() ) ) publie_ok++; topic = "humid/SI7021/" ; topic += host; if ( client.publish(String(topic).c_str(), String(humid_Si7021).c_str() ) ) publie_ok++; #endif #ifdef Capteur_CCS811 topic = "co2/CCS811/" ; topic += host; if ( client.publish(String(topic).c_str(), String(eco2_CCS811).c_str() ) ) publie_ok++; topic = "ppmTVOC/CCS811/" ; topic += host; if ( client.publish(String(topic).c_str(), String(etvoc_CCS811).c_str() ) ) publie_ok++; #endif #ifdef PMS5003 topic = "pm_1/PMS5003/" ; topic += host; if ( client.publish(String(topic).c_str(), String(pm_1).c_str() ) ) publie_ok++; topic = "pm_2_5/PMS5003/" ; topic += host; if ( client.publish(String(topic).c_str(), String(pm_2_5).c_str() ) ) publie_ok++; topic = "pm_10/PMS5003/" ; topic += host; if ( client.publish(String(topic).c_str(), String(pm_10).c_str() ) ) publie_ok++; topic = "pm_endessous_0_3/PMS5003/" ; topic += host; if ( client.publish(String(topic).c_str(), String(pm_endessous_0_3).c_str() ) ) publie_ok++; topic = "pm_endessous_0_5/PMS5003/" ; topic += host; if ( client.publish(String(topic).c_str(), String(pm_endessous_0_5).c_str() ) ) publie_ok++; topic = "pm_endessous_1/PMS5003/" ; topic += host; if ( client.publish(String(topic).c_str(), String(pm_endessous_1).c_str() ) ) publie_ok++; topic = "pm_endessous_2_5/PMS5003/" ; topic += host; if ( client.publish(String(topic).c_str(), String(pm_endessous_2_5).c_str() ) ) publie_ok++; topic = "pm_endessous_5/PMS5003/" ; topic += host; if ( client.publish(String(topic).c_str(), String(pm_endessous_5).c_str() ) ) publie_ok++; topic = "pm_endessous_10/PMS5003/" ; topic += host; if ( client.publish(String(topic).c_str(), String(pm_endessous_10).c_str() ) ) publie_ok++; #endif Serial.println(publie_ok); if (publie_ok > publie_max) Serial.println("donnees transmises"); delay(5000); #ifdef PMS5003 pms.write(Pmsx003::cmdSleep); #endif dodo(); } } delay(1000); } delay(1000); }