381 lines
11 KiB
C++
381 lines
11 KiB
C++
#include <main.h>
|
||
#include <ArduinoOTA.h>
|
||
#include <Ticker.h>
|
||
#include <AsyncMqttClient.h>
|
||
#include <leds.h>
|
||
#include <ESP_EEPROM.h>
|
||
|
||
bool meas = false;
|
||
short minCnt;
|
||
bool send_move = false;
|
||
int mov, old_mov = 0;
|
||
int adc = 0;
|
||
int lastADC = 0;
|
||
int mvDelay, mvDelaySet;
|
||
|
||
unsigned long cRun;
|
||
|
||
const char* ssid = "wf-home";
|
||
const char* password = "0ndthnrf";
|
||
const char* mqtt_server = "192.168.1.111";
|
||
|
||
AsyncMqttClient mqttClient;
|
||
Ticker mqttReconnectTimer;
|
||
|
||
WiFiEventHandler wifiConnectHandler;
|
||
WiFiEventHandler wifiDisconnectHandler;
|
||
Ticker wifiReconnectTimer;
|
||
|
||
void connectToWifi();
|
||
void connectToMqtt();
|
||
void onWifiConnect(const WiFiEventStationModeGotIP& event);
|
||
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event);
|
||
void onMqttConnect(bool sessionPresent);
|
||
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason);
|
||
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total);
|
||
/* void onMqttSubscribe(uint16_t packetId, uint8_t qos);
|
||
void onMqttUnsubscribe(uint16_t packetId);
|
||
void onMqttPublish(uint16_t packetId); */
|
||
|
||
leds g_led(G_LED, 300, 100, true);
|
||
leds b_led(B_LED, 300, 100, true);
|
||
|
||
//leds r_led(R_LED, 100);
|
||
|
||
void setup() {
|
||
Serial.begin(9600, SERIAL_8N1);
|
||
//Serial1.begin(9600);
|
||
//Serial1.println("Booting"); // "Загрузка"
|
||
|
||
WiFi.mode(WIFI_STA);
|
||
WiFi.hostname("MidRoom");
|
||
ArduinoOTA.onStart([]() {
|
||
//Serial1.println("Start Update"); // "Начало OTA-апдейта"
|
||
});
|
||
ArduinoOTA.onEnd([]() {
|
||
//Serial1.println("\nEnd Update"); // "Завершение OTA-апдейта"
|
||
});
|
||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||
////Serial1.printf("Progress: %u%%\r", (progress / (total / 100)));
|
||
});
|
||
ArduinoOTA.onError([](ota_error_t error) {
|
||
// //Serial1.printf("Error[%u]: ", error);
|
||
// if (error == OTA_AUTH_ERROR) //Serial1.println("Auth Failed");
|
||
// // "Ошибка при аутентификации"
|
||
// else if (error == OTA_BEGIN_ERROR) //Serial1.println("Begin Failed");
|
||
// // "Ошибка при начале OTA-апдейта"
|
||
// else if (error == OTA_CONNECT_ERROR) //Serial1.println("Connect Failed");
|
||
// // "Ошибка при подключении"
|
||
// else if (error == OTA_RECEIVE_ERROR) //Serial1.println("Receive Failed");
|
||
// // "Ошибка при получении данных"
|
||
// else if (error == OTA_END_ERROR) //Serial1.println("End Failed");
|
||
// // "Ошибка при завершении OTA-апдейта"
|
||
});
|
||
ArduinoOTA.begin();
|
||
|
||
wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
|
||
wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);
|
||
|
||
mqttClient.onConnect(onMqttConnect);
|
||
mqttClient.onDisconnect(onMqttDisconnect);
|
||
/* mqttClient.onSubscribe(onMqttSubscribe);
|
||
mqttClient.onUnsubscribe(onMqttUnsubscribe);
|
||
mqttClient.onPublish(onMqttPublish); */
|
||
mqttClient.onMessage(onMqttMessage);
|
||
mqttClient.setServer(mqtt_server, 1883);
|
||
mqttClient.setClientId("MidRoomT");
|
||
|
||
pinMode(MOV_SENS, INPUT_PULLUP);
|
||
pinMode(P_SENS, OUTPUT);
|
||
pinMode(R_LED, OUTPUT);
|
||
pinMode(G_LED, OUTPUT);
|
||
pinMode(B_LED, OUTPUT);
|
||
//analogWriteRange(100);
|
||
digitalWrite(P_SENS, LOW);
|
||
//digitalWrite(WF_LED, HIGH);
|
||
digitalWrite(R_LED, LOW);
|
||
digitalWrite(G_LED, HIGH);
|
||
digitalWrite(B_LED, HIGH);
|
||
//Serial1.println(F("Begin MH-Z19"));
|
||
for(int i = 0; i < 5; i++){
|
||
//Serial1.print('.');
|
||
delay(1000);
|
||
}
|
||
//Serial1.println();
|
||
mhz19.begin(Serial);
|
||
Wire.begin();
|
||
bool status = bme.begin(BME280_ADDRESS_ALTERNATE);
|
||
if (!status) {
|
||
//Serial1.println(F("Could not find a valid BME280 sensor, check wiring, address, sensor ID!"));
|
||
}
|
||
else{
|
||
delay(100);
|
||
p = bme.readPressure();
|
||
t = bme.readTemperature();
|
||
h = bme.readHumidity();
|
||
/* Serial1.print(F("T: "));
|
||
Serial1.print(t);
|
||
Serial1.print(F("\tH: "));
|
||
Serial1.print(h);
|
||
Serial1.print(F("\tP: "));
|
||
Serial1.println(p); */
|
||
}
|
||
|
||
EEPROM.begin(16);
|
||
EEPROM.get(4, mvDelaySet);
|
||
//mvDelaySet = 90;
|
||
mvDelay = -1;
|
||
|
||
connectToWifi();
|
||
|
||
cRun = millis();
|
||
cRunADC = millis();
|
||
//Serial1.println(F("Start Loop"));
|
||
//(R_LED, HIGH);
|
||
}
|
||
|
||
void loop() {
|
||
float pt, tt, ht;
|
||
char v[11];
|
||
static int stDelay = 0;
|
||
|
||
ArduinoOTA.handle();
|
||
g_led.tick();
|
||
b_led.tick();
|
||
//r_led.tick();
|
||
if(digitalRead(MOV_SENS) > 0){
|
||
if(mvDelay == -1){
|
||
g_led.start();
|
||
mqttClient.publish(TOPIC"/move", 1, false, "1");
|
||
}
|
||
mvDelay = mvDelaySet;
|
||
}
|
||
|
||
if((cRunADC + 99) < millis()){
|
||
cRunADC = millis();
|
||
adc = analogRead(A0);
|
||
samples.add(adc);
|
||
adc = samples.getMedian();
|
||
if(abs(adc - lastADC) > 10){
|
||
lastADC = adc;
|
||
itoa(adc, v, 10);
|
||
g_led.start();
|
||
mqttClient.publish(TOPIC"/light", 1, false, v);
|
||
}
|
||
}
|
||
/*if (digitalRead(MOV_SENS) != old_mov){
|
||
old_mov = digitalRead(MOV_SENS);
|
||
//Serial1.println(F("Change mov detected"));
|
||
mqttClient.publish(TOPIC"/move", 1, false, old_mov ? "1" : "0");
|
||
}*/
|
||
|
||
if((cRun + 999) < millis()){
|
||
cRun = millis();
|
||
// Serial.println("ADC:"+String(adc));
|
||
// itoa(mvDelay, v, 10);
|
||
// mqttClient.publish(TOPIC"/movesec", 0, false, v);
|
||
// itoa(mvDelaySet, v, 10);
|
||
// mqttClient.publish(TOPIC"/movesecset", 0, false, v);
|
||
if(mvDelay == 0) {
|
||
g_led.start();
|
||
mqttClient.publish(TOPIC"/move", 1, false, "0");
|
||
mvDelay = -1;
|
||
}
|
||
if(mvDelay > 0) mvDelay--;
|
||
|
||
if(minCnt % 10 == 0){
|
||
co2 = mhz19.getCO2();
|
||
// /* Serial1.print("CO2: ");
|
||
// Serial1.println(co2); */
|
||
// // Serial.println("Measure BME");
|
||
// digitalWrite(P_SENS, HIGH);
|
||
// bme.begin(BME280_ADDRESS_ALTERNATE);
|
||
// delay(10);
|
||
// pt = bme.readPressure();
|
||
// tt = bme.readTemperature();
|
||
// ht = bme.readHumidity();
|
||
// if(!isnan(pt))
|
||
// p = pt;//+= (pt - p) / 60.0f ;
|
||
// if(!isnan(tt))
|
||
// t = tt;//+= (tt - t) / 30.0f ;
|
||
// if(!isnan(ht))
|
||
// h = ht;//+= (ht - h) / 30.0f ;
|
||
// // Serial.println(p);
|
||
// // Serial.println(t);
|
||
// // Serial.println(h);
|
||
// digitalWrite(P_SENS, LOW);
|
||
}
|
||
if(++minCnt == 60){
|
||
minCnt = 0;
|
||
|
||
digitalWrite(P_SENS, HIGH);
|
||
bme.begin(BME280_ADDRESS_ALTERNATE);
|
||
delay(10);
|
||
pt = bme.readPressure();
|
||
tt = bme.readTemperature();
|
||
ht = bme.readHumidity();
|
||
if(!isnan(pt))
|
||
p = pt;//+= (pt - p) / 60.0f ;
|
||
if(!isnan(tt))
|
||
t = tt;//+= (tt - t) / 30.0f ;
|
||
if(!isnan(ht))
|
||
h = ht;//+= (ht - h) / 30.0f ;
|
||
// Serial.println(p);
|
||
// Serial.println(t);
|
||
// Serial.println(h);
|
||
digitalWrite(P_SENS, LOW);
|
||
|
||
if(mqttClient.connected()){
|
||
g_led.start();
|
||
//r_led.start();
|
||
//Serial1.println("Begin Publish");
|
||
itoa(adc, v, 10);
|
||
mqttClient.publish(TOPIC"/light", 1, false, v);
|
||
dtostrf(t, 5, 1,v);
|
||
trim(v);
|
||
mqttClient.publish(TOPIC"/temp", 1, false, v);
|
||
//Serial1.println("Publish1");
|
||
dtostrf(h, 5, 1,v);
|
||
trim(v);
|
||
mqttClient.publish(TOPIC"/humid", 1, false, v);
|
||
//Serial1.println("Publish2");
|
||
if(firstRun){
|
||
stDelay++;
|
||
if(stDelay > 3) firstRun = false;
|
||
}
|
||
if(!firstRun && (mhz19.errorCode == RESULT_OK)){
|
||
itoa(co2, v, 10);
|
||
mqttClient.publish(TOPIC"/co2", 1, false, v);
|
||
//Serial1.println("Publish3");
|
||
}
|
||
}
|
||
}
|
||
else if(minCnt % 20 == 0){
|
||
dtostrf(millis() / 60000.0, 7, 2, v);
|
||
trim(v);
|
||
//ultoa(millis(), v, 10);
|
||
if(mqttClient.connected()){
|
||
g_led.start();
|
||
mqttClient.publish(TOPIC"/millis", 0, false, v);
|
||
// dtostrf(t, 5, 1,v);
|
||
// mqttClient.publish(TOPIC"/temp", 0, false, v);
|
||
// //Serial1.println("Publish1");
|
||
// dtostrf(h, 5, 1,v);
|
||
// mqttClient.publish(TOPIC"/humid", 0, false, v);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void connectToWifi() {
|
||
//Serial.println(F("Connecting to Wi-Fi..."));
|
||
//Serial1.flush();
|
||
WiFi.begin(ssid, password);
|
||
}
|
||
|
||
void connectToMqtt() {
|
||
//Serial.println(F("Connecting to MQTT..."));
|
||
//Serial1.flush();
|
||
mqttClient.connect();
|
||
}
|
||
|
||
void onWifiConnect(const WiFiEventStationModeGotIP& event) {
|
||
//Serial.println(F("Connected to Wi-Fi."));
|
||
//Serial.print(F("IP: "));
|
||
//Serial1.flush();
|
||
//Serial.println(WiFi.localIP());
|
||
//digitalWrite(WF_LED, LOW);
|
||
connectToMqtt();
|
||
}
|
||
|
||
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
|
||
// Serial1.println(F("Disconnected from Wi-Fi."));
|
||
//Serial1.flush();
|
||
mqttReconnectTimer.detach(); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
|
||
wifiReconnectTimer.once(2, connectToWifi);
|
||
//digitalWrite(WF_LED, HIGH);
|
||
}
|
||
|
||
void onMqttConnect(bool sessionPresent) {
|
||
char v[15];
|
||
sprintf(v, "%u", mvDelaySet);
|
||
//itoa(mvDelaySet, v, 10);
|
||
mqttClient.publish(TOPIC"/mvdelay", 1, false, v);
|
||
mqttClient.subscribe(TOPIC"/mvdelay", 1);
|
||
// ultoa(ESP.getFlashChipSize(), v, 10);
|
||
// mqttClient.publish(TOPIC"/chipsize", 1, false, v);
|
||
// ultoa(ESP.getFlashChipRealSize(), v, 10);
|
||
// mqttClient.publish(TOPIC"/realchipsize", 1, false, v);
|
||
//Serial.println("Connected to MQTT");
|
||
digitalWrite(R_LED, HIGH);
|
||
}
|
||
|
||
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
|
||
// Serial1.println("Disconnected from MQTT.");
|
||
//digitalWrite(B_LED, LOW);
|
||
//digitalWrite(R_LED, HIGH);
|
||
if (WiFi.isConnected()) {
|
||
mqttReconnectTimer.once(2, connectToMqtt);
|
||
}
|
||
digitalWrite(R_LED, LOW);
|
||
}
|
||
|
||
/*void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
|
||
// //Serial1.println("Subscribe acknowledged.");
|
||
// //Serial1.print(" packetId: ");
|
||
// //Serial1.println(packetId);
|
||
// //Serial1.print(" qos: ");
|
||
// //Serial1.println(qos);
|
||
}
|
||
|
||
void onMqttUnsubscribe(uint16_t packetId) {
|
||
// //Serial1.println("Unsubscribe acknowledged.");
|
||
// //Serial1.print(" packetId: ");
|
||
// //Serial1.println(packetId);
|
||
}*/
|
||
|
||
void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total) {
|
||
if(strcmp(topic, TOPIC"/mvdelay") == 0){
|
||
mvDelaySet = atoi(payload);
|
||
EEPROM.put(4, mvDelaySet);
|
||
EEPROM.commit();
|
||
}
|
||
b_led.start();
|
||
}
|
||
/*
|
||
void onMqttPublish(uint16_t packetId) {
|
||
//Serial1.println("Publish acknowledged.");
|
||
//Serial1.print(" packetId: ");
|
||
//Serial1.println(packetId);
|
||
//g_led.start();
|
||
}
|
||
|
||
*/
|
||
void trim(char *s)
|
||
{
|
||
// удаляем пробелы и табы с начала строки:
|
||
unsigned 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';
|
||
}
|
||
} |