- Functionals
ฟังก์ชันหลักของ HandySense
- Manual control การสั่งงานผ่านสมาร์ตโฟน
- Timmer control การตั้งเวลา
- Sensor control การใช้ระบบเซนเซอร์
- Read sensor
- Send data
- Add device
- Multitasking
- Status led
/* ----------------------- Manual Control --------------------------- */
void ControlRelay_Bymanual(int ch_relay, String message) {
DEBUG_PRINTLN();
DEBUG_PRINT("manual_message : ");
DEBUG_PRINTLN(message);
DEBUG_PRINT("ch_relay : ");
DEBUG_PRINTLN(ch_relay);
if (status_manual[ch_relay] == 0) {
status_manual[ch_relay] = 1;
if (message == "on") {
Open_relay(ch_relay);
RelayStatus[ch_relay] = 1;
DEBUG_PRINTLN("ON manual");
} else if (message == "off") {
Close_relay(ch_relay);
RelayStatus[ch_relay] = 0;
DEBUG_PRINTLN("OFF manual");
}
check_sendData_status = 1;
}
}
/* ------------ Control Relay By Timmer ------------- */
void ControlRelay_Bytimmer() {
int curentTimer;
int dayofweek;
if (WiFi.status() == WL_CONNECTED) {
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer, nistTime);
if (getLocalTime(&timeinfo)) {
yearNow = timeinfo.tm_year + 1900;
monthNow = timeinfo.tm_mon + 1;
dayNow = timeinfo.tm_mday;
weekdayNow = timeinfo.tm_wday;
hourNow = timeinfo.tm_hour;
minuteNow = timeinfo.tm_min;
secondNow = timeinfo.tm_sec;
curentTimer = (hourNow * 60) + minuteNow;
dayofweek = weekdayNow - 1;
} else {
_now = rtc.now();
curentTimer = (_now.hour() * 60) + _now.minute();
dayofweek = _now.dayOfTheWeek() - 1;
DEBUG_PRINT("USE RTC 1");
}
} else {
_now = rtc.now();
curentTimer = (_now.hour() * 60) + _now.minute();
dayofweek = _now.dayOfTheWeek() - 1;
DEBUG_PRINT("USE RTC 2");
}
//DEBUG_PRINT("curentTimer : "); DEBUG_PRINTLN(curentTimer);
/* check curentTimer => 0-1440 */
if (curentTimer < 0 || curentTimer > 1440) {
curentTimerError = 1;
DEBUG_PRINT("curentTimerError : ");
DEBUG_PRINTLN(curentTimerError);
} else {
curentTimerError = 0;
if (dayofweek == -1) {
dayofweek = 6;
}
//DEBUG_PRINT("dayofweek : "); DEBUG_PRINTLN(dayofweek);
if (curentTimer != oldTimer) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
if (time_open[i][dayofweek][j] == curentTimer) {
RelayStatus[i] = 1;
check_sendData_status = 1;
Open_relay(i);
DEBUG_PRINTLN("timer On");
DEBUG_PRINT("curentTimer : ");
DEBUG_PRINTLN(curentTimer);
DEBUG_PRINT("oldTimer : ");
DEBUG_PRINTLN(oldTimer);
} else if (time_close[i][dayofweek][j] == curentTimer) {
RelayStatus[i] = 0;
check_sendData_status = 1;
Close_relay(i);
DEBUG_PRINTLN("timer Off");
DEBUG_PRINT("curentTimer : ");
DEBUG_PRINTLN(curentTimer);
DEBUG_PRINT("oldTimer : ");
DEBUG_PRINTLN(oldTimer);
} else if (time_open[i][dayofweek][j] == 3000 && time_close[i][dayofweek][j] == 3000) {
// Close_relay(i);
// DEBUG_PRINTLN(" Not check day, Not Working relay");
}
}
}
oldTimer = curentTimer;
}
}
}
/* ----------------------- soilMinMax_ControlRelay --------------------------- */
void ControlRelay_BysoilMinMax() {
Get_soil();
for (int k = 0; k < 4; k++) {
if (Min_Soil[k] != 0 && Max_Soil[k] != 0) {
if (soil < Min_Soil[k]) {
if (statusSoil[k] == 0) {
Open_relay(k);
statusSoil[k] = 1;
RelayStatus[k] = 1;
check_sendData_status = 1;
digitalWrite(LEDY, HIGH);
//check_sendData_toWeb = 1;
DEBUG_PRINTLN("soil On");
}
} else if (soil > Max_Soil[k]) {
if (statusSoil[k] == 1) {
Close_relay(k);
statusSoil[k] = 0;
RelayStatus[k] = 0;
check_sendData_status = 1;
digitalWrite(LEDY, HIGH);
//check_sendData_toWeb = 1;
DEBUG_PRINTLN("soil Off");
}
}
}
}
}
/* ----------------------- tempMinMax_ControlRelay --------------------------- */
void ControlRelay_BytempMinMax() {
Get_sht31();
for (int g = 0; g < 4; g++) {
if (Min_Temp[g] != 0 && Max_Temp[g] != 0) {
if (temp < Min_Temp[g]) {
if (statusTemp[g] == 1) {
Close_relay(g);
statusTemp[g] = 0;
RelayStatus[g] = 0;
check_sendData_status = 1;
digitalWrite(LEDY, HIGH);
//check_sendData_toWeb = 1;
DEBUG_PRINTLN("temp Off");
}
} else if (temp > Max_Temp[g]) {
if (statusTemp[g] == 0) {
Open_relay(g);
statusTemp[g] = 1;
RelayStatus[g] = 1;
check_sendData_status = 1;
digitalWrite(LEDY, HIGH);
//check_sendData_toWeb = 1;
DEBUG_PRINTLN("temp On");
}
}
}
}
}
/* ----------------------- Mode for calculator sensor i2c --------------------------- */
int Mode(float* getdata) {
int maxValue = 0;
int maxCount = 0;
for (int i = 0; i < sizeof(getdata); ++i) {
int count = 0;
for (int j = 0; j < sizeof(getdata); ++j) {
if (round(getdata[j]) == round(getdata[i]))
++count;
}
if (count > maxCount) {
maxCount = count;
maxValue = round(getdata[i]);
}
}
return maxValue;
}
/* ----------------------- Calculator sensor SHT31 --------------------------- */
void Get_sht31() {
float buffer_temp = 0;
float buffer_hum = 0;
float temp_cal = 0;
int num_temp = 0;
buffer_temp = sht31.readTemperature();
buffer_hum = sht31.readHumidity();
if (buffer_temp < -40 || buffer_temp > 125 || isnan(buffer_temp)) { // range -40 to 125 C
if (temp_error_count >= 10) {
temp_error = 1;
digitalWrite(status_sht31_error, HIGH);
DEBUG_PRINT("temp_error : ");
DEBUG_PRINTLN(temp_error);
} else {
temp_error_count++;
}
DEBUG_PRINT("temp_error_count : ");
DEBUG_PRINTLN(temp_error_count);
} else {
ma_temp[4] = ma_temp[3];
ma_temp[3] = ma_temp[2];
ma_temp[2] = ma_temp[1];
ma_temp[1] = ma_temp[0];
ma_temp[0] = buffer_temp;
int mode_value_temp = Mode(ma_temp);
for (int i = 0; i < sizeof(ma_temp); i++) {
if (abs(mode_value_temp - ma_temp[i]) < 1) {
temp_cal = temp_cal + ma_temp[i];
num_temp++;
}
}
temp = temp_cal / num_temp;
temp_error = 0;
temp_error_count = 0;
digitalWrite(status_sht31_error, LOW);
}
float hum_cal = 0;
int num_hum = 0;
if (buffer_hum < 0 || buffer_hum > 100 || isnan(buffer_hum)) { // range 0 to 100 %RH
if (hum_error_count >= 10) {
hum_error = 1;
//digitalWrite(status_sht31_error, LOW);
DEBUG_PRINT("hum_error : ");
DEBUG_PRINTLN(hum_error);
} else {
hum_error_count++;
}
DEBUG_PRINT("hum_error_count : ");
DEBUG_PRINTLN(hum_error_count);
} else {
ma_hum[4] = ma_hum[3];
ma_hum[3] = ma_hum[2];
ma_hum[2] = ma_hum[1];
ma_hum[1] = ma_hum[0];
ma_hum[0] = buffer_hum;
int mode_value_hum = Mode(ma_hum);
for (int j = 0; j < sizeof(ma_hum); j++) {
if (abs(mode_value_hum - ma_hum[j]) < 1) {
hum_cal = hum_cal + ma_hum[j];
num_hum++;
}
}
humidity = hum_cal / num_hum;
hum_error = 0;
hum_error_count = 0;
//digitalWrite(status_sht31_error, HIGH);
}
}
/* ----------------------- Calculator sensor Max44009 --------------------------- */
void Get_max44009() {
float buffer_lux = 0;
float lux_cal = 0;
int num_lux = 0;
if(tpye_lux == 2){
buffer_lux = (myLux.getLux()* 2.15) / 1000;
} else {
buffer_lux = (lightMeter.readLightLevel() * 2.15) / 1000; //(KLux)
}
if (buffer_lux < 0 || buffer_lux > 188000 || isnan(buffer_lux)) { // range 0.045 to 188,000 lux
if (lux_error_count >= 10) {
lux_error = 1;
digitalWrite(status_max44009_error, HIGH);
DEBUG_PRINT("lux_error : ");
DEBUG_PRINTLN(lux_error);
} else {
lux_error_count++;
}
DEBUG_PRINT("lux_error_count : ");
DEBUG_PRINTLN(lux_error_count);
} else {
ma_lux[4] = ma_lux[3];
ma_lux[3] = ma_lux[2];
ma_lux[2] = ma_lux[1];
ma_lux[1] = ma_lux[0];
ma_lux[0] = buffer_lux;
int mode_value_lux = Mode(ma_lux);
for (int i = 0; i < sizeof(ma_lux); i++) {
if (abs(mode_value_lux - ma_lux[i]) < 1) {
lux_cal = lux_cal + ma_lux[i];
num_lux++;
}
}
lux_44009 = lux_cal / num_lux;
lux_error = 0;
lux_error_count = 0;
digitalWrite(status_max44009_error, LOW);
}
}
/* ----------------------- Calculator sensor Soil --------------------------- */
void Get_soil() {
float buffer_soil = 0;
sensorValue_soil_moisture = analogRead(Soil_moisture_sensorPin);
voltageValue_soil_moisture = (sensorValue_soil_moisture * 3.3) / (4095.00);
buffer_soil = ((-55.82) * voltageValue_soil_moisture) + 113.52;
if (buffer_soil < 0 || buffer_soil > 100 || isnan(buffer_soil)) { // range 0 to 100 %
if (soil_error_count >= 10) {
soil_error = 1;
digitalWrite(status_soil_error, HIGH);
DEBUG_PRINT("soil_error : ");
DEBUG_PRINTLN(soil_error);
} else {
soil_error_count++;
}
DEBUG_PRINT("soil_error_count : ");
DEBUG_PRINTLN(soil_error_count);
} else {
ma_soil[4] = ma_soil[3];
ma_soil[3] = ma_soil[2];
ma_soil[2] = ma_soil[1];
ma_soil[1] = ma_soil[0];
ma_soil[0] = buffer_soil;
soil = (ma_soil[0] + ma_soil[1] + ma_soil[2] + ma_soil[3] + ma_soil[4]) / 5;
if (soil <= 0) {
soil = 0;
} else if (soil >= 100) {
soil = 100;
}
soil_error = 0;
soil_error_count = 0;
digitalWrite(status_soil_error, LOW);
}
}
/* --------- UpdateData_To_Server --------- */
void UpdateData_To_Server() {
String DatatoWeb;
char msgtoWeb[200];
DatatoWeb = "{\"data\": {\"temperature\":" + String(temp) +
",\"humidity\":" + String(humidity) + ",\"lux\":" +
String(lux_44009) + ",\"soil\":" + String(soil) + "}}";
DEBUG_PRINT("DatatoWeb : "); DEBUG_PRINTLN(DatatoWeb);
DatatoWeb.toCharArray(msgtoWeb, (DatatoWeb.length() + 1));
if (client.publish("@shadow/data/update", msgtoWeb)) {
DEBUG_PRINTLN(" Send Data Complete ");
}
}
/* --------- sendStatus_RelaytoWeb --------- */
void sendStatus_RelaytoWeb() {
String _payload;
char msgUpdateRalay[200];
if (check_sendData_status == 1) {
_payload = "{\"data\": {\"led0\":\"" + String(RelayStatus[0]) + "\",\"led1\":\"" + String(RelayStatus[1]) + "\",\"led2\":\"" + String(RelayStatus[2]) + "\",\"led3\":\"" + String(RelayStatus[3]) + "\"}}";
DEBUG_PRINT("_payload : ");
DEBUG_PRINTLN(_payload);
_payload.toCharArray(msgUpdateRalay, (_payload.length() + 1));
if (client.publish("@shadow/data/update", msgUpdateRalay)) {
check_sendData_status = 0;
DEBUG_PRINTLN("Send StatusRelay FULL");
}
}
}
/* --------- Respone soilMinMax toWeb --------- */
void send_soilMinMax() {
String soil_payload;
char soilMinMax_data[450];
if (check_sendData_SoilMinMax == 1) {
soil_payload = "{\"data\": {\"min_soil0\":" + String(Min_Soil[0]) + ",\"max_soil0\":" + String(Max_Soil[0]) + ",\"min_soil1\":" + String(Min_Soil[1]) + ",\"max_soil1\":" + String(Max_Soil[1]) + ",\"min_soil2\":" + String(Min_Soil[2]) + ",\"max_soil2\":" + String(Max_Soil[2]) + ",\"min_soil3\":" + String(Min_Soil[3]) + ",\"max_soil3\":" + String(Max_Soil[3]) + "}}";
DEBUG_PRINT("_payload : ");
DEBUG_PRINTLN(soil_payload);
soil_payload.toCharArray(soilMinMax_data, (soil_payload.length() + 1));
if (client.publish("@shadow/data/update", soilMinMax_data)) {
check_sendData_SoilMinMax = 0;
}
}
}
/* --------- Respone tempMinMax toWeb --------- */
void send_tempMinMax() {
String temp_payload;
char tempMinMax_data[400];
if (check_sendData_tempMinMax == 1) {
temp_payload = "{\"data\": {\"min_temp0\":" + String(Min_Temp[0]) + ",\"max_temp0\":" + String(Max_Temp[0]) + ",\"min_temp1\":" + String(Min_Temp[1]) + ",\"max_temp1\":" + String(Max_Temp[1]) + ",\"min_temp2\":" + String(Min_Temp[2]) + ",\"max_temp2\":" + String(Max_Temp[2]) + ",\"min_temp3\":" + String(Min_Temp[3]) + ",\"max_temp3\":" + String(Max_Temp[3]) + "}}";
DEBUG_PRINT("_payload : ");
DEBUG_PRINTLN(temp_payload);
temp_payload.toCharArray(tempMinMax_data, (temp_payload.length() + 1));
if (client.publish("@shadow/data/update", tempMinMax_data)) {
check_sendData_tempMinMax = 0;
}
}
}
/* -------- webSerialJSON function ------- */
void webSerialJSON() {
while (Serial.available() > 0) {
Serial.setTimeout(10000);
EepromStream eeprom(0, 1024);
DeserializationError err = deserializeJson(jsonDoc, Serial);
if (err == DeserializationError::Ok) {
String command = jsonDoc["command"].as<String>();
bool isValidData = !jsonDoc["client"].isNull();
if (command == "restart") {
delay(100);
ESP.restart();
}
if (isValidData) {
/* ------------------WRITING----------------- */
serializeJson(jsonDoc, eeprom);
eeprom.flush();
// ถ้าไม่เหมือนคือเพิ่มอุปกรณ์ใหม่ // ถ้าเหมือนคือการเปลี่ยน wifi
if (client_old != jsonDoc["client"].as<String>()) {
Delete_All_config();
}
delay(100);
ESP.restart();
}
} else {
Serial.read();
}
}
}
/* --------- Auto Connect Wifi and server and setup value init ------------- */
void TaskWifiStatus(void * WifiStatus) {
while (1) {
connectWifiStatus = cannotConnect;
WiFi.begin(ssid.c_str(), password.c_str());
while (WiFi.status() != WL_CONNECTED) {
delay(100);
//DEBUG_PRINTLN("WIFI Not connect !!!");
}
connectWifiStatus = wifiConnected;
client.setServer(mqtt_server.c_str(), mqtt_port.toInt());
client.setCallback(callback);
timeClient.begin();
client.connect(mqtt_Client.c_str(), mqtt_username.c_str(), mqtt_password.c_str());
delay(100);
while (!client.connected() ) {
client.connect(mqtt_Client.c_str(), mqtt_username.c_str(), mqtt_password.c_str());
DEBUG_PRINTLN("NETPIE2020 can not connect");
delay(100);
}
if (client.connect(mqtt_Client.c_str(), mqtt_username.c_str(), mqtt_password.c_str())) {
connectWifiStatus = serverConnected;
DEBUG_PRINTLN("NETPIE2020 connected");
client.subscribe("@private/#");
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer, nistTime);
printLocalTime();
yearNow = timeinfo.tm_year + 1900;
monthNow = timeinfo.tm_mon + 1;
dayNow = timeinfo.tm_mday;
hourNow = timeinfo.tm_hour;
minuteNow = timeinfo.tm_min;
secondNow = timeinfo.tm_sec;
rtc.adjust(DateTime(yearNow, monthNow, dayNow, hourNow, minuteNow, secondNow));
OTA_update();
}
while (WiFi.status() == WL_CONNECTED) { // เชื่อมต่อ wifi แล้ว ไม่ต้องทำอะไรนอกจากส่งค่า
sendStatus_RelaytoWeb();
send_soilMinMax();
send_tempMinMax();
delay(500);
if (!client.connected()) {
client.connect(mqtt_Client.c_str(), mqtt_username.c_str(), mqtt_password.c_str());
DEBUG_PRINTLN("NETPIE2020 not connect Server");
delay(100);
}
client.loop();
server.handleClient();
delay(1);
}
}
}
/* --------- Auto Connect Serial ------------- */
void TaskWaitSerial(void * WaitSerial) {
while (1) {
if (Serial.available()) webSerialJSON();
delay(500);
}
}
int buff_count_LED_serverConnected;
void IRAM_ATTR Blink_LED() {
if (connectWifiStatus == editDeviceWifi) {
digitalWrite(LEDR, HIGH);
digitalWrite(connect_WifiStatusToBox, HIGH);
digitalWrite(LEDY, !digitalRead(LEDY));
} else if (connectWifiStatus == cannotConnect) {
digitalWrite(LEDY, HIGH);
digitalWrite(LEDR, !digitalRead(LEDR));
digitalWrite(connect_WifiStatusToBox, HIGH);
} else if (connectWifiStatus == serverConnected) {
digitalWrite(LEDR, LOW);
digitalWrite(LEDY, LOW);
digitalWrite(connect_WifiStatusToBox, LOW);
} else if (connectWifiStatus == wifiConnected) {
buff_count_LED_serverConnected++;
if (buff_count_LED_serverConnected < 7) {
digitalWrite(LEDR, !digitalRead(LEDR));
} else if (buff_count_LED_serverConnected < 10) {
digitalWrite(LEDR, LOW);
} else buff_count_LED_serverConnected = 0;
}
}