diff --git a/26.bin b/26.bin new file mode 100644 index 0000000..93ed430 Binary files /dev/null and b/26.bin differ diff --git a/28.bin b/28.bin new file mode 100644 index 0000000..d07ff94 Binary files /dev/null and b/28.bin differ diff --git a/CCS811_test/CCS811_test.ino b/CCS811_test/CCS811_test.ino new file mode 100644 index 0000000..271ff90 --- /dev/null +++ b/CCS811_test/CCS811_test.ino @@ -0,0 +1,97 @@ + +#include + +Preferences preferences; + +#include "Adafruit_CCS811.h" + +Adafruit_CCS811 ccs; + +void setup() +{ + Serial.begin(9600); + + Serial.println("CCS811 test"); + Wire.begin(25, 21); + + // Удаляем отдельный ключ + //preferences.remove("counter"); + // Удаляем все настройки под заданным пространством имён + //preferences.clear(); + + if (!ccs.begin()) + { + Serial.println("Failed to start sensor! Please check your wiring."); + while (1) + ; + } + + // Wait for the sensor to be ready + while (!ccs.available()) + ; +} + +void loop() +{ + if (ccs.available()) + { + if (!ccs.readData()) + { + + unsigned long timenow = millis(); + + if (timenow >= 43200000 && timenow <= 43240000) + { + preferences.begin("airdata", false); + preferences.putUInt("co2", ccs.geteCO2()); + preferences.putUInt("tvoc", ccs.getTVOC()); + preferences.putUInt("baseline", ccs.getBaseline()); + preferences.end(); + Serial.println("Write data in preferenses - OK"); + preferences.end(); + } + + Serial.println("----- "); + Serial.println(timenow); + Serial.println(getMacAddress()); + Serial.println("----- "); + + Serial.print("NOW CO2: "); + Serial.println(ccs.geteCO2()); + + Serial.print("NOW ppm, TVOC: "); + Serial.println(ccs.getTVOC()); + + Serial.print("NOW aseline: "); + Serial.println(ccs.getBaseline()); + + Serial.println("================="); + + preferences.begin("airdata", false); + Serial.print("Preferenses CO2: "); + Serial.println(preferences.getUInt("co2", 0)); + + Serial.print("Preferenses TVOC: "); + Serial.println(preferences.getUInt("tvoc", 0)); + + Serial.print("Preferenses Baseline: "); + Serial.println(preferences.getUInt("baseline", 0)); + Serial.println("============================================="); + preferences.end(); + } + else + { + Serial.println("ERROR!"); + } + } + delay(5000); +} + +String getMacAddress() +{ + uint8_t baseMac[6]; + esp_read_mac(baseMac, ESP_MAC_WIFI_STA); + char baseMacChr[18] = {0}; + sprintf(baseMacChr, "%02X%02X%02X%02X%02X%02X", baseMac[0], baseMac[1], baseMac[2], baseMac[3], baseMac[4], baseMac[5]); + return String(baseMacChr); +} \ No newline at end of file diff --git a/CCS811_test/Рабочий стол - Ярлык.lnk b/CCS811_test/Рабочий стол - Ярлык.lnk new file mode 100644 index 0000000..3215754 Binary files /dev/null and b/CCS811_test/Рабочий стол - Ярлык.lnk differ diff --git a/M5Atom_airqa.ino b/M5Atom_airqa.ino index 66e19f9..9f1e73f 100644 --- a/M5Atom_airqa.ino +++ b/M5Atom_airqa.ino @@ -8,8 +8,17 @@ Диапазон измерения концентрации летучих органических веществ 0 ... 1187 ppb */ +/*************************************************************************** + +Датчики воздуха +24A1605423AC - light +5002918A38CC +5002919F5450 +24A160474D14 +24A160542B80 + + ***************************************************************************/ #include "esp_sleep.h" -#include "driver/rtc_io.h" #include // https://github.com/tzapu/WiFiManager #include //Сохранение настроек хеша прошивки @@ -33,12 +42,12 @@ //Наша кнопочка при нажатии на которую произойдет вызов wifi менеджера и перезагрузка в станцию #define TRIGGER_PIN 39 #define uS_TO_S_FACTOR 1000000 -#define TIME_TO_SLEEP 30 +#define TIME_TO_SLEEP 60 #define GPIO_WAK 23 #define CCS811_ADDR 0x5B //Default I2C Address //#define CCS811_ADDR 0x5A //Alternate I2C Address -unsigned int VersionSW = 225; //65536 Версия прошивки +unsigned int VersionSW = 30; //65536 Версия прошивки //15 - добавлено то, се, забыл вообще дописать что добавленоSerial //19 - вывод в консоль всех действий, ошибки с обновлнеием - починил, прияногое мигание светодиодом, тест для поиска metrics. @@ -46,6 +55,12 @@ unsigned int VersionSW = 225; //65536 Версия прошивки //22 - поправлено поиск сервера по metrics local. //23 - добавленн BSID //24 - полный передел всего +//25 - новые топики, спящий режим +//26 - тест обновления сука - работает +//27 - таймаут станции без wifi 40 сек +//28 - калибровка вернулась +//29 - baseline выведен и отключен +//30 - новое освещение оранжевый цвет gpio_num_t pinWak = GPIO_NUM_23; @@ -65,13 +80,14 @@ IPAddress IpMqtt; WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "0.ua.pool.ntp.org", 7200, 60000); //Собственно сервер времени смещение и частоат запроса, но он вручную const PROGMEM char *willmess = "{\"conn\":\"err\"}"; -const char *mqttHostName = "cctv.automation.art"; //Хостнейм брокера metrics.local cctv.automation.art //192.168.89.210 -unsigned int mqttPort = 8889; //Порт брокера 1883 8889 +const char *mqttHostName = "metrics"; //Хостнейм брокера metrics.local cctv.automation.art //192.168.89.210 +unsigned int mqttPort = 1883; //Порт брокера 1883 8889 + String getMacAddress(); String macc = getMacAddress(); -String topicTemp = "aastudio/" + macc + "/data/0"; -String willTopicTemp = "aastudio/" + macc + "/status"; +String topicTemp = "aastudio/sens/" + macc + "/data/0"; +String willTopicTemp = "aastudio/sens/" + macc + "/status"; const PROGMEM char *mqttLogin = "login", *mqttPass = "password"; @@ -80,37 +96,51 @@ char bufWillTopic[150]; const char *mqttIPHost; -RTC_DATA_ATTR unsigned long timingUpdate, timingSendMqtt; //Таймеры для millis() -int PROGMEM nextM5Update = 450000; //каждые 7.5 минут запрос обновления с сервера -int PROGMEM nextReqSensor = 10000; //опрос датчиков раз в 10 секунд -int PROGMEM nextMqttSend = 60000; //Отправка +RTC_DATA_ATTR byte countOta = 0; +int PROGMEM nextM5Update = 450000; //каждые 7.5 минут запрос обновления с сервера +int PROGMEM nextReqSensor = 10000; //опрос датчиков раз в 10 секунд +int PROGMEM nextMqttSend = 60000; //Отправка -//Поправочные коефициенты для датчиков -//[24A160474D14, 5002919F5450, 5002918A38CC] -//tcoeff[0,1,2] -//hcoeff[0,1,2] - -float PROGMEM tcoeff[3] = {-11.18, -9.62, -10.6}; //Температура -float PROGMEM hcoeff[3] = {13.77, 14.07, 15.56}; //Влажность -float callibrationT = 0, callibrationH = 0; float TempAv, HumAv, Eco2Av, TvocAv; +unsigned int BaselineTvoc=0; byte errorID = 0; - long rssi = 0; - -#define NUM_AVER 5 -float averageT, averageH, averageECO, averageTVOC; // перем. среднего -float valArrayT[NUM_AVER], valArrayH[NUM_AVER], valArrayECO[NUM_AVER], valArrayTVOC[NUM_AVER]; // массив byte idxT = 0, idxH = 0, idxECO = 0, idxTVOC = 0; bool mqttSendFlag = false; int reqCounter = 0; bool flagblink = true; +void ledset(byte color = 0, bool blink = false) +{ + M5.dis.setBrightness(30); //Половина яркости + switch (color) + { + case 2: + M5.dis.drawpix(0, 0xf00000); //Зеленый + break; + case 1: + M5.dis.drawpix(0, 0x00ff00); //Красный + break; + case 3: + M5.dis.drawpix(0, 0x0000ff); //Синий + break; + case 4: + M5.dis.drawpix(0, 0x707070); //Белый + break; + default: + M5.dis.clear(); + break; + } +} + //Настройки void setup() { + Serial.begin(115200); + // Serial.setDebugOutput(true); + btStop(); // esp_bt_controller_disable(); @@ -118,35 +148,27 @@ void setup() M5.begin(true, false, true); Wire.begin(25, 21); //Пины для I2c на ATOM - // pinMode(GPIO_WAK, OUTPUT); //Пин датчика для работы - // digitalWrite(GPIO_WAK, LOW); - // gpio_hold_en(pinWak); - // gpio_deep_sleep_hold_en(); - // rtc_gpio_set_level (pin_MOSFET, 1); // GPIO ВЫСОКИЙ - // esp_sleep_pd_config (ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - // esp_sleep_enable_timer_wakeup (60 * 1000 * 1000); - // esp_deep_sleep_start (); + pinMode(GPIO_WAK, OUTPUT); //Пин датчика для работы + digitalWrite(GPIO_WAK, LOW); pinMode(TRIGGER_PIN, INPUT); - hdc1080.begin(0x40); //14 бит температура и влажность + hdc1080.begin(0x40); hdc1080.setResolution(HDC1080_RESOLUTION_11BIT, HDC1080_RESOLUTION_11BIT); while (!ccs.begin() && !ccs.available()) //The device's I2C address is 0x5A { - Serial.println("Failed BEGIN And Failed available "); + ledset(1, true); } - //ccs.setTempOffset(8.6); - + //ccs.setTempOffset(8.6); + // ccs.setBaseline(21634); //Установка коеффициентов каллибровки по MAC адресу // SetCallibrationCoeff(); delay(15); WiFi.mode(WIFI_STA); - Serial.begin(115200); - Serial.setDebugOutput(true); topicTemp.toCharArray(bufTopic, topicTemp.length() + 1); willTopicTemp.toCharArray(bufWillTopic, willTopicTemp.length() + 1); @@ -156,15 +178,10 @@ void setup() // wm.resetSettings(); // wipe settings - // const char *custom_radio_str = "
One
Two
Three"; - // new (&custom_field) WiFiManagerParameter(custom_radio_str); // custom html input - // wm.addParameter(&custom_field); - // wm.setSaveParamsCallback(saveParamCallback); - std::vector menu = {"wifi", "info", "param", "sep", "restart", "exit"}; wm.setMenu(menu); wm.setClass("invert"); - //wm.setConfigPortalTimeout(60); + wm.setConfigPortalTimeout(40); wm.setMinimumSignalQuality(20); wm.setScanDispPerc(true); @@ -225,20 +242,6 @@ int setServCall(IPAddress SetIpaddr) return 0; } -//Функция получения данных из MQTT если мы подпишемся на топики -// void callback(char *topic, byte *payload, unsigned int length) -// { -// ////////////Serial.print("Message arrived ["); -// ////////////Serial.print(topic); -// //////////Serial.print("] "); -// for (int i = 0; i < length; i++) -// { -// //////////Serial.print((char)payload[i]); -// } -// //////////Serial.println(); -// } - -//Запрос времени NTP и установка локлаьного времени int reqNtpTime() { if (timeClient.update()) @@ -259,44 +262,32 @@ int reqNtpTime() return 0; } -//Нажатие кнопки для сброса int checkButton() { Serial.println("Button Pressed to RESET"); wm.resetSettings(); - // ESP.restart(); + ESP.restart(); //////////Serial.println("Starting config portal"); - wm.setConfigPortalTimeout(120); + //wm.setConfigPortalTimeout(120); - if (!wm.startConfigPortal("AirQaPortal", "12345678")) //Логин и пароль точки доступа - { - Serial.println("failed to connect or hit timeout"); + // if (!wm.startConfigPortal("AirQaPortal", "12345678")) //Логин и пароль точки доступа + // { + // Serial.println("failed to connect or hit timeout"); - ESP.restart(); - } - else - { - Serial.println("Clien connected to AP"); - } + // ESP.restart(); + // } + // else + // { + // Serial.println("Clien connected to AP"); + // } return 0; } -// { -// String value; -// if (wm.server->hasArg(name)) -// { -// value = wm.server->arg(name); -// } -// return value; -// } - -//Обновление прошивки, происходит проверка и загрузка - void OTAUpdate() { - Serial.println("OTAUpdate() START"); + Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!OTAUpdate() START!!!!!!!!!!!!!!!!!!!!!!!!!!"); bool flagOTA = false; String keyOTA; String payload; @@ -304,7 +295,7 @@ void OTAUpdate() if (WiFi.status() == WL_CONNECTED) { HTTPClient http; - String serverPath = "http://Dmeteosence.s-host.net/airqa/airquality.php?meteopas=e93gme9hAt9nSWaV&mac=" + macc + "&meteodata=gethash"; + String serverPath = "http://meteosence.s-host.net/airqa/airquality.php?meteopas=e93gme9hAt9nSWaV&mac=" + macc + "&meteodata=gethash"; Serial.println(serverPath); http.begin(serverPath.c_str()); @@ -367,14 +358,6 @@ void OTAUpdate() t_httpUpdate_return ret = ESPhttpUpdate.update("http://meteosence.s-host.net/airqa/airatoms.bin"); - //После update ничего не происходит, такая вот особенность. - //Если все прошло хорошо, перезагрузка на новую прошивку - // Если указано значение true, модуль ESP перезагрузится после успешного завершения обновления. В случае ложного , модуль не перезагружается автоматически. Загруженная новая прошивка остается в стадии обновления флэш-памяти на модуле ESP. - // Процесс загрузки во время следующего запуска модуля путем сброса скопирует обновленное микропрограммное обеспечение в фактическую область программы, и запустится новая программа эскиза. Значение по умолчанию верно. - - ////////Serial.print("ret "); - Serial.println(ret); - switch (ret) { case HTTP_UPDATE_FAILED: @@ -401,31 +384,6 @@ void OTAUpdate() } } -//Функция для индикации Led -void ledset(char color = 't', bool blink = false) -{ - M5.dis.setBrightness(30); //Половина яркости - switch (color) - { - case 'g': - M5.dis.drawpix(0, 0xf00000); //Зеленый - break; - case 'r': - M5.dis.drawpix(0, 0x00f000); //Красный - break; - case 'b': - M5.dis.drawpix(0, 0x0000f0); //Синий - break; - case 'w': - M5.dis.drawpix(0, 0x707070); //Белый - break; - default: - M5.dis.clear(); - break; - } -} - -//Получение мак адреса String getMacAddress() { uint8_t baseMac[6]; @@ -435,63 +393,88 @@ String getMacAddress() return String(baseMacChr); } -//Установка коефициентов калибровки -void SetCallibrationCoeff() +int SetCallibrationCoeff(String MacThat) { - // ////////Serial.print("Mac: "); - // ////////Serial.println(getMacAddress()); - //[24A160474D14, 5002919F5450, 5002918A38CC] - //tcoeff[0,1,2] - //hcoeff[0,1,2] + // 24A1605423AC - light + // 5002918A38CC + // 5002919F5450 + // 24A160474D14 + // 24A160542B80 - if (macc == "24A160474D14") + if (MacThat == "24A1605423AC") { - callibrationT = tcoeff[0]; - callibrationH = hcoeff[0]; - } - if (macc == "5002919F5450") - { - callibrationT = tcoeff[1]; - callibrationH = hcoeff[1]; + TempAv += -6.91; + HumAv += 7.95; } - if (macc == "5002918A38CC") + if (MacThat == "5002918A38CC") { - callibrationT = tcoeff[2]; - callibrationH = hcoeff[2]; + TempAv += -5.72; + HumAv += 12.74; } + + if (MacThat == "5002919F5450") + { + TempAv += -6.57; + HumAv += 12.89; + } + + if (MacThat == "24A160474D14") + { + TempAv += -7.14; + HumAv += 11.84; + } + + if (MacThat == "24A160542B80") + { + TempAv += -7.37; + HumAv += 8.5; + } + + return 0; } //Запрос данных с датчиков. void reqSensorData() { - delay(15); + float hdc1080Temp = 0, hdc1080Hum = 0; int eco2 = 0, tvoc = 0; - for (int g = 0; g <= 10; g++) + hdc1080Temp = hdc1080.readTemperature(); + hdc1080Hum = hdc1080.readHumidity(); + + if (hdc1080Temp < -40 || hdc1080Temp > 60) + { + errorID = 6; + } + + if (hdc1080Hum < 0 || hdc1080Temp > 100) + { + errorID = 7; + } + + char outstr[6]; + dtostrf(hdc1080Temp, 5, 2, outstr); + TempAv = atof(outstr); + dtostrf(hdc1080Hum, 5, 2, outstr); + HumAv = atof(outstr); + + + for (int g = 0; g <= 5; g++) { delay(1000); if (ccs.available()) { if (!ccs.readData()) { - // ccs.readAlgorithmResults(); + ccs.setEnvironmentalData(hdc1080Hum-55,hdc1080Temp-25); eco2 = ccs.geteCO2(); tvoc = ccs.getTVOC(); - Serial.println(ccs.geteCO2()); - Serial.println(ccs.getTVOC()); - - Serial.print("baseline: "); - Serial.println(ccs.getBaseline()); - - Serial.print("CurrentSelected: "); - Serial.println(ccs.getCurrentSelected()); - - Serial.print("RawADCreading: "); - Serial.println(ccs.getRawADCreading()); - + BaselineTvoc=ccs.getBaseline(); + Serial.println(eco2); + Serial.println(tvoc); } else { @@ -507,31 +490,6 @@ void reqSensorData() } } - hdc1080Temp = hdc1080.readTemperature(); - hdc1080Hum = hdc1080.readHumidity(); - - if (hdc1080Temp < -40 || hdc1080Temp > 60) - { - errorID = 6; - } - - if (hdc1080Hum < 0 || hdc1080Temp > 100) - { - errorID = 7; - } - - Serial.println("Original data: "); - Serial.print(hdc1080.readTemperature()); - Serial.print(" "); - Serial.println(hdc1080.readHumidity()); - - Serial.println("Calibration data: "); - Serial.print(hdc1080Temp); - Serial.print(" "); - Serial.println(hdc1080Hum); - - TempAv = hdc1080Temp; - HumAv = hdc1080Hum; Eco2Av = eco2; TvocAv = tvoc; @@ -553,16 +511,25 @@ int SendMqttReq(bool sendVal = true, bool sendStatus = true, byte statusConn = 1 doc["h"] = HumAv; doc["eco"] = (int)Eco2Av; doc["tvoc"] = (int)TvocAv; - doc["ligh"] = (int)map(analogRead(33), 0, 4095, 0, 100); + doc["blt"]= BaselineTvoc; + if (macc == "24A1605423AC") + { + doc["ligh"] = (int)map(analogRead(33), 0, 4095, 0, 100); + } doc["ts"] = timeNow; serializeJson(doc, JsonData); - doc.remove("t"); + doc.remove("t"); doc.remove("h"); doc.remove("eco"); doc.remove("tvoc"); - doc.remove("ligh"); + doc.remove("blt"); + + if (macc == "24A1605423AC") + { + doc.remove("ligh"); + } doc.remove("ts"); doc.clear(); @@ -576,7 +543,6 @@ int SendMqttReq(bool sendVal = true, bool sendStatus = true, byte statusConn = 1 if (sendStatus == true) { const char *conn; - switch (statusConn) { case 1: @@ -598,7 +564,6 @@ int SendMqttReq(bool sendVal = true, bool sendStatus = true, byte statusConn = 1 doc["conn"] = conn; doc["rssi"] = rssi; doc["bsid"] = WiFi.BSSIDstr(); - //doc["lasterror"] = errorID; doc["ts"] = timeNow; doc["sv"] = VersionSW; @@ -621,7 +586,7 @@ void reconnectMqtt() byte circle = 0; while (!MqttClient.connected()) { - ////Serial.print("MQTT reconnect..."); + Serial.print("MQTT reconnect..."); circle++; if (circle == 2) @@ -632,13 +597,10 @@ void reconnectMqtt() String maccrandom = macc + String(random(0xffff), HEX); const char *clientId = maccrandom.c_str(); - //const char *id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage - ////Serial.println(clientId); - if (MqttClient.connect(clientId, bufWillTopic, 2, true, willmess)) { Serial.println("MqttClient.connect() - OK"); - errorID = 8; + mqttSendFlag = true; SendMqttReq(false, true, 1); @@ -660,7 +622,7 @@ void reconnectMqtt() 5 : MQTT_CONNECT_UNAUTHORIZED - the client was not authorized to connect */ mqttSendFlag = false; - delay(3000); + delay(1000); } } } @@ -673,54 +635,49 @@ void loop() if (!MqttClient.connected()) { reconnectMqtt(); - ledset('w', true); + ledset(1, true); } - //Если не определен IP то и не будет отправки. - // 40 секунд и происходит сброс настроек WIFI - if (M5.Btn.isPressed()) + if (countOta >= 10) { - ledset('r', true); - checkButton(); - } - - if (millis() - timingUpdate > nextM5Update) - { - reqNtpTime(); + // reqNtpTime(); OTAUpdate(); - timingUpdate = millis(); + countOta = 0; } + countOta++; reqSensorData(); - ledset('g', true); + SetCallibrationCoeff(macc); SendMqttReq(true, true, 3); MqttClient.loop(); disconnectMQTT(); delay(500); + + if (M5.Btn.pressedFor(1000)) + { + ledset(4, true); + checkButton(); + } + goToSleep(); } int disconnectMQTT() { - MqttClient.disconnect(); + MqttClient.disconnect(); return 0; } int goToSleep() { - ledset(); + ledset(3, true); WiFi.disconnect(true); WiFi.mode(WIFI_OFF); - // adc_power_off(); esp_wifi_stop(); - // rtc_gpio_init(pinWak); - // rtc_gpio_set_direction(pinWak, RTC_GPIO_MODE_OUTPUT_ONLY); - // rtc_gpio_set_level(pinWak, 0); - esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR); esp_deep_sleep_start(); diff --git a/M5Atom_airqa.ino.m5stick_c.bin b/M5Atom_airqa.ino.m5stick_c.bin index a5d0b15..691c2e6 100644 Binary files a/M5Atom_airqa.ino.m5stick_c.bin and b/M5Atom_airqa.ino.m5stick_c.bin differ diff --git a/data.xlsx b/data.xlsx new file mode 100644 index 0000000..5b45791 Binary files /dev/null and b/data.xlsx differ diff --git a/pdf/Документ Microsoft Word.docx b/pdf/Документ Microsoft Word.docx new file mode 100644 index 0000000..e69de29