Table des matières

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

Les mesures:

Évolutions:

futures:

pistes :

Process

Sortie du mode veille

  1. se connecte au reseau Wifi
  2. se met en mode OTA pour d'éventuel mise à jour des programmes
  3. actionne le relai de mise liaison Resistance 180k/A0 Wemos pour une mesure de la tension de la batterie
  4. setup et initialisation des puces de mesure
  5. 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);
}