Files
AHome/ESP_BigRoom/src/main.cpp
2022-10-15 12:19:44 +03:00

523 lines
17 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "main.h"
MHZ19 myMHZ19;
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
RunningMedian samples = RunningMedian(5 * sizeof(int));
AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
//const char* ssid = "wf-home";
//const char* password = "0ndthnrf";
const char* ssid = "wf-home";
const char* password = "0ndthnrf";
const char* mqtt_server = "192.168.1.111";
void connectToWifi();
void connectToMqtt();
void WiFiEvent(WiFiEvent_t event);
void onMqttConnect(bool sessionPresent);
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
void onMqttSubscribe(uint16_t packetId, uint8_t qos);
void onMqttUnsubscribe(uint16_t packetId);
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total);
void onMqttPublish(uint16_t packetId);
void trim(char *s);
leds bled(LED_B, 300, true);
void setup() {
Serial.begin(115200);
Serial.println("Booting"); // "Загрузка"
WiFi.mode(WIFI_STA);
WiFi.hostname("BigRoom");
// ArduinoOTA.onStart([]() {
// // Serial.println("Start"); // "Начало OTA-апдейта"
// });
// ArduinoOTA.onEnd([]() {
// // Serial.println("\nEnd"); // "Завершение OTA-апдейта"
// });
// ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
// // Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
// });
// ArduinoOTA.onError([](ota_error_t error) {
// // Serial.printf("Error[%u]: ", error);
// // if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
// // // "Ошибка при аутентификации"
// // else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
// // // "Ошибка при начале OTA-апдейта"
// // else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
// // // "Ошибка при подключении"
// // else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
// // // "Ошибка при получении данных"
// // else if (error == OTA_END_ERROR) Serial.println("End Failed");
// // // "Ошибка при завершении OTA-апдейта"
// });
// ArduinoOTA.begin();
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
WiFi.onEvent(WiFiEvent);
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
mqttClient.onSubscribe(onMqttSubscribe);
mqttClient.onUnsubscribe(onMqttUnsubscribe);
mqttClient.onMessage(onMqttMessage);
mqttClient.onPublish(onMqttPublish);
mqttClient.setServer(mqtt_server, 1883);
mqttClient.setClientId("BigRoom");
pinMode(MOVE_SENS, INPUT_PULLUP);
pinMode(LED_R, OUTPUT);
pinMode(LED_G, OUTPUT);
pinMode(LED_B, OUTPUT);
pinMode(POWER, OUTPUT);
pinMode(RECIVER, OUTPUT);
ledcSetup(PWM_WHITE, 5000, 8);
ledcSetup(PWM_BLUE, 5000, 8);
ledcAttachPin(LED_WHITE, PWM_WHITE);
ledcAttachPin(LED_BLUE, PWM_BLUE);
delay(200);
digitalWrite(LED_R, LOW);
digitalWrite(LED_G, HIGH);
digitalWrite(LED_B, HIGH);
Serial2.begin(9600);
myMHZ19.begin(Serial2);
myMHZ19.setRange(); // *Important, Pass your Stream reference here
myMHZ19.autoCalibration(true);
char myVersion[4];
myMHZ19.getVersion(myVersion);
Serial.print("\nFirmware Version: ");
for(byte i = 0; i < 4; i++)
{
Serial.print(myVersion[i]);
if(i == 1)
Serial.print(".");
}
Serial.println("");
Serial.print("Range: ");
Serial.println(myMHZ19.getRange());
Serial.print("Background CO2: ");
Serial.println(myMHZ19.getBackgroundCO2());
Serial.print("Temperature Cal: ");
Serial.println(myMHZ19.getTempAdjustment());
Serial.print("ABC Status: "); myMHZ19.getABC() ? Serial.println("ON") : Serial.println("OFF");
//digitalWrite(P_SENS, LOW);
#undef SDA //delete dafault SDA pin number
#undef SCL //delete dafault SCL pin number
#define SDA 33 //assign new SDA pin to GPIO1/D2/0TX for all slaves on i2c bus
#define SCL 32 //assign new SCL pin to GPIO3/D7/0RX for all slaves on i2c bus
if (!htu.begin(SDA, SCL)) {
Serial.println("Couldn't find sensor!");
while (1);
}
Serial.println("Sensor found!");
char s[7];
EEPROM.begin(10);
EEPROM.get(0, periodMotion);
itoa(periodMotion, s, 10);
mqttClient.publish(TOPIC"", 1, false, s);
//publish period
EEPROM.get(1, spLight);
itoa(spLight, s, 10);
mqttClient.publish(TOPIC"", 1, false, s);
//publish splight
EEPROM.get(3, dbLight);
itoa(dbLight, s, 10);
mqttClient.publish(TOPIC"", 1, false, s);
EEPROM.get(5, levelBlue);
itoa(levelBlue, s, 10);
mqttClient.publish(TOPIC"", 1, false, s);
EEPROM.get(6, levelWhite);
itoa(levelWhite, s, 10);
mqttClient.publish(TOPIC"", 1, false, s);
if(spLight == 65535) {
spLight = 1000;
EEPROM.writeShort(1, spLight);
}
if(dbLight == 65535) {
dbLight = 1000;
EEPROM.writeShort(3, dbLight);
}
if(levelBlue == 255) {
levelBlue = 100;
EEPROM.writeShort(5, levelBlue);
}
if(levelWhite == 255) {
levelWhite = 100;
EEPROM.writeByte(6, levelWhite);
}
if(periodMotion == 255) {
periodMotion = 60;
EEPROM.writeByte(0, periodMotion);
}
EEPROM.commit();
Serial.print(F("PeriodMove:"));Serial.println(periodMotion);
Serial.print(F("SPLight:"));Serial.println(spLight);
Serial.print(F("DBLight:"));Serial.println(dbLight);
Serial.print(F("BLevel:"));Serial.println(levelBlue);
Serial.print(F("WLevel:"));Serial.println(levelWhite);
curDelay = -1;
wLamp = bLamp = false;
statLamp = 0;
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "text/plain", "Hi! I am ESP32.");
});
AsyncElegantOTA.setID("BigRoom");
AsyncElegantOTA.begin(&server); // Start ElegantOTA
WebSerial.begin(&server);
connectToWifi();
}
void loop() {
static uint32_t cRun = millis();
static uint8_t sec = 0;
static uint16_t prevLLevel = 0;
static uint32_t levBlue = 0, levWhite = 0;
static unsigned long levRunB = 0, levRunW = 0;
char s[7];
//ArduinoOTA.handle();
bled.tick();
if(digitalRead(MOVE_SENS) > 0){
if(curDelay == -1){
bled.start();
mqttClient.publish(TOPIC"move", 1, false, "1");
//Serial.println("move");
}
move = true;
curDelay = periodMotion;
}
uint16_t LightLev = analogRead(LIGHT_SENS);
samples.add(LightLev);
LightLev = samples.getMedian();
if ((LightLev < spLight) && move && !bLamp){
levBlue = levelBlue * 2.55;
ledcWrite(PWM_BLUE, levBlue);
statLamp |= 0x01;
bLamp = true;
//Serial.println(F("BLamp On"));
//WebSerial.println(F("Blue Lamp On"));
}
else if((LightLev > (spLight + dbLight)) || (move == 0)){
if((levRunB + 50 <= millis() && levBlue > 0)){
levRunB = millis();
levBlue--;
}
ledcWrite(PWM_BLUE, levBlue);
statLamp &= 0xFE;
bLamp = false;
}
if(lightWhite && !wLamp){
levWhite = levelWhite * 2.55;
ledcWrite(PWM_WHITE, levWhite);
statLamp |= 0x02;
wLamp = true;
Serial.println(F("WLamp On"));
WebSerial.println(F("White Lamp On"));
}
else if (!lightWhite){
if((levRunW + 30 <= millis() && levWhite > 0)){
//WebSerial.println(levWhite);
levRunW = millis();
levWhite--;
}
ledcWrite(PWM_WHITE, levWhite);
statLamp &= 0xFD;
wLamp = false;
}
if(statLamp > 0) digitalWrite(POWER, HIGH);
else if((levBlue == 0) && (levWhite == 0)) digitalWrite(POWER, LOW);
if((cRun + 1000) <= millis()){ //Once per second
cRun = millis();
if(abs(LightLev - prevLLevel) > 100){
itoa(LightLev, s, 10);
mqttClient.publish(TOPIC"lightlev", 1, false, s);
}
prevLLevel = LightLev;
if(curDelay > -1){
Serial.println("ADC: " + String(LightLev) + " MV:" + String(move) + " TMv:" + curDelay + " SL:" + String(statLamp) + " PS:" + digitalRead(POWER));
Serial.println("SPL: " + String(spLight) + " DBL:" + String(dbLight)+ " BL:" + String(bLamp));
}
sec++;
if(curDelay > 0) curDelay--;
if(curDelay == 0){
mqttClient.publish(TOPIC"move", 1, false, "0");
bled.start();
Serial.println("no move");
move = false;
curDelay = -1;
}
if((sec + 2) % 30 == 0){
temp = htu.readTemperature();
hum = htu.readHumidity();
Serial.println("Temp: " + String(temp));
Serial.println("Hum: " + String(hum));
Serial.println(sec);
}
if(sec == 59){
//minuts++;
sec = 0;
// }
// if(minuts == periodMinCO2){
int CO2; // Buffer for CO2
CO2 = myMHZ19.getCO2(); // Request CO2 (as ppm)
if(myMHZ19.errorCode == RESULT_OK) // RESULT_OK is an alis for 1. Either can be used to confirm the response was OK.
{
Serial.println(CO2);
itoa(CO2, s, 10);
bled.start();
mqttClient.publish(TOPIC"co2", 1, false, s);
}
else{
Serial.println("CO2err:" + String(myMHZ19.errorCode));
}
if(temp != 0.0f){
// Serial.println("Send");
// Serial.println("Temp: " + String(temp));
// Serial.println("Hum: " + String(hum));
dtostrf(temp, 6, 1, s);
trim(s);
bled.start();
mqttClient.publish(TOPIC"temp", 1, false, s);
}
if(hum != 0.0f){
dtostrf(hum, 6, 1, s);
trim(s);
mqttClient.publish(TOPIC"hum", 1, false, s);
//sendDataI(msgLight, LightLev);
//minuts = 0;
}
bled.start();
dtostrf(cRun / 60000.0, 6, 1, s);
trim(s);
mqttClient.publish(TOPIC"mins", 1, false, s);
itoa(WiFi.RSSI(), s, 10);
mqttClient.publish(TOPIC"RSSI", 1, false, s);
itoa(LightLev, s, 10);
mqttClient.publish(TOPIC"lightlev", 1, false, s);
}
}
}
void connectToWifi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(ssid, password);
}
void connectToMqtt() {
Serial.println("Connecting to MQTT...");
mqttClient.connect();
}
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
digitalWrite(LED_R, HIGH);
server.begin();
Serial.println("HTTP server started");
connectToMqtt();
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
xTimerStart(wifiReconnectTimer, 0);
server.end();
digitalWrite(LED_R, LOW);
break;
default:
break;
}
}
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);
//uint16_t packetIdSub =
// Serial.print("Subscribing Lamp1, packetId: ");
// Serial.println(packetIdSub);
//packetIdSub =
char s[7];
itoa(periodMotion, s, 10);
mqttClient.publish(TOPIC"moveperiod", 1, false, s);
itoa(levelBlue, s, 10);
mqttClient.publish(TOPIC"lampblevel", 1, false, s);
itoa(levelWhite, s, 10);
mqttClient.publish(TOPIC"lampwlevel", 1, false, s);
itoa(spLight, s, 10);
mqttClient.publish(TOPIC"spLevel", 1, false, s);
itoa(dbLight, s, 10);
mqttClient.publish(TOPIC"dbLevel", 1, false, s);
mqttClient.publish(TOPIC"reciever", 1, false, "0");
mqttClient.publish(TOPIC"lampw", 1, false, lightWhite ? "1" : "0");
mqttClient.publish(TOPIC"lampw_set", 1, false, lightWhite ? "1" : "0");
mqttClient.subscribe(TOPIC"lampblevel", 1);
mqttClient.subscribe(TOPIC"lampwlevel", 1);
//mqttClient.subscribe(TOPIC"lampw", 1);
mqttClient.subscribe(TOPIC"lampw_set", 1);
mqttClient.subscribe(TOPIC"moveperiod", 1);
mqttClient.subscribe(TOPIC"spLevel", 1);
mqttClient.subscribe(TOPIC"dbLevel", 1);
mqttClient.subscribe(TOPIC"reciever", 1);
Serial.print(F("PeriodMove:"));Serial.println(periodMotion);
Serial.print(F("SPLight:"));Serial.println(spLight);
Serial.print(F("DBLight:"));Serial.println(dbLight);
Serial.print(F("BLevel:"));Serial.println(levelBlue);
Serial.print(F("WLevel:"));Serial.println(levelWhite);
//Serial.print("Subscribing Lamp2, packetId: ");
//Serial.println(packetIdSub);
//Serial.println("Publishing at Lamp 1");
//mqttClient.publish("/home/kor/lamp2", 1, false, lStat2 ? "1" : "0");
//Serial.println("Publishing at Lamp 2");
digitalWrite(LED_G, LOW);
}
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");
digitalWrite(LED_R, HIGH);
if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}
void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
// Serial.println("Subscribe acknowledged.");
// Serial.print(" packetId: ");
// Serial.println(packetId);
// Serial.print(" qos: ");
// Serial.println(qos);
}
void onMqttUnsubscribe(uint16_t packetId) {
// Serial.println("Unsubscribe acknowledged.");
// Serial.print(" packetId: ");
// Serial.println(packetId);
}
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
bool w = false;
char pl[20];
strncpy(pl, payload, len);
pl[len] = 0;
Serial.printf("New message - topic %s, payload %s\n", topic, pl);
WebSerial.print("New message - topic ");WebSerial.print(topic);WebSerial.print(", payload ");WebSerial.println(pl);
if(strcmp(topic, TOPIC"lampblevel") == 0){
levelBlue = atoi(pl);
EEPROM.writeByte(5, levelBlue);
Serial.printf("New LevelBlue: %d\n", levelBlue);
WebSerial.print("New LevelBlue: ");WebSerial.println(levelBlue);
w = true;
if(bLamp)
ledcWrite(PWM_BLUE, (levelBlue) * 2.55);
}
if(strcmp(topic, TOPIC"lampwlevel") == 0){
levelWhite = atoi(pl);
Serial.printf("New LevelWite: %d\n", levelWhite);
WebSerial.print("New LevelWhite: ");WebSerial.println(levelWhite);
EEPROM.writeByte(6, levelWhite);
w = true;
if(lightWhite)
ledcWrite(PWM_WHITE, (levelWhite) * 2.55);
}
if(strcmp(topic, TOPIC"lampw_set") == 0){
lightWhite = atoi(pl);
Serial.printf("New LampWhite: %d\n", lightWhite);
WebSerial.print("New LampWhite: ");WebSerial.println(lightWhite);
mqttClient.publish(TOPIC"lampw", 1, false, lightWhite ? "1" : "0");
//EEPROM.put(0, levelBlue);
//w = true;
}
if(strcmp(topic, TOPIC"reciever") == 0){
reciever = atoi(pl);
digitalWrite(RECIVER, reciever);
Serial.printf("New Reciever: %d\n", lightWhite);
WebSerial.print("New Reciever: ");WebSerial.println(lightWhite);
//mqttClient.publish(TOPIC"reciever", 1, false, reciever ? "1" : "0");
//EEPROM.put(0, levelBlue);
//w = true;
}
if(strcmp(topic, TOPIC"moveperiod") == 0){
periodMotion = atoi(pl);
Serial.printf("New MovePeriod: %d\n", periodMotion);
WebSerial.print("New MovePeriod: ");WebSerial.println(periodMotion);
EEPROM.writeByte(0, periodMotion);
w = true;
}
if(strcmp(topic, TOPIC"spLevel") == 0){
spLight = atoi(pl);
Serial.printf("New SPLevel: %d\n", spLight);
WebSerial.print("New SPLevel: ");WebSerial.println(spLight);
EEPROM.writeShort(1, spLight);
w = true;
}
if(strcmp(topic, TOPIC"dbLevel") == 0){
dbLight = atoi(pl);
Serial.printf("New DBLevel: %d\n", dbLight);
WebSerial.print("New DBLevel: ");WebSerial.println(dbLight);
EEPROM.writeShort(3, dbLight);
w = true;
}
if(w) EEPROM.commit();
}
void onMqttPublish(uint16_t packetId) {
// Serial.println("Publish acknowledged.");
// Serial.print(" packetId: ");
// Serial.println(packetId);
//g_led.start();
}
void trim(char *s)
{
// удаляем пробелы и табы с начала строки:
int i=0,j;
while((s[i]==' ')||(s[i]=='\t'))
{
i++;
}
if(i>0)
{
for(j=0; j < strlen(s); j++)
{
s[j]=s[j+i];
}
s[j]='\0';
}
// удаляем пробелы и табы с конца строки:
i=strlen(s)-1;
while((s[i]==' ')||(s[i]=='\t'))
{
i--;
}
if(i < (strlen(s)-1))
{
s[i+1]='\0';
}
}