397 lines
12 KiB
C++
397 lines
12 KiB
C++
#include <Arduino.h>
|
|
#include <ArduinoOTA.h>
|
|
#include <Ticker.h>
|
|
#include <AsyncMqttClient.h>
|
|
#include "SdsDustSensor.h"
|
|
#include <ESP_EEPROM.h>
|
|
#include <RunningMedian.h>
|
|
#include <ESP8266WiFi.h>
|
|
#include <ESPAsyncTCP.h>
|
|
#include <ESPAsyncWebServer.h>
|
|
#include <WebSerial.h>
|
|
#include <ESP8266WiFiMulti.h>
|
|
#include "CG_RadSens.h"
|
|
|
|
#define WIFI_SSID "wf-home"
|
|
#define WIFI_PASSWORD "0ndthnrf"
|
|
//#define WIFI_SSID2 "BR"
|
|
//#define WIFI_PASSWORD2 "499727479o"
|
|
#define MQTT_SERV "192.168.1.111"
|
|
#define TOPIC "home/kor/"
|
|
|
|
#define HOSTNAME "ESP_Kor"
|
|
|
|
#define LED_WF (D0)
|
|
#define LED_MQ (D4)
|
|
#define LED_WRK (D3)
|
|
|
|
#define LAMP_OUT (D5)
|
|
#define PIN_MOVE (D2)
|
|
|
|
int rxPin = D7;
|
|
int txPin = D8;
|
|
SdsDustSensor sds(rxPin, txPin);
|
|
|
|
int cSec, adc, move, oldmov, minLight, minLightDB, LightInt, timeDelay, curDelay, fadeTime;
|
|
uint8_t sdsPeriod;
|
|
bool lamp;
|
|
float mins;
|
|
|
|
RunningMedian samples = RunningMedian(5 * sizeof(int));
|
|
|
|
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 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);
|
|
|
|
unsigned long cRun;
|
|
unsigned long stled;
|
|
|
|
ESP8266WiFiMulti wifiMulti;
|
|
AsyncWebServer server(80);
|
|
|
|
CG_RadSens radSens(RS_DEFAULT_I2C_ADDRESS);
|
|
bool rsOk;
|
|
float dynval; // Переменная для динамического значения интенсивности
|
|
float statval; // Переменная для статического значения интенсивности
|
|
uint32_t impval; // Переменная для кол-ва импульсов
|
|
|
|
void setup()
|
|
{
|
|
Serial.begin(9600);
|
|
WiFi.mode(WIFI_STA);
|
|
//WiFi.persistent(false);
|
|
WiFi.hostname(HOSTNAME);
|
|
//wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);
|
|
//wifiMulti.addAP(WIFI_SSID2, WIFI_PASSWORD2);
|
|
ArduinoOTA.onStart([]() {
|
|
Serial.println("ArduinoOTA start");
|
|
});
|
|
ArduinoOTA.onEnd([]() {
|
|
Serial.println("\nArduinoOTA end");
|
|
});
|
|
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
|
Serial.printf("OTA 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");
|
|
} 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");
|
|
}
|
|
});
|
|
ArduinoOTA.begin();
|
|
|
|
wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
|
|
wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);
|
|
|
|
mqttClient.onConnect(onMqttConnect);
|
|
mqttClient.onDisconnect(onMqttDisconnect);
|
|
mqttClient.onSubscribe(onMqttSubscribe);
|
|
mqttClient.onUnsubscribe(onMqttUnsubscribe);
|
|
mqttClient.onMessage(onMqttMessage);
|
|
mqttClient.onPublish(onMqttPublish);
|
|
mqttClient.setServer(MQTT_SERV, 1883);
|
|
|
|
|
|
pinMode(LED_WF, OUTPUT);
|
|
pinMode(LED_MQ, OUTPUT);
|
|
pinMode(LED_WRK, OUTPUT);
|
|
pinMode(LAMP_OUT, OUTPUT);
|
|
//pinMode(3, FUNCTION_3);
|
|
//delay(10);
|
|
//digitalWrite(3, LOW);
|
|
pinMode(PIN_MOVE, INPUT);
|
|
|
|
digitalWrite(LED_WF, LOW);
|
|
digitalWrite(LED_MQ, HIGH);
|
|
digitalWrite(LED_WRK, LOW);
|
|
|
|
EEPROM.begin(20);
|
|
EEPROM.get(0, timeDelay);
|
|
EEPROM.get(4, minLight);
|
|
EEPROM.get(8, minLightDB);
|
|
EEPROM.get(12, sdsPeriod);
|
|
EEPROM.get(16, LightInt);
|
|
Serial.printf("timeDelay=%d\n", timeDelay);
|
|
Serial.printf("minLight=%d\n", minLight);
|
|
Serial.printf("minLightDB=%d\n", minLightDB);
|
|
Serial.printf("sdsPeriod=%d\n", sdsPeriod);
|
|
Serial.printf("LightInt=%d\n", LightInt);
|
|
//mvDelaySet = 90;
|
|
curDelay = -1;
|
|
|
|
sds.begin();
|
|
Serial.println(sds.queryFirmwareVersion().toString()); // prints firmware version
|
|
sds.setActiveReportingMode();
|
|
sds.setCustomWorkingPeriod(sdsPeriod);
|
|
connectToWifi();
|
|
|
|
cRun = millis();
|
|
stled = millis();
|
|
mins = 0;
|
|
WebSerial.begin(&server);
|
|
/* Attach Message Callback */
|
|
server.begin();
|
|
//Wire.begin();
|
|
//rsOk = radSens.init();
|
|
radSens.setSensitivity(105);
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
char v[6];
|
|
ArduinoOTA.handle();
|
|
static unsigned long cRunADC = millis();
|
|
|
|
if(digitalRead(PIN_MOVE) > 0){
|
|
if(curDelay == -1) mqttClient.publish(TOPIC"move", 1, false, "1");
|
|
move = true;
|
|
curDelay = timeDelay - 7;
|
|
}
|
|
if (cRunADC + 50 < millis()){
|
|
cRunADC = millis();
|
|
adc = analogRead(A0);
|
|
samples.add(adc);
|
|
//if (mqttClient.connected()) analogWrite(LED_MQ, int(samples.getMedian()));
|
|
}
|
|
//adc = samples.getMedian();
|
|
|
|
if ((samples.getMedian() <= minLight) && (move == 1)){
|
|
analogWrite(LAMP_OUT, LightInt);
|
|
if(lamp == false){
|
|
Serial.println("Lamp ON");
|
|
Serial.print("ADC: ");Serial.print(samples.getMedian());
|
|
Serial.print(", Move: ");Serial.println(move);
|
|
WebSerial.println("Lamp ON");
|
|
WebSerial.print("ADC: ");WebSerial.print(samples.getMedian());
|
|
WebSerial.print(", Move: ");WebSerial.println(move);
|
|
itoa(int(samples.getMedian()), v, 10);
|
|
mqttClient.publish(TOPIC"adc", 1, false, v);
|
|
mqttClient.publish(TOPIC"lamp", 1, false, "1");
|
|
lamp = true;
|
|
}
|
|
}
|
|
else if((samples.getMedian() > (minLight + minLightDB)) || (move == 0)){
|
|
analogWrite(LAMP_OUT, 0);
|
|
//curDelay = 2;
|
|
if(lamp == true){
|
|
Serial.println("Lamp OFF");
|
|
Serial.print("ADC: ");Serial.print(samples.getMedian());
|
|
Serial.print(", Move: ");Serial.println(move);
|
|
WebSerial.println("Lamp OFF");
|
|
WebSerial.print("ADC: ");WebSerial.print(samples.getMedian());
|
|
WebSerial.print(", Move: ");WebSerial.println(move);
|
|
itoa(int(samples.getMedian()), v, 10);
|
|
mqttClient.publish(TOPIC"adc", 1, false, v);
|
|
mqttClient.publish(TOPIC"lamp", 1, false, "0");
|
|
lamp = false;
|
|
}
|
|
}
|
|
if(stled + 300 < millis()){
|
|
digitalWrite(LED_WRK, HIGH);
|
|
}
|
|
if(cRun + 999 < millis()){
|
|
cRun = millis();
|
|
//if(!rsOk){
|
|
// WebSerial.println("RadSens not Ok");
|
|
// rsOk = radSens.init();
|
|
//}
|
|
//dynval = radSens.getRadIntensyDynamic();
|
|
//statval = radSens.getRadIntensyStatic();
|
|
//impval = radSens.getNumberOfPulses();
|
|
|
|
cSec++;
|
|
mins += 1 / 60.0;
|
|
if(cSec == 10){
|
|
sprintf(v, "%.1f", mins);
|
|
mqttClient.publish(TOPIC"minsmain", 1, false, v);
|
|
itoa(int(samples.getMedian()), v, 10);
|
|
mqttClient.publish(TOPIC"adc", 1, false, v);
|
|
//sprintf(v, "%.1f", statval);
|
|
//mqttClient.publish(TOPIC"mkr", 1, false, v);
|
|
cSec = 0;
|
|
}
|
|
if(curDelay == 0) {
|
|
mqttClient.publish(TOPIC"move", 1, false, "0");
|
|
move = false;
|
|
curDelay = -1;
|
|
}
|
|
if(curDelay > 0){
|
|
curDelay--;
|
|
WebSerial.print("MoveSens:");
|
|
WebSerial.print(digitalRead(PIN_MOVE));
|
|
WebSerial.print("Timer light:");
|
|
WebSerial.print(curDelay);
|
|
WebSerial.print(", adc:");
|
|
WebSerial.print(adc);
|
|
WebSerial.print(", median:");
|
|
WebSerial.println(int(samples.getMedian()));
|
|
}
|
|
|
|
PmResult pm = sds.readPm();
|
|
//if((stled + 300) < millis()) digitalWrite(LED_WRK, LOW);
|
|
//lwork = !lwork;
|
|
if (pm.isOk()) {
|
|
if(mqttClient.connected()){
|
|
stled = millis();
|
|
|
|
sprintf(v, "%.1f", pm.pm25);
|
|
mqttClient.publish(TOPIC"pm25", 1, false, v);
|
|
sprintf(v, "%.1f", pm.pm10);
|
|
mqttClient.publish(TOPIC"pm10", 1, false, v);
|
|
}
|
|
Serial.print(cRun); Serial.print("\t");
|
|
Serial.print("PM2.5 = ");
|
|
Serial.print(pm.pm25);
|
|
Serial.print(", PM10 = ");
|
|
Serial.println(pm.pm10);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
void connectToWifi() {
|
|
Serial.println("Connecting to Wi-Fi...");
|
|
//wifiMulti.run();
|
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
|
}
|
|
|
|
void connectToMqtt() {
|
|
Serial.println("Connecting to MQTT...");
|
|
mqttClient.connect();
|
|
}
|
|
|
|
void onWifiConnect(const WiFiEventStationModeGotIP& event) {
|
|
Serial.println("Connected to Wi-Fi.");
|
|
Serial.print("IP: ");
|
|
Serial.println(WiFi.localIP());
|
|
connectToMqtt();
|
|
digitalWrite(LED_WF, HIGH);
|
|
}
|
|
|
|
void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
|
|
Serial.println("Disconnected from Wi-Fi.");
|
|
mqttReconnectTimer.detach(); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
|
|
wifiReconnectTimer.once(2, connectToWifi);
|
|
digitalWrite(LED_WF, LOW);
|
|
}
|
|
|
|
void onMqttConnect(bool sessionPresent) {
|
|
Serial.println("Connected to MQTT.");
|
|
Serial.print("Session present: ");
|
|
Serial.println(sessionPresent);
|
|
char v[10];
|
|
|
|
itoa(timeDelay, v, 10);
|
|
mqttClient.publish(TOPIC"mvdelay", 1, false, v);
|
|
itoa(minLight, v, 10);
|
|
mqttClient.publish(TOPIC"lightsp", 1, false, v);
|
|
itoa(minLightDB, v, 10);
|
|
mqttClient.publish(TOPIC"lightdb", 1, false, v);
|
|
itoa(sdsPeriod, v, 10);
|
|
mqttClient.publish(TOPIC"sdsperiod", 1, false, v);
|
|
itoa(LightInt, v, 10);
|
|
mqttClient.publish(TOPIC"lightlev", 1, false, v);
|
|
|
|
mqttClient.subscribe(TOPIC"mvdelay", 1);
|
|
mqttClient.subscribe(TOPIC"lightsp", 1);
|
|
mqttClient.subscribe(TOPIC"lightdb", 1);
|
|
mqttClient.subscribe(TOPIC"sdsperiod", 1);
|
|
mqttClient.subscribe(TOPIC"lightlev", 1);
|
|
|
|
//analogWrite(LED_MQ, 1023);
|
|
digitalWrite(LED_MQ, LOW);
|
|
}
|
|
|
|
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
|
|
//Serial.println("Disconnected from MQTT.");
|
|
|
|
if (WiFi.isConnected()) {
|
|
mqttReconnectTimer.once(2, connectToMqtt);
|
|
}
|
|
//analogWrite(LED_MQ, 0);
|
|
digitalWrite(LED_MQ, HIGH);
|
|
}
|
|
|
|
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 chd = false;
|
|
if(strcmp(topic, TOPIC"mvdelay") == 0){
|
|
timeDelay = atoi(payload);
|
|
Serial.printf("timeDelay=%d\n", timeDelay);
|
|
EEPROM.put(0, timeDelay);
|
|
chd = true;
|
|
}
|
|
if(strcmp(topic, TOPIC"lightsp") == 0){
|
|
minLight = atoi(payload);
|
|
Serial.printf("minLight=%d\n", minLight);
|
|
EEPROM.put(4, minLight);
|
|
chd = true;
|
|
}
|
|
if(strcmp(topic, TOPIC"lightdb") == 0){
|
|
minLightDB = atoi(payload);
|
|
Serial.printf("minLightDB=%d\n", minLightDB);
|
|
EEPROM.put(8, minLightDB);
|
|
chd = true;
|
|
}
|
|
if(strcmp(topic, TOPIC"sdsperiod") == 0){
|
|
sdsPeriod = atoi(payload);
|
|
EEPROM.put(12, sdsPeriod);
|
|
Serial.printf("sdsPeriod=%d\n", sdsPeriod);
|
|
sds.setCustomWorkingPeriod(sdsPeriod);
|
|
chd = true;
|
|
}
|
|
if(strcmp(topic, TOPIC"lightlev") == 0){
|
|
LightInt = atoi(payload);
|
|
Serial.printf("LightLev=%d\n", LightInt);
|
|
EEPROM.put(16, LightInt);
|
|
chd = true;
|
|
}
|
|
if(chd){
|
|
EEPROM.commit();
|
|
Serial.println("EEPROM commit");
|
|
}
|
|
}
|
|
|
|
void onMqttPublish(uint16_t packetId) {
|
|
Serial.println("Publish acknowledged.");
|
|
Serial.print(" packetId: ");
|
|
Serial.println(packetId);
|
|
digitalWrite(LED_WRK, LOW);
|
|
stled = millis();
|
|
}
|