diff options
| author | vlapa <vlapa@ya.ru> | 2026-06-13 18:38:24 +0300 |
|---|---|---|
| committer | vlapa <vlapa@ya.ru> | 2026-06-13 18:38:24 +0300 |
| commit | 0258932b0c21f28385c2ab3acecbf4eaaa00b399 (patch) | |
| tree | a5dd89d61ce135a75d2bd992c56551a6a48d5a1d /src/main.cpp | |
Firstmain
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 588 |
1 files changed, 588 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..9227cb7 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,588 @@ +//******************************************************************** +//* +//* Tablo na WS2812b + mqtt + bme280 (2) +//* 2021.02.01 - 2025.03.01 +//* +//* A - градус +//* В - минус +//* С - двоеточие +//* D - пусто +//* E - точка +//* F - p +//* G - h +//******************************************************************** +#include <Arduino.h> +#include <WiFi.h> +#include <HTTPUpdateServer.h> +#include <NTPClient.h> +#include <WiFiUdp.h> +#include <PubSubClient.h> + +#include "tablo_ws2812.h" +// #include <string.h> + +#include <WiFiClient.h> +#include <WebServer.h> +#include <ESPmDNS.h> +#include <Update.h> +const char *host = "esp32"; + +const uint8_t TIME_DAY = 8; +const uint8_t TIME_NIGHT = 18; +const uint8_t BRIGHT_DAY = 5; +const uint8_t BRIGHT_NIGHT = 1; + +// const char *ssid = "link"; +const char *ssid = "MikroTik-2"; +const char *pass = "dkfgf#*12091997"; +const char *ntp_server = "ntp3.vniiftri.ru"; +const char *mqtt_server = "89.110.92.137"; +const uint16_t mqtt_port = 1883; +const char *mqtt_user = "mqtt"; +const char *mqtt_pass = "qwe1243"; + +const uint32_t utcOffsetInSeconds = 10800; +const uint32_t utcPeriodMseconds = 86400000; // 86400000-р/сут; 604800000-р/нед + +WiFiUDP ntpUDP; +NTPClient timeClient(ntpUDP, ntp_server, utcOffsetInSeconds, utcPeriodMseconds); + +// const char *mqtt_client = "Tablo_Home_345"; +const char *mqtt_client = "Tablo_Villa-002"; +// const char *mqtt_client2 = "Home_bme280_villa"; +const char *mqtt_client2 = "Villa_bme280_base"; + +const char *inTopic = "/t;p;h;v;;"; +// const char *inTopic_room = "/t;p;h;"; +// const char *inTopic_balkon = "/t;"; + +String temp, pres, hum, vcc; + +// String outTemp_room = "00.00A"; +// String outTemp_balkon = "00.00A"; +// String outPres_room = "000"; +// String outHum_room = "00"; +// String outHum_balkon = "00"; +// String outVolt_room = "00"; +// String outVolt_balkon = "00"; + +WiFiClient espClient; +PubSubClient client(espClient); + +uint32_t timeUpdateH = 02; // время обновления NTP +uint32_t timeUpdateM = 05; // время обновления NTP +String z = ""; // строка данных для отображения + +uint32_t colorTime = 16766720; // цвет часы (желтый) +uint32_t colorTemp = 16711935; // цвет температура (красный) +uint32_t colorTemp2 = 65280; // цвет внешняя температура (зеленый) +uint32_t colorTempOut = 9127187; // цвет температура2 (коричневый) +uint32_t colorPress = 9830400; // цвет давление (розовый) +uint32_t colorWiFi = 16728935; // цвет WiFi (томато) +uint32_t colorHum = 52945; // цвет влажность (бирюзовый) +uint32_t colorHumOut = 255; // цвет влажность2 (синий// Время отображения каждого показания: +// 0-время, 1-темп, 2-давл, 3-влажн, 4-темп2, 5-влажн2 +uint16_t visData[] = {5, 2, 2, 2, 2, 2, 2}; +uint8_t count_data = 4; // сколько еще отображать показаний +uint16_t strOld = 0; +uint8_t count = 0; + +uint32_t timeReadOld = 0; +uint32_t color = 0; + +bool flagSec = true; +bool flagTemp = false; +bool flagTemp2 = false; +bool flagTempOut = false; +bool flagPress = false; +bool flagHum = false; +bool flagHumOut = false; +bool flagVis = true; + +uint32_t timeOld = 0; +uint8_t brightVis = BRIGHT_NIGHT; + +WebServer server(80); +ESP8266HTTPUpdateServer httpUpdater; + +//----------------------------------- +// Login page +const char *loginIndex = + "<form name='loginForm'>" + "<table width='20%' bgcolor='A09F9F' align='center'>" + "<tr>" + "<td colspan=2>" + "<center><font size=4><b>ESP32 Login Page</b></font></center>" + "<br>" + "</td>" + "<br>" + "<br>" + "</tr>" + "<td>Username:</td>" + "<td><input type='text' size=25 name='userid'><br></td>" + "</tr>" + "<br>" + "<br>" + "<tr>" + "<td>Password:</td>" + "<td><input type='Password' size=25 name='pwd'><br></td>" + "<br>" + "<br>" + "</tr>" + "<tr>" + "<td><input type='submit' onclick='check(this.form)' value='Login'></td>" + "</tr>" + "</table>" + "</form>" + "<script>" + "function check(form)" + "{" + "if(form.userid.value=='admin' && form.pwd.value=='admin')" + "{" + "window.open('/serverIndex')" + "}" + "else" + "{" + " alert('Error Password or Username')/*displays error message*/" + "}" + "}" + "</script>"; + +// Server Index Page +const char *serverIndex = + "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>" + "<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>" + "<input type='file' name='update'>" + "<input type='submit' value='Update'>" + "</form>" + "<div id='prg'>progress: 0%</div>" + "<script>" + "$('form').submit(function(e){" + "e.preventDefault();" + "var form = $('#upload_form')[0];" + "var data = new FormData(form);" + " $.ajax({" + "url: '/update'," + "type: 'POST'," + "data: data," + "contentType: false," + "processData:false," + "xhr: function() {" + "var xhr = new window.XMLHttpRequest();" + "xhr.upload.addEventListener('progress', function(evt) {" + "if (evt.lengthComputable) {" + "var per = evt.loaded / evt.total;" + "$('#prg').html('progress: ' + Math.round(per*100) + '%');" + "}" + "}, false);" + "return xhr;" + "}," + "success:function(d, s) {" + "console.log('success!')" + "}," + "error: function (a, b, c) {" + "}" + "});" + "});" + "</script>"; + +//----------------------------------- +inline bool mqtt_subscribe(PubSubClient &client, const String &topic) +{ + Serial.print("Subscribing to: "); + Serial.println(topic); + return client.subscribe(topic.c_str()); +} + +//----------------------------------- +inline bool mqtt_publish(PubSubClient &client, const String &topic, const String &value) +{ + Serial.print("Publishing topic "); + Serial.print(topic); + Serial.print(" = "); + Serial.println(value); + return client.publish(topic.c_str(), value.c_str()); +} + +//----------------------------------- +void reconnect() +{ + // visibleWork("DDDDD", colorWiFi, BRIGHT_DAY); + // strip.show(); + uint8_t countMqtt = 20; + while (!client.connect(mqtt_client, mqtt_user, mqtt_pass)) + { + strip.show(); + if (countMqtt--) + { + visibleWork("0B0B0", colorWiFi, BRIGHT_DAY); + delay(250); + visibleWork("B0B0B", colorWiFi, BRIGHT_DAY); + delay(250); + } + else + { + ESP.restart(); + } + } + + String topic('/'); + topic += mqtt_client2; + topic += inTopic; + mqtt_subscribe(client, topic); + + // topic = '/'; + // topic += mqtt_client3; + // topic += inTopic_balkon; + // mqtt_subscribe(client, topic); + + Serial.println("MQTT - Ok!\n"); +} + +//******************************************************************** +// подключение к WiFi +void setupWiFi() +{ + digitalWrite(LED_BUILTIN, LOW); + Serial.println("\n\nSetup WiFi: "); + visibleWork("ABABA", colorWiFi, BRIGHT_DAY); + strip.show(); + + WiFi.begin(ssid, pass); + uint8_t countWiFi = 20; + while (WiFi.status() != WL_CONNECTED) + { + delay(500); + Serial.print('.'); + if (!countWiFi--) + ESP.restart(); + } + digitalWrite(LED_BUILTIN, HIGH); + + //----------------------------------- + // индикация IP + String l = WiFi.localIP().toString(); + l = l.substring(l.lastIndexOf('.') + 1, l.length()); + + (l.toInt() < 100) ? l = "DDE" + l : l = "DE" + l; + visibleWork(l, colorWiFi, BRIGHT_DAY); + + strip.show(); + Serial.print("\nWiFi connected !\n"); + Serial.println(WiFi.localIP()); + delay(2000); + + //----------------------------------- + // индикация силы сигнала + int16_t RSSI_MAX = -50; + int16_t RSSI_MIN = -100; + int16_t dBm = WiFi.RSSI(); + Serial.print("RSSI dBm = "); + Serial.println(dBm); + l = "DDE"; + (dBm <= RSSI_MIN) ? l += 0 : (dBm >= RSSI_MAX) ? l += 100 + : l += 2 * (dBm + 100); + Serial.print("RSSI % = "); + Serial.println(l); + Serial.println("\n"); + + visibleWork(l, colorWiFi, BRIGHT_DAY); + strip.show(); + delay(2000); + + Serial.println(); + + z = "BBBBB"; + visibleWork(z, colorTemp, BRIGHT_DAY); + strip.show(); + + while (!timeClient.update()) + { + delay(500); + Serial.print('.'); + } + flagVis = true; + count = 0; +} + +//******************************************************************** +// MQTT +void mqtt_callback(char *topic, byte *payload, unsigned int length) +{ + //------------------------ + // Просто печатаем то, что пришло: + // Serial.print(topic); + // Serial.print(" \t"); + // for (uint8_t i = 0; i < length; ++i) + // { + // Serial.print((char)payload[i]); + // } + // Serial.println("---"); + //------------------------ + // + if (!strncmp(topic + 1, mqtt_client2, strlen(mqtt_client2))) + { + char *topicBody = topic + strlen(mqtt_client2) + 1; + if (!strncmp(topicBody, inTopic, strlen(inTopic))) + { + String data_room = ""; + Serial.print(topicBody); + Serial.print(" - "); + for (uint8_t i = 0; i < length; i++) + data_room += (char)payload[i]; + Serial.println(data_room); + temp = data_room.substring(0, data_room.indexOf(";")); + data_room = data_room.substring(data_room.indexOf(";") + 1, data_room.length()); + pres = data_room.substring(0, data_room.indexOf(";")); + data_room = data_room.substring(data_room.indexOf(";") + 1, data_room.length()); + hum = data_room.substring(0, data_room.indexOf(";")); + } + } + // else if (!strncmp(topic + 1, mqtt_client3, strlen(mqtt_client3))) + // { + // char *topicBody = topic + strlen(mqtt_client3) + 1; + // if (!strncmp(topicBody, inTopic_balkon, strlen(inTopic_balkon))) + // { + // String data_balkon = ""; + // Serial.print(topicBody); + // Serial.print(" - "); + // for (uint8_t i = 0; i < length; i++) + // data_balkon += (char)payload[i]; + // Serial.println(data_balkon); + // temp_out = data_balkon.substring(0, data_balkon.indexOf(";")); + // } + // } + + //------------------------ +} + +//******************************************************************** +// пересчет millis() +void TimeMillis() +{ + color = colorTime; + + if (timeClient.getHours() < 10) + z += "D"; + + z += timeClient.getHours(); // часы + (flagSec) ? z += "C" : z += "D"; + + if (timeClient.getMinutes() < 10) + z += "0"; + + z += timeClient.getMinutes(); // минуты + + if ((timeClient.getHours() >= TIME_DAY) && (timeClient.getHours() < TIME_NIGHT)) + { + brightVis = BRIGHT_DAY; + } + else + { + brightVis = BRIGHT_NIGHT; + } +} + +//******************************************************************** +// BME280 +void Temp() +{ + if (temp.charAt(0) == '-') + { + if (temp.indexOf('.') == 2) + { + z = "B" + temp.substring(1, temp.indexOf('.')); + z += 'E' + temp.substring(3, 4); + } + else + { + z = "DB" + temp.substring(1, temp.indexOf('.')); + } + } + else + { + if (temp.indexOf('.') == 2) + { + z = temp.substring(0, temp.indexOf('.')); + z += 'E' + temp.substring(3, 4); + } + else + { + z = 'D' + temp.substring(0, temp.indexOf('.')); + z += 'E' + temp.substring(2, 3); + } + } + temp.substring(0, 1); + + z += 'A'; + color = colorTemp; + flagTemp = true; +} + +void Press() +{ + z += "DD" + pres.substring(0, 3); + color = colorPress; + flagPress = true; +} + +void Hum() +{ + (hum.length() > 2) ? z = "DD" : z = "DDD"; + z += hum.substring(0, 2); + color = colorHum; + flagHum = true; +} + +//******************************************************************** +// запись значений датчиков в память +// void dataWrite(uint8_t n, String str) +// { +// data[n].num = str.substring(0, 1).toInt(); +// if (str.indexOf('%') > 0) +// data[n].hum = str.substring(str.indexOf('%') + 1, str.indexOf('%') + 3).toInt(); +// if (str.indexOf('*') > 0) +// data[n].temp = str.substring(str.indexOf('*') + 1, str.indexOf('*' + 5)).toFloat(); +// if (str.indexOf('$') > 0) +// data[n].press = str.substring(str.indexOf('$') + 1, str.indexOf('$') + 4).toInt(); +// if (str.indexOf('^') > 0) +// data[n].voltage = str.substring(str.indexOf('^') + 1, str.indexOf('^') + 4).toInt(); +// } +//******************************************************************** +// void parserBuf(String tmp) +// { +// if (tmp.substring(0, 2).toInt() == sensorNum_1) +// { +// dataWrite(0, tmp); +// } +// // else if (tmp.substring(0, 2).toInt() == sensorNum_2) +// // { +// // dataWrite(1, tmp); +// // } +// } +//******************************************************************** +// визуальные эффекты +// void show_1() +// { +// strip.clear(); +// for (uint8_t i = 0; i < PIXEL_COUNT / 2; ++i) +// { +// strip.setPixelColor(i, strip.Color(random(1, 255), random(1, 255), random(1, 255))); +// strip.setPixelColor(PIXEL_COUNT - i - 1, strip.Color(random(1, 255), random(1, 255), random(1, 255))); +// strip.show(); +// delay(5); +// } +// delay(500); +// for (uint8_t i = 0; i < PIXEL_COUNT / 2; ++i) +// { +// strip.setPixelColor(i, 0, 0, 0); +// strip.setPixelColor(PIXEL_COUNT - i - 1, 0, 0, 0); +// strip.show(); +// delay(5); +// } +// delay(500); +// z = "DDDDD"; +// } + +//******************************************************************** +void setup() +{ + Serial.begin(115200); + pinMode(LED_BUILTIN, OUTPUT); + digitalWrite(LED_BUILTIN, HIGH); + + strip.begin(); + z = "AAAAA"; + strip.show(); + + client.setServer(mqtt_server, mqtt_port); + client.setCallback(mqtt_callback); + + setupWiFi(); + + timeClient.begin(); + server.begin(); + httpUpdater.setup(&server); + + // visible_effect(); + + timeOld = millis(); +} + +//******************************************************************** +void loop() +{ + // visible_effect(); + + if (WiFi.status() != WL_CONNECTED) + { + setupWiFi(); + } + + if (!client.connected()) + { + reconnect(); + } + + if (flagVis) + { + z = ""; + switch (count) + { + case 0: + { + TimeMillis(); + flagTemp = false; + flagPress = false; + flagHum = false; + flagTempOut = false; + flagHumOut = false; + break; + } + case 1: + { + if (flagTemp == false) + Temp(); + break; + } + case 2: + { + if (flagPress == false) + Press(); + break; + } + case 3: + { + if (flagHum == false) + Hum(); + break; + } + } + flagVis = false; + visibleWork(z, color, brightVis); + // timeReadOld = millis(); + } + + // Отображение секундного тире + if (millis() - timeReadOld >= 500 && (!count)) // || count == 1)) + { + flagSec = !flagSec; + timeReadOld = millis(); + + flagVis = true; + } + + // Счетчик отображаемых данных + if (millis() - timeOld >= (visData[count] * 1000)) + { + (count >= count_data) ? count = 0 : count++; + flagVis = true; + timeOld = millis(); + } + + server.handleClient(); + client.loop(); + delay(1); +} + +//********************************************************************
\ No newline at end of file |
