// psswd's into include/secret.h // others settings in main.h #include "main.h" using namespace std; DHT sensors[SENSORS_NUMBER] = {DHT(4, DHT22), DHT(5, DHT22), DHT(18, DHT22), DHT(19, DHT22), DHT(21, DHT22)}; float temp[SENSORS_NUMBER]; float hum[SENSORS_NUMBER]; WiFiClient WifiClient; PubSubClient MqttClient(WifiClient); WiFiUDP NtpUDP; NTPClient TimeClient(NtpUDP, "europe.pool.ntp.org", 0, 60000); Pangodream_18650_CL Battery(ADC_PIN, CONV_FACTOR, READS); RTC_DS3231 rtc; //---------------- Réveil --------------------// int mesure_freq = 600; // temps entre deux réveils en secondes //-------------------- FONCTIONS --------------------// //-------------- Connexion MQTT --------------// void setupMQTT(const char *address, int port) { MqttClient.setServer(address, port); } void setupWIFI(const char *wifi_name, const char *password) { Serial.println('\n'); WiFi.begin(wifi_name, password); Serial.print("Connecting to "); Serial.print(wifi_name); while ((WiFi.status() != WL_CONNECTED) && (millis() <= 60000)) { Serial.println("Nouvelle tentative de connexion..."); delay(500); Serial.print('.'); } Serial.println('\n'); Serial.println("Connection established!"); Serial.print("IP address:\t"); Serial.println(WiFi.localIP()); } void reconnect(void) { Serial.println("Connecting to MQTT Broker..."); while (!MqttClient.connected()) { Serial.print("."); if (MqttClient.connect(ESPNAME, MQTT_USER, MQTT_MDP)) { Serial.println("Connected."); } } } //-------------- Initialisation et lecture des capteurs --------------// void initSensors(DHT *sensors, int number) { int i; for (i = 0; i < number; i++) { sensors[i].begin(); } } void readSensors(DHT sensors[], float temp[], float hum[], int number) { int i; for (i = 0; i < number; i++) { *(temp + i) = sensors[i].readTemperature(); *(hum + i) = sensors[i].readHumidity(); } } //-------------------- Sleep de l'ESP --------------------// /* void sleep() { esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * US_TO_S_FACTOR); esp_deep_sleep_start(); } //exemple d'une triple utilisation de valeur pour une fonction utilise pour la date std::tuple<int, int, int> getDate() { time_t rawtime = TimeClient.getEpochTime(); struct tm *ti; ti = localtime(&rawtime); int year = ti->tm_year + 1900; int month = (ti->tm_mon + 1) < 10 ? 0 + (ti->tm_mon + 1) : (ti->tm_mon + 1); int day = (ti->tm_mday) < 10 ? 0 + (ti->tm_mday) : (ti->tm_mday); return std::make_tuple(year, month, day); } */ //-------------------- Programmation du réveil de l'alimentation --------------------// void wakeup(){ // initializing the rtc if(!rtc.begin()) { Serial.println("Couldn't find RTC!"); Serial.flush(); while (1) delay(10); } if(rtc.lostPower()) { // this will adjust to the date and time at compilation rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } //we don't need the 32K Pin, so disable it rtc.disable32K(); // set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far) // if not done, this easily leads to problems, as both register aren't reset on reboot/recompile rtc.clearAlarm(1); rtc.clearAlarm(2); // stop oscillating signals at SQW Pin // otherwise setAlarm1 will fail rtc.writeSqwPinMode(DS3231_OFF); // turn off alarm 2 (in case it isn't off already) // again, this isn't done at reboot, so a previously set alarm could easily go overlooked rtc.disableAlarm(2); // schedule an alarm 10 seconds in the future if(!rtc.setAlarm1( rtc.now() + TimeSpan(mesure_freq), DS3231_A1_Second // this mode triggers the alarm when the seconds match. See Doxygen for other options )) { Serial.println("Error, alarm wasn't set!"); }else { Serial.println("Alarm will happen in 10 seconds!"); } } //-------------------- Création de trames --------------------// void writeMessage(char *txt, float *temp, float *hum, int number) { int chargelvl = Battery.getBatteryChargeLevel(); switch (number) { case 1: sprintf(txt, "|%s|%0.2f|%0.2f", CLUSTER, temp[0], hum[0]); break; case 2: sprintf(txt, "|%s|%0.2f %0.2f|%0.2f %0.2f", CLUSTER, temp[0], temp[1], hum[0], hum[1]); break; case 3: sprintf(txt, "|%s|%0.2f %0.2f %0.2f|%0.2f %0.2f %0.2f", CLUSTER, temp[0], temp[1], temp[2], hum[0], hum[1], hum[2]); break; case 4: sprintf(txt, "|%s|%0.2f %0.2f %0.2f %0.2f|%0.2f %0.2f %0.2f %0.2f", CLUSTER, temp[0], temp[1], temp[2], temp[3], hum[0], hum[1], hum[2], hum[3]); break; case 5: sprintf(txt, "|%s|%0.2f %0.2f %0.2f %0.2f %0.2f|%0.2f %0.2f %0.2f %0.2f %0.2f|%d", CLUSTER, temp[0], temp[1], temp[2], temp[3], temp[4], hum[0], hum[1], hum[2], hum[3], hum[4], chargelvl); break; case 6: sprintf(txt, "|%s|%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f|%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f", CLUSTER, temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], hum[0], hum[1], hum[2], hum[3], hum[4], hum[5]); break; default: Serial.println("Erreur, temp et hum sont trop longs : trop de capteurs"); break; } } //-------------------- Initialisation --------------------// void setup() { Serial.begin(9600); setupWIFI(SSID, SSID_PWD); setupMQTT(MQTT_ADDRESS, MQTT_PORT); initSensors(sensors, SENSORS_NUMBER); TimeClient.begin(); delay(2000); } //-------------------- Boucle pringicipale --------------------// void loop() { int year, month, day; int lenght; char time[30]; char date[30]; char msg[70]; MqttClient.loop(); if (!MqttClient.connected()) { reconnect(); } readSensors(sensors, temp, hum, SENSORS_NUMBER); writeMessage(msg, temp, hum, SENSORS_NUMBER); Serial.print("une trame de data : "); Serial.println(msg); TimeClient.update(); TimeClient.getFormattedTime().toCharArray(time, 30); tie(year, month, day) = getDate(); lenght = sprintf(date, "%d-%d-%d ", year, month, day); sprintf(date + lenght, time); sprintf(date + strlen(date), msg); MqttClient.publish(TOPIC, date); delay(2000); Serial.println("Extinction de l'ESP ! "); wakeup(); }