Kerminy HackerSpace

Outils du site


ressources:capteurs:wemos_d1_cjmcu_8128

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 :

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);
}
ressources/capteurs/wemos_d1_cjmcu_8128.txt · Dernière modification : 2024/02/08 17:20 de 127.0.0.1