После работы в лабе

master
SmartUbuntu 2021-08-31 13:36:25 +03:00
parent c6348a6706
commit 7aa65c26a0
13 changed files with 793 additions and 10 deletions

17
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,17 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/home/smart/Arduino/libraries/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}

View File

@ -18,16 +18,29 @@
#include <ESPmDNS.h>
#include <ESP32Servo.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 26
//Наша кнопочка при нажатии на которую произойдет вызов wifi менеджера и перезагрузка в станцию
#define TRIGGER_PIN 39
#define SERVO_PIN 33
unsigned int VersionSW = 5; //65536 Версия прошивки
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress insideThermometer;
unsigned int VersionSW = 8; //65536 Версия прошивки
//2 поиск по metrics local
//3 -
//4 - тестовая для проверки загрузки прошивки
//5 - логин и пароль
//5 - логин и пароль
//7- температура
//8 атач
Servo servoAir;
int posServo = 0;
@ -47,17 +60,21 @@ PubSubClient MqttClient(espClient);
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "192.168.89.210", 0, 30000); //Собственно сервер времени смещение и частоат запроса, но он вручную
float tempC=0;
const char *spacePref = "ota-config";
const PROGMEM char *mqttHostName = "metrics"; //Хостнейм брокера 192.168.89.210 cctv.automation.art:8889
unsigned int mqttPort = 1883; //Порт брокера 1883
unsigned int mqttPort = 1883; //Порт брокера 1883
const PROGMEM char *mqttLogin = "AA_Lab", //Логин пароль - необходимо сменить код при connect()
*mqttPass = "automation.art$";
const char *mqttIPHost; //тут хранится IP хоста по хостнейму
unsigned long timingUpdate, timingReqSensor, timingSendMqtt, timingAjaxUpdate; //Таймеры для millis()
unsigned long timingUpdate,timingUpdateDS, timingReqSensor, timingSendMqtt, timingAjaxUpdate; //Таймеры для millis()
int PROGMEM nextM5Update = 60000; //450000 //каждые 7.5 минут запрос обновления с сервера
int PROGMEM nextM5UpdateDS = 10000; //450000 //каждые 7.5 минут запрос обновления с сервера
String getMacAddress();
String macc = getMacAddress();
@ -94,10 +111,28 @@ void ledset(char color, bool blink = false)
}
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if(tempC == DEVICE_DISCONNECTED_C)
{
Serial.println("Error: Could not read temperature data");
return;
}
Serial.print("Temp C: ");
Serial.print(tempC);
}
//Настройки
void setup()
{
M5.begin(true, false, true);
servoAir.attach(SERVO_PIN);
sensors.begin();
sensors.setResolution(insideThermometer, 9);
pinMode(SERVO_PIN, OUTPUT);
digitalWrite(SERVO_PIN, LOW);
@ -144,7 +179,8 @@ void setup()
}
//Запрос IP сервера MQTT и установка сервера
setMqttServer();
setMqttServer();
reqNtpTime();
reqNtpTime();
firstStart();
@ -213,7 +249,7 @@ void moveServo(int SetAngleTmp, int SpeedAngleTmp, int posServoTmp)
if ((SetAngleTmp >= 0 && SetAngleTmp <= 100) && (SpeedAngleTmp >= 0 && SpeedAngleTmp <= 50))
{
servoAir.attach(SERVO_PIN);
MapAngle = map(SetAngleTmp, 0, 100, 2, 178);
// 544 мкс — для 0° и 2400 мкс — для 180°.
@ -251,7 +287,7 @@ void moveServo(int SetAngleTmp, int SpeedAngleTmp, int posServoTmp)
OTApreferences.end();
servoAir.detach();
// servoAir.detach();
}
@ -460,8 +496,8 @@ void SendMqttReq()
doc["anglestate"] = posServo;
servoAir.detach();
doc["percent"] = SetAngle;
doc["rssi"] = rssi;
doc["lasterror"] = errorID;
doc["rssi"] = rssi;
doc["t"]=tempC;
doc["time"] = now();
char resultString[200];
@ -559,6 +595,29 @@ void loop()
SendMqttReq();
posServoLast = posServo;
}
if (millis() - timingUpdateDS > nextM5UpdateDS)
{
sensors.requestTemperatures();
SendMqttReq();
tempC = sensors.getTempCByIndex(0);
// Check if reading was successful
if(tempC != DEVICE_DISCONNECTED_C)
{
Serial.print("Temperature for the device 1 (index 0) is: ");
Serial.println(tempC);
}
else
{
Serial.println("Error: Could not read temperature data");
}
timingUpdateDS = millis();
}
MqttClient.loop();
}

