iot_water_monitor_v2
Dependencies: easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code
Application/main.cpp
- Committer:
- DuyLionTran
- Date:
- 2018-04-03
- Revision:
- 57:898fcb6692cd
- Parent:
- 56:3729bedac5ab
File content as of revision 57:898fcb6692cd:
/** * Revision * version 1.0 * .... * version 2.5 02-14-2018: 3rd relay and remote time setting are added * version 2.6 02-14-2018: DO Sensor added, calibration is still on the way * version 2.6.3 02-19-2018: developing calibration. the average voltage is ok * version 2.6.5 02-21-2018: developing calibration. Sensor read is completely ok * version 2.6.8 02-27-2018: developing DO calibration. DS18B20 temperature sensor is added * version 2.7 03-04-2018: DO calibration complete. IWDG is added * version 2.7.5 03-08-2018: DS18B20 & IWDG is being developed * version 2.7.5a 03-08-2018: DS18B20 problem discovered at line 42th ReadSensor.cpp Upload RTC time converted to epoch * version 2.8 03-18-2018: DS18B20 problem solved * version 2.8.5 03-19-2018: Set time to turn on/off the relay * version 2.9 03-22-2018: Watchdog worked. Some hardware bugs found * version 2.9.7 03-29-2018: Try to upload 1 more time if upload fail * version 2.9.7 03-30-2018 * version 2.9.8 03-04-2018 Minor changes. Time frame updated to IBM Watson every 60s */ /*************************************************************** * Includes ***************************************************************/ #include "mbed.h" #include "ReadSensor.h" #include "SimpleMQTT.h" #include "CommandExecution.h" #include "flash_programming.h" #include "Watchdog.h" /*************************************************************** * Definitions ***************************************************************/ //#define READ_ANALOG_SOFTTIMER #define READ_SECOND 1 /* Read timer every 1 second(s) */ #define INTERVAL_BETWEEN_EACH_UPLOAD_TYPE 10 /* The interval between each upload type in second */ #define RECONNECT_WIFI 60 /* Try to reconnect to wifi */ #ifdef READ_ANALOG_SOFTTIMER #define READ_ANALOG_MS 30 #endif #define PROCESS_SENSOR_VALUE_S 2 #define CALIB_STATE_CHANGE_PERIOD_S 5 #define ALARM_TIME_ODD 20 #define SEND_TIME_INTERVAL 60 /* Send Time frame every 60s */ /*************************************************************** * Variables ***************************************************************/ bool isUploading = false; bool isSendingData = false; bool isUploadImmediately = false; bool isFirstUpload = true; uint8_t uploadType = SENSOR_VALUE; uint8_t currentCalibMode = 1; uint8_t calibStateCounter = 0; uint32_t lastRead = 0; uint32_t noWiFilastRead = 0; uint16_t intervalSecondCounter = 0; uint32_t uploadPeriodCounter = 0; #ifdef READ_ANALOG_SOFTTIMER uint32_t lastReadAnalog = 0; #endif struct UploadValue DataStruct; Watchdog wd; extern float doValue; extern float temperature; extern bool isCalibrating; /*************************************************************** * Structs/Classess ***************************************************************/ static Serial pc(SERIAL_TX, SERIAL_RX); //DigitalOut myled(LED1); DigitalOut myled(A6); DigitalOut espEn(D2); DigitalOut espRs(D7); Timer UploadTimer; #ifdef READ_ANALOG_SOFTTIMER Timer ReadAnalogTimer; #endif Ticker DisplayDO; /*************************************************************** * Unity function definitions ***************************************************************/ void ReadAllFlashValues(); void SensorRun(); void enableESP(); void BinkLEDStart(); void AutomaticHandle(); void TimeAlarmHandle(); /*************************************************************** * Unity function declarations ***************************************************************/ void ReadAllFlashValues() { DataStruct.ADC_TEMPVal = 0; DataStruct.ADC_DOVal = 0; DataStruct.SENSOR_TEMPVal = 0; DataStruct.SENSOR_DOVal = 0; DataStruct.RELAY_State_1 = FP_ReadValue(RELAY1_ADDRESS); DataStruct.RELAY_State_2 = FP_ReadValue(RELAY2_ADDRESS); DataStruct.RELAY_State_3 = FP_ReadValue(RELAY3_ADDRESS); DataStruct.CONFIG_Mode = FP_ReadValue(MODE_ADDRESS); DataStruct.CONFIG_OxyThreshold = FP_ReadValue(OXY_THRES_ADDRESS); DataStruct.CONFIG_TemperatureThreshold = FP_ReadValue(TEMP_THRES_ADDRESS); DataStruct.CONFIG_UploadInterval = FP_ReadValue(UPLOAD_PERIOD_ADDRESS); DataStruct.CONFIG_AlarmTime = FP_ReadValue(ALARM_TIME_ADDRESS); DataStruct.CONFIG_SetRelayState_1 = FP_ReadValue(SET_RELAY_1_ADDRESS); DataStruct.CONFIG_SetRelayState_2 = FP_ReadValue(SET_RELAY_2_ADDRESS); printf("All values: %d %d %d %d %d %d %d %d %d\r\n", DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.CONFIG_Mode, DataStruct.CONFIG_OxyThreshold, DataStruct.CONFIG_TemperatureThreshold, DataStruct.CONFIG_UploadInterval, DataStruct.CONFIG_AlarmTime, DataStruct.CONFIG_SetRelayState_1, DataStruct.CONFIG_SetRelayState_2); if (DataStruct.CONFIG_Mode == 0xFFFFFFFF) { DataStruct.CONFIG_Mode = 0; } if (DataStruct.CONFIG_OxyThreshold == 0xFFFFFFFF) { DataStruct.CONFIG_OxyThreshold = 50; } if (DataStruct.CONFIG_TemperatureThreshold == 0xFFFFFFFF) { DataStruct.CONFIG_TemperatureThreshold = 25; } if (DataStruct.CONFIG_UploadInterval == 0xFFFFFFFF) { DataStruct.CONFIG_UploadInterval = 300; } CE_HandleRelays(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); } void SensorRun() { if (!isSendingData) { wd.Service(); for (uint8_t j = 0; j < SCOUNT; j++) { SENSOR_AnalogRead(); } SENSOR_GetDOValue(); DataStruct.SENSOR_DOVal = doValue; DataStruct.SENSOR_TEMPVal = temperature; if (isCalibrating) { SENSOR_DoCalibration(currentCalibMode); if (currentCalibMode == 3) { currentCalibMode = 1; isCalibrating = false; } calibStateCounter++; /* Change calibration mode every PROCESS_SENSOR_VALUE_S*CALIB_STATE_CHANGE_PERIOD_S second(s) */ if ((calibStateCounter % CALIB_STATE_CHANGE_PERIOD_S) == 0) { currentCalibMode++; } } } else { printf("No sensor reading because uploading data\r\n"); } } void enableESP() { espRs = 0; espEn = 0; wait(2); espEn = 1; espRs = 1; printf("ESP enabled\r\n"); } void BinkLEDStart() { myled = 1; for (uint8_t j = 0; j < 8; j++) { myled = !myled; wait(0.2); } myled = 0; } void AutomaticHandle() { if (DataStruct.CONFIG_Mode == 1) { /* Automatic mode */ // printf("DataStruct.SENSOR_DOVal*100 %d\r\n",(uint32_t)(DataStruct.SENSOR_DOVal*100)); if ((uint32_t)(DataStruct.SENSOR_DOVal*10) >= DataStruct.CONFIG_OxyThreshold) { /* Turn on the pumps */ DataStruct.RELAY_State_1 = 1; DataStruct.RELAY_State_2 = 1; DataStruct.RELAY_State_3 = 1; } else { /* Turn off the pumps */ DataStruct.RELAY_State_1 = 0; DataStruct.RELAY_State_2 = 0; DataStruct.RELAY_State_3 = 0; } CE_HandleRelays(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); FP_WriteRelayStates(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); } } void TimeAlarmHandle(time_t CurrentTime) { if (CurrentTime == (DataStruct.CONFIG_AlarmTime)) { DataStruct.RELAY_State_1 = DataStruct.CONFIG_SetRelayState_1; DataStruct.RELAY_State_2 = DataStruct.CONFIG_SetRelayState_2; CE_HandleRelays(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); FP_WriteRelayStates(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); } } /*************************************************************** * Main ***************************************************************/ int main() { pc.baud(115200); printf("PROGRAM STARTS\r\n"); set_time(1514768400); //01-01-2018 8:30AM enableESP(); UploadTimer.start(); #ifdef READ_ANALOG_SOFTTIMER ReadAnalogTimer.start(); #endif BinkLEDStart(); lastRead = 0; pc.printf("\r\nViKa IoT Water Monitor mbed Application\r\n"); pc.printf("\r\nconnecting to AP\r\n"); wd.Configure(24.8); wd.Service(); NetworkInterface* network = easy_connect(true); if (!network) { printf ("Error easy_connect\n\r"); wifiConnected = false; } wd.Service(); printf ("ATTEMPT CONNECT\n\r"); MQTTNetwork mqttNetwork(network); MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork); wd.Service(); MQTT_AttemptConnect(&client, &mqttNetwork, network, DataStruct); wd.Service(); if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { printf ("---ERROR line : %d, error type %d\n\r", __LINE__, connack_rc); wifiConnected = false; // while (true) // wait(1.0); // Permanent failures - don't retry } if (wd.WatchdogCausedReset()) { printf("Watchdog caused reset.\r\n"); } wd.Service(); DisplayDO.attach(&SensorRun, PROCESS_SENSOR_VALUE_S); ReadAllFlashValues(); SENSOR_ReadDoCharacteristicValues(); BinkLEDStart(); wd.Service(); lastRead = UploadTimer.read(); myled = 1; while (true) { time_t seconds = time(NULL); AutomaticHandle(); TimeAlarmHandle(seconds); #ifdef READ_ANALOG_SOFTTIMER if ((uint32_t)(ReadAnalogTimer.read_ms() - lastReadAnalog) > READ_ANALOG_MS) { SENSOR_AnalogRead(); lastReadAnalog = ReadAnalogTimer.read_ms(); } #endif if (wifiConnected) { if(connected == true) { /* Upload for the first time */ if (isFirstUpload) { if (MQTT_PublishAll(&client, seconds, SENSOR_VALUE, DataStruct) != MQTT::SUCCESS) { wait(2); MQTT_PublishAll(&client, seconds, SENSOR_VALUE, DataStruct); wait(2); uint32_t uploadTimeFramePeriod = SEND_TIME_INTERVAL; if (MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod) == MQTT::SUCCESS) { } else { MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod); } } else { wait(2); uint32_t uploadTimeFramePeriod = SEND_TIME_INTERVAL; if (MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod) == MQTT::SUCCESS) { } else { MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod); } } wait(2); isFirstUpload = false; } /* Periodic upload */ if ((uint32_t)(UploadTimer.read() - lastRead) >= READ_SECOND) { // Read timer every readSecond(s) /* Start uploading data */ if (!isUploading) { wd.Service(); uploadPeriodCounter++; if (uploadPeriodCounter == DataStruct.CONFIG_UploadInterval) { uploadPeriodCounter = 0; isUploading = true; intervalSecondCounter = INTERVAL_BETWEEN_EACH_UPLOAD_TYPE; } else if ((uploadPeriodCounter % SEND_TIME_INTERVAL) == 0) { uint32_t uploadTimeFramePeriod = SEND_TIME_INTERVAL; if (MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod) == MQTT::SUCCESS) { myled = 1; } else { if (MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod) == MQTT::SUCCESS) { myled = 1; } else { myled = 0; } } } } else { wd.Service(); if (intervalSecondCounter == INTERVAL_BETWEEN_EACH_UPLOAD_TYPE) { isSendingData = true; if (MQTT_PublishAll(&client, seconds, uploadType, DataStruct) == MQTT::SUCCESS) { myled = 1; uploadType++; if (uploadType > CONFIG_VALUE) { isUploading = false; uploadType = SENSOR_VALUE; commandID++; UploadTimer.reset(); } } else { /* Try to reupload */ if (MQTT_PublishAll(&client, seconds, uploadType, DataStruct) == MQTT::SUCCESS) { myled = 1; uploadType++; if (uploadType > RELAY_STATE) { isUploading = false; uploadType = SENSOR_VALUE; commandID++; UploadTimer.reset(); } } else { myled = 0; client.disconnect(); mqttNetwork.disconnect(); /* if we have lost the connection */ MQTT_AttemptConnect(&client, &mqttNetwork, network, DataStruct); } } isSendingData = false; intervalSecondCounter = 0; } else { intervalSecondCounter++; } } lastRead = UploadTimer.read(); } /* allow the MQTT client to receive subscribe messages and manage keep alive */ wd.Service(); client.yield(500); } else if (connected == false) { connected = true; } } else { wd.Service(); if ((uint32_t)(UploadTimer.read() - noWiFilastRead) >= RECONNECT_WIFI) { wifiConnected = true; network = easy_connect(true); MQTT_AttemptConnect(&client, &mqttNetwork, network, DataStruct); if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { printf ("---ERROR line : %d, error type %d\n\r", __LINE__, connack_rc); wifiConnected = false; // while (true) // wait(1.0); // Permanent failures - don't retry } noWiFilastRead = UploadTimer.read(); } } } }