Kerminy HackerSpace

Outils du site


capteurs:wemos_d1_cjmcu_8128

Ceci est une ancienne révision du document !


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
  • 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.

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

V3

 
 
// ESP_Wemos
// attend x seconde , poste en mqtt , deep sleep
/*
   2N2222 switch sur le - relai Omron g5v-1-3v
   2N2222 C \
          B - |)
          E /
   D8 -> 10k -> B(2N2222)
   GND -> C(2N2222)
       -> CJMCU
   E(2N2222) -> relai bobine
   3.3V-> relai bobine
       -> relai entree contact
   relai sortie contact -> V CJMCU
 * */
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include "EspMQTTClient.h"
 
//I2C address 0x40  SIS7021
//I2C address 0x5A  CCS811
//I2C address 0x76  BMP280
 
//#define PMS5003  // si capteur connecté
//#define SI702x
#define HDC1080
 
#ifdef SI702x
#include "Adafruit_Si7021.h"
#endif
#ifdef HDC1080
#include "ClosedCube_HDC1080.h"
ClosedCube_HDC1080 hdc1080;
#endif
 
#include "Adafruit_BMP280.h"
#include "ccs811.h"         // include library for CCS811 - Sensor from martin-pennings https://github.com/maarten-pennings/CCS811
 
#ifdef PMS5003
#include "pms.h"
#endif
 
#include <Wire.h>
 
#define CCS811_ADDR 0x5A    //Alternate I2C Address
CCS811 ccs811;
#ifdef SI702x
Adafruit_Si7021 SI702x = Adafruit_Si7021();
#endif
Adafruit_BMP280 bmp; // I2C
Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor();
Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor();
 
#ifdef PMS5003
Pmsx003 pms(D4, D3);
int rxPin = D3; // sds011 D1 D2 utilisé par DHT12 i2c
int txPin = D4;
#endif
 
String prog_version = "4";
String version_maj =  "4";
 
const char* ssid = "SSID";
const char* password = "PASS";
const char* mqtt_server = "192.168.2.34";
const char* host_c = "ESP-3C82F2"; // = ausi nom client mqtt
char host[20] = "ESP-3C82F2";
const char* mqtt_user = "user";
const char* mqtt_pass = "user_pass";
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;
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 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.println(ssid);
 
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}
void dodo() {
  Serial.print("dodo min :");
  Serial.println((float)minute_dodo);
  // Connect D0 to RST to wake up !
  ESP.deepSleep(minute_dodo * 60 * 1000000);
}
 
void setup() {
  temps_milli = millis();
 
  // Connect D0 to RST to wake up
  pinMode(D0, WAKEUP_PULLUP);
  Serial.begin(115200);
  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();
 
  /////////////// CAPTEURS ////////////////
  digitalWrite(D8, HIGH); // met sous tension les capteurs
  delay(200);
  Serial.println();
  Wire.begin();
  //// 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");
  // 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();
 
  ////Si7021
#ifdef SI702x
  Serial.println("Si7021 test!");     /* ---- SETUP SI702x ----- */
  if (!SI702x.begin()) {
    Serial.println("Did not find Si702x sensor!");
  }
  else  Serial.println("ok");
#endif
  ////HDC1080
#ifdef 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
 
  Serial.println("fini");
#endif
}
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;
  });
 
}
 
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;
  //// 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;
  //// HDC1080
#ifdef HDC1080
  Serial.print("temp/HDC180 = ");
  Serial.print(hdc1080.readTemperature());
  Serial.println(" °C, ");
  Serial.print("hdc1080/HDC180 = ");
  Serial.println(hdc1080.readHumidity());
  temp_hdc1080 = (float) hdc1080.readTemperature();
  humid_hdc1080 = (float) hdc1080.readHumidity();
  humidite = humid_hdc1080;
#endif
  //// Si7021 /////
#ifdef 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 /////
  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);
    }
  }
 
 
#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 && press_bmp280 > 0 && humidite > 0 && eco2_ccs811 > 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 > 30000) {
      if ( faire_maj != true) dodo();
    }
    if (now - temps_milli > 10000) { // attend 10s 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");
        String topic = "pgvrs/"; topic += host;
        if ( client.publish(String(topic).c_str(), String(prog_version).c_str()  ) ) publie_ok++;
        topic = "temp/BPM280/"  ; topic += host;
        if ( client.publish(String(topic).c_str(), String(temp_bmp280).c_str()   ) ) publie_ok++;
        topic = "press/BPM280/" ; topic += host;
        if ( client.publish(String(topic).c_str(), String(press_bmp280).c_str()  ) ) publie_ok++;
#ifdef 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 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
        topic = "co2/CCS811/"   ; topic += host;
        if ( client.publish(String(topic).c_str(), String(eco2).c_str()    ) ) publie_ok++;
        topic = "ppmTVOC/CCS811/"   ; topic += host;
        if ( client.publish(String(topic).c_str(), String(etvoc).c_str()   ) ) publie_ok++;
#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 > 5) Serial.println("donnees transmises");
        delay(5000);
#ifdef PMS5003
        pms.write(Pmsx003::cmdSleep);
#endif
      }
    }
    delay(1000);
  }
  delay(1000);
}
capteurs/wemos_d1_cjmcu_8128.1617102048.txt.gz · Dernière modification : 2024/02/08 17:20 (modification externe)