Binary file not shown.

5
tenzo/tenzosensor/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

View File

@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

View File

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

View File

@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x1E0000,
app1, app, ota_1, 0x1F0000,0x1E0000,
spiffs, data, spiffs, 0x3D0000,0x30000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x1E0000
5 app1 app ota_1 0x1F0000 0x1E0000
6 spiffs data spiffs 0x3D0000 0x30000

View File

@ -0,0 +1,16 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:m5stack-atom]
platform = espressif32
board = m5stack-atom
framework = arduino
lib_extra_dirs = /home/smart/Arduino/libraries
board_build.partitions = min_spiffs.csv

View File

@ -0,0 +1,577 @@
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
#include <Preferences.h> //Сохранение настроек хеша прошивки
#include <HTTPClient.h>
#include <ESP32httpUpdate.h> //Библиотека ОТА обновлений
#include "M5Atom.h" //Библиотека атома для функции Led и Кнопки, можно упразднить и убрать
#include <WiFiUdp.h> //Udp клиент
#include <NTPClient.h> //NTP запрос времени
#include <TimeLib.h> //Внутреннее время
#include <Wire.h> //Библиотека дял I2C
#include <PubSubClient.h> //Mtqq
#include <ArduinoJson.h> //Упакова в JSon - удобная библиотека
#include <ESPmDNS.h>
#include <Q2HX711.h>
// aastudio/act/24A16053B7C4/data/0
#define BPin 21
#define APin 25
const byte hx711_data_pin = 26;
const byte hx711_clock_pin = 32;
#define TRIGGER_PIN 39
unsigned int VersionSW = 5;
Q2HX711 hx711(hx711_data_pin, hx711_clock_pin);
//3 - Первый код для тензо
WiFiManager wm; // обьект менеджера
Preferences OTApreferences; //Обьект хранения настроек хеша прошивки
String JsonData;
StaticJsonDocument<200> doc, docResult;
WiFiClient espClient;
PubSubClient MqttClient(espClient);
IPAddress IpMqtt;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "192.168.89.210", 0, 20000); //Собственно сервер времени смещение и частоат запроса, но он вручную
const PROGMEM char *willmess = "{\"conn\":\"err\"}";
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/act/" + macc + "/data/0";
String setTopic = "aastudio/act/" + macc + "/set/0";
String willTopicTemp = "aastudio/act/" + macc + "/status";
const PROGMEM char *mqttLogin = "AA_Lab", *mqttPass = "automation.art$";
byte setPercent = 0, setSpeedAnemo = 0;
int stateResistor = 0;
const char *mqttIPHost; //тут хранится IP хоста по хостнейму
unsigned long timingUpdate = 0, timingReqSensor = 0, timingSendMqtt = 0; //Таймеры для millis()
int PROGMEM nextM5Update = 450000, nextMqttSend = 5000; //каждые 7.5 минут запрос обновления с сервера
bool mqttSendFlag = false;
int reqCounter = 0;
long rssi = 0, minRes=1480, maxRes=2600;
char bufTopic[140], bufWillTopic[150], bufSetTopic[150];
int moveAnemo(byte percent);
int setMotor(bool Finput, int Binput);
//void callback(char *topic, byte *payload, unsigned int length);
int disconnectMQTT();
int SendMqttReq(bool sendVal, bool sendStatus, byte statusConn);
const int NUM_READ = 16; // количество усреднений для средних арифм. фильтров
float expRunningAverageAdaptive(float newVal) {
static int t = 0;
static int vals[NUM_READ];
static int average = 0;
if (++t >= NUM_READ) t = 0; // перемотка t
average -= vals[t]; // вычитаем старое
average += newVal; // прибавляем новое
vals[t] = newVal; // запоминаем в массив
return ((float)average / NUM_READ);
}
void ledset(byte color = 0)
{
M5.dis.setBrightness(60); //Половина яркости
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, 0xffffff); //Белый
break;
case 5:
M5.dis.drawpix(0, 0xffec00); //желтый
break;
default:
M5.dis.clear();
break;
}
}
//Настройки
int getIpBlock(int index, String str)
{
char separator = '.';
int found = 0;
int strIndex[] = {0, -1};
int maxIndex = str.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++)
{
if (str.charAt(i) == separator || i == maxIndex)
{
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i + 1 : i;
}
}
return found > index ? str.substring(strIndex[0], strIndex[1]).toInt() : 0;
}
IPAddress str2IP(String str)
{
IPAddress ret(getIpBlock(0, str), getIpBlock(1, str), getIpBlock(2, str), getIpBlock(3, str));
return ret;
}
int setMqttServer(const char *mqttHostNameF, unsigned int mqttPortF)
{
mdns_init();
IPAddress ipaddr;
OTApreferences.begin("ota-config");
OTApreferences.putString("mqttip", "0");
delay(1000);
String keyIpMqtt = OTApreferences.getString("mqttip", "0");
Serial.print("keyIpMqtt: ");
Serial.println(keyIpMqtt);
if (keyIpMqtt == "0")
{
//Запрос по хостнейму .local
ipaddr = MDNS.queryHost(mqttHostNameF, 4000);
//Таймаут 4 секунды
//Если не получили по хостнейму МДНС
Serial.print("mdns: ");
Serial.println(ipaddr);
if (ipaddr.toString() == "0.0.0.0")
{
//Запрос к ДНС по адресу сайта
int err = WiFi.hostByName(mqttHostNameF, ipaddr);
////real internal timeout in lwip library is 14[s]
//Если получили по хостнейму
if (err == 1)
{
Serial.print("hostByName: ");
Serial.println(ipaddr);
MqttClient.setServer(ipaddr, mqttPortF);
OTApreferences.putString("mqttip", ipaddr.toString());
}
else
{
Serial.print("All method not FOUND IP");
}
}
else
{ //Если все хорошо
OTApreferences.putString("mqttip", ipaddr.toString());
MqttClient.setServer(ipaddr, mqttPortF);
}
}
else
{
MqttClient.setServer(str2IP(keyIpMqtt), mqttPortF);
}
//MqttClient.setCallback(callback);
OTApreferences.end();
return 0;
}
//Запрос времени NTP и установка локлаьного времени
int reqNtpTime()
{
if (timeClient.update())
{
uint32_t timeEpoch = timeClient.getEpochTime();
if (timeEpoch < 1600000000)
{
Serial.println("Error reqNtpTime() Time");
return 1;
}
setTime(timeEpoch);
// Serial.print(timeEpoch);
// Serial.print(" <=ntp== ==device=> ");
// Serial.println(now());
}
return 0;
}
// //{"percent":50,"speed":20}
// void callback(char *topic, byte *payload, unsigned int length)
// {
// Serial.print("Message arrived [");
// Serial.print(topic);
// Serial.print("] ");
// char jsonResult[250];
// for (int i = 0; i < length; i++)
// {
// Serial.print((char)payload[i]);
// jsonResult[i] = (char)payload[i];
// }
// DeserializationError error = deserializeJson(docResult, jsonResult);
// if (error)
// {
// Serial.print(F("deserializeJson() failed: "));
// return;
// }
// setPercent = (byte)docResult["amount"]; //0-100
// // setSpeedAnemo = (byte)docResult["speed"]; //speed
// }
//Нажатие кнопки для сброса
void checkButton()
{
Serial.println("Button RESET Pressed");
disconnectMQTT();
delay(100);
OTApreferences.begin("ota-config");
OTApreferences.putString("mqttip", "0");
OTApreferences.end();
wm.resetSettings();
ESP.restart();
}
//Обновление прошивки, происходит проверка и загрузка
//Делается Get запрос на хостинг проверяется хеш, если хеш
void OTAUpdate()
{
////Serial.\println("OTAUpdate()");
bool flagOTA = false;
String keyOTA;
String payload;
OTApreferences.begin("ota-config");
if (WiFi.status() == WL_CONNECTED)
{
HTTPClient http;
String serverPath = "http://meteosence.s-host.net/airqa/airquality.php?meteopas=sdsfsd45540dfdfsksfl45&mac = " + macc + " &meteodata = gethash";
http.begin(serverPath.c_str());
int httpResponseCode = http.GET();
if (httpResponseCode > 0)
{
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
payload = http.getString();
Serial.println(payload);
if (payload != "errno" || payload != "errfi")
{
keyOTA = OTApreferences.getString("md5HashOTA");
if (keyOTA.length() <= 0)
{
OTApreferences.putString("md5HashOTA", "undifined");
}
keyOTA = OTApreferences.getString("md5HashOTA");
if (payload != keyOTA)
{
flagOTA = true;
OTApreferences.putString("md5HashOTA", payload);
//Serial.println("flagOTA = true;");
}
}
}
else
{
Serial.print("Error code HTTP: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}
else
{
Serial.println("WiFi Disconnected");
}
if (flagOTA == true)
{
flagOTA = false;
//Serial.println("flagOTA = false;");
t_httpUpdate_return ret = ESPhttpUpdate.update("http://meteosence.s-host.net/airqa/tenzo/tenzo.bin");
//После update ничего не происходит, такая вот особенность.
//Если все прошло хорошо, перезагрузка на новую прошивку
//Serial.print("ret ");
//Serial.println(ret);
switch (ret)
{
case HTTP_UPDATE_FAILED:
//Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
//Serial.println(ESPhttpUpdate.getLastError());
//Serial.println(ESPhttpUpdate.getLastErrorString().c_str());
//Serial.println("HTTP_UPDATE_FAILD Error");
ESP.restart();
break;
case HTTP_UPDATE_NO_UPDATES:
//Serial.println("HTTP_UPDATE_NO_UPDATES");
ESP.restart();
break;
case HTTP_UPDATE_OK:
//Serial.println("HTTP_UPDATE_OK");
ESP.restart();
break;
}
}
OTApreferences.end();
}
//Получение мак адреса
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);
}
//Отправка данных по MQTT
int SendMqttReq(bool sendVal = true, bool sendStatus = true, byte statusConn = 1)
{
if (mqttSendFlag == true)
{
char resultString[200];
String JsonData = "";
rssi = WiFi.RSSI();
unsigned long timeNow = now();
doc["filter"] = digitalRead(BPin);
doc["preassure"] = expRunningAverageAdaptive((hx711.read()/1000));
doc["ts"] = timeNow;
serializeJson(doc, JsonData);
doc.remove("ts");
doc.remove("preassure");
doc.remove("filter");
doc.clear();
doc.garbageCollect();
Serial.println(JsonData); //Вывод JSON строки в консоль
JsonData.toCharArray(resultString, JsonData.length() + 1);
MqttClient.publish(bufTopic, resultString, true);
if (sendStatus == true)
{
const char *conn;
switch (statusConn)
{
case 1:
conn = "on";
break;
case 2:
conn = "off";
break;
case 3:
conn = "slp";
break;
case 4:
conn = "upd";
break;
default:
break;
}
doc["conn"] = conn;
doc["rssi"] = rssi;
doc["bsid"] = WiFi.BSSIDstr();
doc["ts"] = timeNow;
doc["exp"] = timeNow + 20000;
doc["sv"] = VersionSW;
JsonData = "";
serializeJson(doc, JsonData);
Serial.println(JsonData); //Вывод JSON строки в консоль
doc.clear();
doc.garbageCollect();
JsonData.toCharArray(resultString, JsonData.length() + 1);
MqttClient.publish(bufWillTopic, resultString, true);
}
}
return 0;
}
//Переподключение при петери связи с MQTT
//7 раз проверили и вернулись в общий цикл что бы вдруг что втянуть обновления
void reconnectMqtt()
{
byte circle = 0;
while (!MqttClient.connected())
{
circle++;
if (circle == 5)
{
break;
}
String maccrandom = macc + String(random(0xffff), HEX);
const char *clientId = maccrandom.c_str();
if (MqttClient.connect(clientId, mqttLogin, mqttPass, bufWillTopic, 2, true, willmess))
{
Serial.println("Mqttconnect - OK");
mqttSendFlag = true;
// MqttClient.subscribe(bufSetTopic);
SendMqttReq(false, true, 1);
}
else
{
Serial.print("Mqtt.state() = ");
Serial.println(MqttClient.state());
/*
-4 : MQTT_CONNECTION_TIMEOUT - the server didn't respond within the keepalive time
-3 : MQTT_CONNECTION_LOST - the network connection was broken
-2 : MQTT_CONNECT_FAILED - the network connection failed
-1 : MQTT_DISCONNECTED - the client is disconnected cleanly
0 : MQTT_CONNECTED - the client is connected
1 : MQTT_CONNECT_BAD_PROTOCOL - the server doesn't support the requested version of MQTT
2 : MQTT_CONNECT_BAD_CLIENT_ID - the server rejected the client identifier
3 : MQTT_CONNECT_UNAVAILABLE - the server was unable to accept the connection
4 : MQTT_CONNECT_BAD_CREDENTIALS - the username/password were rejected
5 : MQTT_CONNECT_UNAUTHORIZED - the client was not authorized to connect
*/
mqttSendFlag = false;
delay(500);
}
}
}
void setup()
{
Serial.begin(115200);
Serial.setDebugOutput(true);
M5.begin(true, false, true);
pinMode(APin, OUTPUT);
pinMode(BPin, INPUT);
digitalWrite(APin, HIGH);
delay(50);
pinMode(TRIGGER_PIN, INPUT);
WiFi.mode(WIFI_STA);
delay(100);
Serial.println(setTopic);
Serial.println(topicTemp);
Serial.println(willTopicTemp);
setTopic.toCharArray(bufSetTopic, setTopic.length() + 1);
topicTemp.toCharArray(bufTopic, topicTemp.length() + 1);
willTopicTemp.toCharArray(bufWillTopic, willTopicTemp.length() + 1);
// wm.resetSettings(); // wipe settings
std::vector<const char *> menu = {"wifi", "info", "param", "sep", "restart", "exit"};
wm.setMenu(menu);
// set dark theme
wm.setClass("invert");
wm.setConfigPortalTimeout(30); // auto close configportal after n seconds
wm.setMinimumSignalQuality(10); // set min RSSI (percentage) to show in scans, null = 8%
wm.setScanDispPerc(true); // show RSSI as percentage not graph icons
wm.setWiFiAutoReconnect(true); // if true, enable autoreconnecting
bool res;
res = wm.autoConnect("TensoM5Portal", "12345678"); // Подключение к анонимной точке доступа
if (!res)
{
Serial.println("Failed to connect or hit timeout");
ESP.restart();
}
if (reqNtpTime() == 1)
{
reqNtpTime();
}
setMqttServer(mqttHostName, mqttPort);
}
void loop()
{
M5.update();
if (WiFi.status() != WL_CONNECTED)
{
Serial.println(WiFi.status());
ESP.restart();
}
if (!MqttClient.connected())
{
reconnectMqtt();
}
if (millis() - timingSendMqtt > nextMqttSend)
{
SendMqttReq(true,true,1);
timingSendMqtt = millis();
}
// 40 секунд и происходит сброс настроек WIFI
if (M5.Btn.wasReleasefor(40000))
{
checkButton();
}
//По таймеру запруск обновления прошивки
if (millis() - timingUpdate > nextM5Update)
{
reqNtpTime();
SendMqttReq(false, true, 4);
OTAUpdate();
SendMqttReq(false, true, 1);
timingUpdate = millis();
}
//Таймер отправки данных в брокер
MqttClient.loop();
}
int disconnectMQTT()
{
MqttClient.disconnect();
return 0;
}

View File

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html