From 3f9ef8347babb5245ca4b6651ef76c0cdf6a9320 Mon Sep 17 00:00:00 2001 From: SmartUaWIn Date: Mon, 1 Mar 2021 23:02:38 +0200 Subject: [PATCH] =?UTF-8?q?=D0=92=D1=81=D0=B5=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0=D0=B5=D1=82.=20=D0=A3=D1=81=D1=82=D0=B0=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BA=D0=B0=20=D1=87=D0=B5=D1=80=D0=B5=D0=B7=20?= =?UTF-8?q?=D0=BD=D0=BE=D0=BB=D1=8C,=20=D0=B1=D0=B5=D0=B7=20=D0=BE=D0=B1?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D0=B2=D0=BE=D0=B7=D0=B4=D1=83=D1=85=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AAOffice_vent.ino | 259 ++++++++++++++++++++++++++++++---------------- README.md | 11 +- 2 files changed, 179 insertions(+), 91 deletions(-) diff --git a/AAOffice_vent.ino b/AAOffice_vent.ino index fcef6a1..c3e7130 100644 --- a/AAOffice_vent.ino +++ b/AAOffice_vent.ino @@ -1,13 +1,13 @@ /* -Отправка данных на MQTT про обновление +Управление сервоприводом MQTT */ - +#include #include // https://github.com/tzapu/WiFiManager #include //Сохранение настроек хеша прошивки #include #include //Библиотека ОТА обновлений -#include "M5Atom.h" //Библиотека атома для функции Led и Кнопки, можно упразднить и убрать +//#include "M5Atom.h" //Библиотека атома для функции Led и Кнопки, можно упразднить и убрать #include //Udp клиент #include //NTP запрос времени @@ -17,19 +17,18 @@ #include //Mtqq #include //Упакова в JSon - удобная библиотека #include -#include +#include //Наша кнопочка при нажатии на которую произойдет вызов wifi менеджера и перезагрузка в станцию #define TRIGGER_PIN 39 -#define safetyPin 26 -#define safetyPinOutput 32 - unsigned int VersionSW = 1; //65536 Версия прошивки -Servo servoAir; -int posServo = 0; +Servo servoAir; +int posServo = 0; +int posServoLast = 0; +byte errorID = 0; WiFiManager wm; // обьект менеджера WiFiManagerParameter custom_field; @@ -44,43 +43,57 @@ PubSubClient MqttClient(espClient); WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, "0.ua.pool.ntp.org", 7200, 60000); //Собственно сервер времени смещение и частоат запроса, но он вручную +const char *spacePref = "ota-config"; const PROGMEM char *mqttHostName = "cctv.automation.art"; //Хостнейм брокера 192.168.89.210 cctv.automation.art:8889 unsigned int mqttPort = 8889; //Порт брокера 1883 -const PROGMEM char *topicName = "/aastudio/sw8"; // +mac адресс девайса Префикс топика -const PROGMEM char *topicNameSub = "/aastudio/sw8/angle"; -const PROGMEM char *mqttLogin = "tt", //Логин пароль - необходимо сменить код при connect() - *mqttPass = "tt"; + +const PROGMEM char *mqttLogin = NULL, //Логин пароль - необходимо сменить код при connect() + *mqttPass = NULL; const char *mqttIPHost; //тут хранится IP хоста по хостнейму unsigned long timingUpdate, timingReqSensor, timingSendMqtt, timingAjaxUpdate; //Таймеры для millis() int PROGMEM nextM5Update = 450000; //каждые 7.5 минут запрос обновления с сервера int PROGMEM nextReqSensor = 10000; //опрос датчиков раз в 10 секунд -int PROGMEM nextMqttSend = 3000; //Отправка -int PROGMEM nextAjaxUpdate = 30000; +int PROGMEM nextMqttSend = 3000; -String macc = ""; //Глобальное хранение мас адреса +String getMacAddress(); +String macc = getMacAddress(); bool mqttSendFlag = false; -bool safetyStateNow = false, safetyStateOld = false; int reqCounter = 0; long rssi = 0; +byte MapAngle, SetAngle, SpeedAngle=10; + +char bufTopic[140], bufWillTopic[150], bufAngleTopic[150]; + //Настройки void setup() { M5.begin(true, false, true); - delay(50); + M5.Power.begin(); + M5.Lcd.clear(WHITE); + M5.Lcd.setTextSize(4); + M5.Lcd.setTextColor(BLACK); + servoAir.attach(17); - pinMode(safetyPin, INPUT); //Пин датчика для работы - pinMode(safetyPinOutput, OUTPUT); // Установка пина на выход - digitalWrite(safetyPinOutput, HIGH); //Потому что он 3.3В а не 5 как на выходе рядом + String topicTemp = "/aastudio/" + macc; + String willTopicTemp = topicTemp + "/status"; + String angleTopicTemp = topicTemp + "/setangle"; + + Serial.println(topicTemp); + Serial.println(willTopicTemp); + Serial.println(angleTopicTemp); + + topicTemp.toCharArray(bufTopic, topicTemp.length() + 1); + willTopicTemp.toCharArray(bufWillTopic, willTopicTemp.length() + 1); + angleTopicTemp.toCharArray(bufAngleTopic, angleTopicTemp.length() + 1); - servoAir.attach(17); WiFi.mode(WIFI_STA); Serial.begin(115200); - Serial.setDebugOutput(true); + //Serial.setDebugOutput(true); delay(100); Serial.println("\n Starting station"); @@ -103,7 +116,7 @@ void setup() } else { - Serial.println("connected - OK"); + Serial.println("connected client - OK"); } //Запрос IP сервера MQTT и установка сервера @@ -147,7 +160,6 @@ void setServCall(IPAddress SetIpaddr) { MqttClient.setServer(SetIpaddr, mqttPort); MqttClient.setCallback(callback); - Serial.println("Set MQTT Server - OK"); } //Функция получения данных из MQTT если мы подпишемся на топики @@ -164,33 +176,69 @@ void callback(char *topic, byte *payload, unsigned int length) Serial.print((char)payload[i]); jsonResult[i] = (char)payload[i]; } - + DeserializationError error = deserializeJson(docResult, jsonResult); if (error) { Serial.print(F("deserializeJson() failed: ")); //Serial.println(String(error)); - return; + return; } - // {"setangle":20,"timer":0,"timerangle": 10} + // {"angle":20} //сделать проверку на байті - byte SetAngle = docResult["setangle"]; - byte isTimer = docResult["timer"]; - byte isTimerAngle = docResult["timerangle"]; - - servoAir.write(SetAngle); - + SetAngle = docResult["percent"]; + SpeedAngle = docResult["speed"]; //0-100 + + // byte isTimer = docResult["timer"]; + // byte isTimerAngle = docResult["timerangle"]; Serial.println(SetAngle); - Serial.println(isTimer); - Serial.println(isTimerAngle); - + if (SetAngle >= 0 || SetAngle <= 100) + { + MapAngle = map(SetAngle, 0, 100, 2, 178); + // 544 мкс — для 0° и 2400 мкс — для 180°. + + if (posServo < MapAngle) + { + + for (int tok = posServo; tok <= MapAngle; tok++) + { + servoAir.write(tok); + delay(SpeedAngle); + } + } + else + { + + for (int tok = posServo; tok >= MapAngle; tok--) + { + servoAir.write(tok); + delay(SpeedAngle); + } + } + + //servoAir.write(SetAngle); + posServo = (int)MapAngle; + + OTApreferences.begin(spacePref, false); + + OTApreferences.putString("stateangle", String(MapAngle)); + + //char anglePref[4] = OTApreferences.getString("stateangle"); + Serial.println("OTApreferences.getString(stateangle)"); + Serial.println(OTApreferences.getString("stateangle")); + + OTApreferences.end(); + } + + // Serial.println(isTimer); + // Serial.println(isTimerAngle); Serial.println(); -} +} //Запрос времени NTP и установка локлаьного времени void reqNtpTime() @@ -206,27 +254,15 @@ void reqNtpTime() //Нажатие кнопки для сброса void checkButton() { - Serial.println("Button Pressed"); - // delay(3000); - // if (digitalRead(TRIGGER_PIN) == LOW) { - Serial.println("Erasing Config, restarting"); + disconnectMQTT(); wm.resetSettings(); ESP.restart(); - // } - // start portal w delay - Serial.println("Starting config portal"); - wm.setConfigPortalTimeout(120); +} - if (!wm.startConfigPortal("AirAnglePortal", "12345678")) //Логин и пароль точки доступа - { - Serial.println("failed to connect or hit timeout"); - delay(3000); - // ESP.restart(); - } - else - { - Serial.println("CLIENT connect"); - } +void saveParamCallback() +{ + Serial.println("[CALLBACK] saveParamCallback fired"); + Serial.println("PARAM customfieldid = " + getParam("customfieldid")); } String getParam(String name) @@ -239,12 +275,6 @@ String getParam(String name) return value; } -void saveParamCallback() -{ - Serial.println("[CALLBACK] saveParamCallback fired"); - Serial.println("PARAM customfieldid = " + getParam("customfieldid")); -} - //Обновление прошивки, происходит проверка и загрузка //Делается Get запрос на хостинг проверяется хеш, если хеш void OTAUpdate() @@ -254,7 +284,7 @@ void OTAUpdate() String keyOTA; String payload; - OTApreferences.begin("ota-config"); + OTApreferences.begin(spacePref, false); if (WiFi.status() == WL_CONNECTED) { @@ -348,6 +378,29 @@ void OTAUpdate() OTApreferences.end(); } +void ledset(char color, bool blink = false) +{ + // M5.dis.setBrightness(120); //Половина яркости + 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() { @@ -364,11 +417,13 @@ void SendMqttReq() Serial.println("Data in SendMqttReq()"); rssi = WiFi.RSSI(); - // doc["mac"] = String(getMacAddress()); - doc["swver"] = VersionSW; - doc["anglestate"] = String(servoAir.read()); - doc["rssi"] = rssi; - doc["time"] = now(); + // doc["mac"] = String(getMacAddress()); + doc["swver"] = VersionSW; + doc["anglestate"] = String(servoAir.read()); + doc["percent"] = SetAngle; + doc["rssi"] = rssi; + doc["lasterror"] = errorID; + doc["time"] = now(); char resultString[200]; String JsonData = ""; @@ -377,14 +432,19 @@ void SendMqttReq() Serial.println(JsonData); //Вывод JSON строки в консоль JsonData.toCharArray(resultString, JsonData.length() + 1); - String finishTopic = ""; - finishTopic = String(topicName) + "/" + macc; - Serial.println(finishTopic); if (mqttSendFlag == true) { - MqttClient.publish(finishTopic.c_str(), resultString); + MqttClient.publish(bufTopic, resultString, true); //Serial.println("SentToTopic - ok"); } + M5.Lcd.clear(WHITE); + M5.Lcd.setCursor(50, 50); + M5.Lcd.setTextColor(BLACK); + M5.Lcd.print(posServo); M5.Lcd.println(" <"); + + M5.Lcd.setCursor(50, 150); + M5.Lcd.setTextColor(BLACK); + M5.Lcd.print(SetAngle); M5.Lcd.println(" %"); } //Переподключение при петери связи с MQTT @@ -408,22 +468,34 @@ void reconnectMqtt() const char *clientId = macc.c_str(); //macc += String(random(0xffff), HEX); - if (MqttClient.connect(clientId)) //mqttLogin, mqttPass + if (MqttClient.connect(clientId, bufWillTopic, 2, true, "OFFLINE")) //mqttLogin, mqttPass { - String finishTopic = ""; - finishTopic = String(topicName) + "/" + macc; - MqttClient.publish(finishTopic.c_str(), "Reconnect NOW and Subscribe"); + MqttClient.publish(bufTopic, "CONNECT", true); + MqttClient.publish(bufWillTopic, "ONLINE", true); - MqttClient.subscribe(topicNameSub); + MqttClient.subscribe(bufAngleTopic); - Serial.print("Connect MQTT OK"); mqttSendFlag = true; } else { - Serial.print("failed, rc="); - Serial.println(MqttClient.state()); + + ////Serial.print("MqttClient.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(3000); } } } @@ -434,33 +506,40 @@ void loop() M5.update(); if (!MqttClient.connected()) { - reconnectMqtt(); + reconnectMqtt(); } //Если не определен IP то и не будет отправки. // 40 секунд и происходит сброс настроек WIFI - if (M5.Btn.wasReleasefor(40000)) - { - checkButton(); - } + // if (M5.Btn.wasReleasefor(40000)) + // { + // checkButton(); + // } //По таймеру запруск обновления прошивки if (millis() - timingUpdate > nextM5Update) { reqNtpTime(); OTAUpdate(); - // Serial.print("OTAUpdate() - "); + Serial.print("OTAUpdate() "); // Serial.println(millis()); timingUpdate = millis(); } - //Таймер отправки данных в брокер - - if (millis() - timingSendMqtt > nextMqttSend) + if (posServo != posServoLast) { + SendMqttReq(); - timingSendMqtt = millis(); + + posServoLast = posServo; } MqttClient.loop(); } + +int disconnectMQTT() +{ + MqttClient.publish(bufTopic, "DISCONNECTED", true); + MqttClient.disconnect(); + return 0; +} \ No newline at end of file diff --git a/README.md b/README.md index 1758aae..9206076 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ # AAOffice_vent -управление задвижкой вентиляции \ No newline at end of file +управление задвижкой вентиляции + + +Топики и данные + + + Дешевые сервы (а тем более - дешевые клоны дешевых серв) - они не для точного поградусного движения. Более того - нет никакой гарантии, что они будут двигаться на разные градусы с одной и той же скоростью. + + + Сервопривод не имеет обратной связи по углу (для программы), поэтому при запуске будет “резко” повёрнут на стартовый угол (“в ноль” по умолчанию или на указанный в attach(pin, target) \ No newline at end of file