iot_water_monitor_v2
Dependencies: easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code
main.cpp
00001 /** 00002 * Revision 00003 * version 1.0 00004 * .... 00005 * version 2.5 02-14-2018: 3rd relay and remote time setting are added 00006 * version 2.6 02-14-2018: DO Sensor added, calibration is still on the way 00007 * version 2.6.3 02-19-2018: developing calibration. the average voltage is ok 00008 * version 2.6.5 02-21-2018: developing calibration. Sensor read is completely ok 00009 * version 2.6.8 02-27-2018: developing DO calibration. DS18B20 temperature sensor is added 00010 * version 2.7 03-04-2018: DO calibration complete. IWDG is added 00011 * version 2.7.5 03-08-2018: DS18B20 & IWDG is being developed 00012 * version 2.7.5a 03-08-2018: DS18B20 problem discovered at line 42th ReadSensor.cpp 00013 Upload RTC time converted to epoch 00014 * version 2.8 03-18-2018: DS18B20 problem solved 00015 * version 2.8.5 03-19-2018: Set time to turn on/off the relay 00016 * version 2.9 03-22-2018: Watchdog worked. Some hardware bugs found 00017 * version 2.9.7 03-29-2018: Try to upload 1 more time if upload fail 00018 * version 2.9.7 03-30-2018 00019 * version 2.9.8 03-04-2018 Minor changes. Time frame updated to IBM Watson every 60s 00020 */ 00021 00022 /*************************************************************** 00023 * Includes 00024 ***************************************************************/ 00025 #include "mbed.h" 00026 00027 #include "ReadSensor.h" 00028 #include "SimpleMQTT.h" 00029 #include "CommandExecution.h" 00030 #include "flash_programming.h" 00031 00032 #include "Watchdog.h" 00033 00034 /*************************************************************** 00035 * Definitions 00036 ***************************************************************/ 00037 //#define READ_ANALOG_SOFTTIMER 00038 00039 #define READ_SECOND 1 /* Read timer every 1 second(s) */ 00040 #define INTERVAL_BETWEEN_EACH_UPLOAD_TYPE 10 /* The interval between each upload type in second */ 00041 #define RECONNECT_WIFI 60 /* Try to reconnect to wifi */ 00042 #ifdef READ_ANALOG_SOFTTIMER 00043 #define READ_ANALOG_MS 30 00044 #endif 00045 #define PROCESS_SENSOR_VALUE_S 2 00046 #define CALIB_STATE_CHANGE_PERIOD_S 5 00047 #define ALARM_TIME_ODD 20 00048 00049 #define SEND_TIME_INTERVAL 60 /* Send Time frame every 60s */ 00050 /*************************************************************** 00051 * Variables 00052 ***************************************************************/ 00053 bool isUploading = false; 00054 bool isSendingData = false; 00055 bool isUploadImmediately = false; 00056 bool isFirstUpload = true; 00057 uint8_t uploadType = SENSOR_VALUE; 00058 uint8_t currentCalibMode = 1; 00059 uint8_t calibStateCounter = 0; 00060 00061 uint32_t lastRead = 0; 00062 uint32_t noWiFilastRead = 0; 00063 uint16_t intervalSecondCounter = 0; 00064 uint32_t uploadPeriodCounter = 0; 00065 00066 #ifdef READ_ANALOG_SOFTTIMER 00067 uint32_t lastReadAnalog = 0; 00068 #endif 00069 00070 struct UploadValue DataStruct; 00071 Watchdog wd; 00072 00073 extern float doValue; 00074 extern float temperature; 00075 extern bool isCalibrating; 00076 00077 /*************************************************************** 00078 * Structs/Classess 00079 ***************************************************************/ 00080 static Serial pc(SERIAL_TX, SERIAL_RX); 00081 00082 //DigitalOut myled(LED1); 00083 DigitalOut myled(A6); 00084 DigitalOut espEn(D2); 00085 DigitalOut espRs(D7); 00086 00087 Timer UploadTimer; 00088 #ifdef READ_ANALOG_SOFTTIMER 00089 Timer ReadAnalogTimer; 00090 #endif 00091 Ticker DisplayDO; 00092 00093 /*************************************************************** 00094 * Unity function definitions 00095 ***************************************************************/ 00096 void ReadAllFlashValues(); 00097 void SensorRun(); 00098 void enableESP(); 00099 00100 void BinkLEDStart(); 00101 00102 void AutomaticHandle(); 00103 void TimeAlarmHandle(); 00104 00105 /*************************************************************** 00106 * Unity function declarations 00107 ***************************************************************/ 00108 void ReadAllFlashValues() { 00109 DataStruct.ADC_TEMPVal = 0; 00110 DataStruct.ADC_DOVal = 0; 00111 DataStruct.SENSOR_TEMPVal = 0; 00112 DataStruct.SENSOR_DOVal = 0; 00113 DataStruct.RELAY_State_1 = FP_ReadValue(RELAY1_ADDRESS); 00114 DataStruct.RELAY_State_2 = FP_ReadValue(RELAY2_ADDRESS); 00115 DataStruct.RELAY_State_3 = FP_ReadValue(RELAY3_ADDRESS); 00116 DataStruct.CONFIG_Mode = FP_ReadValue(MODE_ADDRESS); 00117 DataStruct.CONFIG_OxyThreshold = FP_ReadValue(OXY_THRES_ADDRESS); 00118 DataStruct.CONFIG_TemperatureThreshold = FP_ReadValue(TEMP_THRES_ADDRESS); 00119 DataStruct.CONFIG_UploadInterval = FP_ReadValue(UPLOAD_PERIOD_ADDRESS); 00120 DataStruct.CONFIG_AlarmTime = FP_ReadValue(ALARM_TIME_ADDRESS); 00121 DataStruct.CONFIG_SetRelayState_1 = FP_ReadValue(SET_RELAY_1_ADDRESS); 00122 DataStruct.CONFIG_SetRelayState_2 = FP_ReadValue(SET_RELAY_2_ADDRESS); 00123 printf("All values: %d %d %d %d %d %d %d %d %d\r\n", DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, 00124 DataStruct.CONFIG_Mode, DataStruct.CONFIG_OxyThreshold, 00125 DataStruct.CONFIG_TemperatureThreshold, DataStruct.CONFIG_UploadInterval, 00126 DataStruct.CONFIG_AlarmTime, 00127 DataStruct.CONFIG_SetRelayState_1, DataStruct.CONFIG_SetRelayState_2); 00128 if (DataStruct.CONFIG_Mode == 0xFFFFFFFF) { 00129 DataStruct.CONFIG_Mode = 0; 00130 } 00131 if (DataStruct.CONFIG_OxyThreshold == 0xFFFFFFFF) { 00132 DataStruct.CONFIG_OxyThreshold = 50; 00133 } 00134 if (DataStruct.CONFIG_TemperatureThreshold == 0xFFFFFFFF) { 00135 DataStruct.CONFIG_TemperatureThreshold = 25; 00136 } 00137 if (DataStruct.CONFIG_UploadInterval == 0xFFFFFFFF) { 00138 DataStruct.CONFIG_UploadInterval = 300; 00139 } 00140 CE_HandleRelays(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); 00141 } 00142 00143 void SensorRun() { 00144 if (!isSendingData) { 00145 wd.Service(); 00146 for (uint8_t j = 0; j < SCOUNT; j++) { 00147 SENSOR_AnalogRead(); 00148 } 00149 SENSOR_GetDOValue(); 00150 DataStruct.SENSOR_DOVal = doValue; 00151 DataStruct.SENSOR_TEMPVal = temperature; 00152 if (isCalibrating) { 00153 SENSOR_DoCalibration(currentCalibMode); 00154 if (currentCalibMode == 3) { 00155 currentCalibMode = 1; 00156 isCalibrating = false; 00157 } 00158 calibStateCounter++; 00159 00160 /* Change calibration mode every PROCESS_SENSOR_VALUE_S*CALIB_STATE_CHANGE_PERIOD_S second(s) */ 00161 if ((calibStateCounter % CALIB_STATE_CHANGE_PERIOD_S) == 0) { 00162 currentCalibMode++; 00163 } 00164 } 00165 } 00166 else { 00167 printf("No sensor reading because uploading data\r\n"); 00168 } 00169 } 00170 00171 void enableESP() { 00172 espRs = 0; 00173 espEn = 0; 00174 wait(2); 00175 espEn = 1; 00176 espRs = 1; 00177 printf("ESP enabled\r\n"); 00178 } 00179 00180 void BinkLEDStart() { 00181 myled = 1; 00182 for (uint8_t j = 0; j < 8; j++) { 00183 myled = !myled; 00184 wait(0.2); 00185 } 00186 myled = 0; 00187 } 00188 00189 void AutomaticHandle() { 00190 if (DataStruct.CONFIG_Mode == 1) { /* Automatic mode */ 00191 // printf("DataStruct.SENSOR_DOVal*100 %d\r\n",(uint32_t)(DataStruct.SENSOR_DOVal*100)); 00192 if ((uint32_t)(DataStruct.SENSOR_DOVal*10) >= DataStruct.CONFIG_OxyThreshold) { 00193 /* Turn on the pumps */ 00194 DataStruct.RELAY_State_1 = 1; 00195 DataStruct.RELAY_State_2 = 1; 00196 DataStruct.RELAY_State_3 = 1; 00197 00198 } 00199 else { 00200 /* Turn off the pumps */ 00201 DataStruct.RELAY_State_1 = 0; 00202 DataStruct.RELAY_State_2 = 0; 00203 DataStruct.RELAY_State_3 = 0; 00204 } 00205 CE_HandleRelays(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); 00206 FP_WriteRelayStates(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); 00207 } 00208 } 00209 00210 void TimeAlarmHandle(time_t CurrentTime) { 00211 if (CurrentTime == (DataStruct.CONFIG_AlarmTime)) { 00212 DataStruct.RELAY_State_1 = DataStruct.CONFIG_SetRelayState_1; 00213 DataStruct.RELAY_State_2 = DataStruct.CONFIG_SetRelayState_2; 00214 CE_HandleRelays(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); 00215 FP_WriteRelayStates(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); 00216 } 00217 } 00218 /*************************************************************** 00219 * Main 00220 ***************************************************************/ 00221 int main() { 00222 pc.baud(115200); 00223 printf("PROGRAM STARTS\r\n"); 00224 set_time(1514768400); //01-01-2018 8:30AM 00225 enableESP(); 00226 UploadTimer.start(); 00227 00228 #ifdef READ_ANALOG_SOFTTIMER 00229 ReadAnalogTimer.start(); 00230 #endif 00231 00232 BinkLEDStart(); 00233 00234 lastRead = 0; 00235 pc.printf("\r\nViKa IoT Water Monitor mbed Application\r\n"); 00236 pc.printf("\r\nconnecting to AP\r\n"); 00237 00238 wd.Configure(24.8); 00239 wd.Service(); 00240 00241 NetworkInterface* network = easy_connect(true); 00242 if (!network) { 00243 printf ("Error easy_connect\n\r"); 00244 wifiConnected = false; 00245 } 00246 wd.Service(); 00247 printf ("ATTEMPT CONNECT\n\r"); 00248 MQTTNetwork mqttNetwork(network); 00249 MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork); 00250 wd.Service(); 00251 MQTT_AttemptConnect(&client, &mqttNetwork, network, DataStruct); 00252 wd.Service(); 00253 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { 00254 printf ("---ERROR line : %d, error type %d\n\r", __LINE__, connack_rc); 00255 wifiConnected = false; 00256 // while (true) 00257 // wait(1.0); // Permanent failures - don't retry 00258 } 00259 if (wd.WatchdogCausedReset()) { 00260 printf("Watchdog caused reset.\r\n"); 00261 } 00262 wd.Service(); 00263 DisplayDO.attach(&SensorRun, PROCESS_SENSOR_VALUE_S); 00264 ReadAllFlashValues(); 00265 SENSOR_ReadDoCharacteristicValues(); 00266 BinkLEDStart(); 00267 wd.Service(); 00268 lastRead = UploadTimer.read(); 00269 00270 myled = 1; 00271 while (true) { 00272 time_t seconds = time(NULL); 00273 AutomaticHandle(); 00274 TimeAlarmHandle(seconds); 00275 #ifdef READ_ANALOG_SOFTTIMER 00276 if ((uint32_t)(ReadAnalogTimer.read_ms() - lastReadAnalog) > READ_ANALOG_MS) { 00277 SENSOR_AnalogRead(); 00278 lastReadAnalog = ReadAnalogTimer.read_ms(); 00279 } 00280 #endif 00281 if (wifiConnected) { 00282 if(connected == true) { 00283 /* Upload for the first time */ 00284 if (isFirstUpload) { 00285 if (MQTT_PublishAll(&client, seconds, SENSOR_VALUE, DataStruct) != MQTT::SUCCESS) { 00286 wait(2); 00287 MQTT_PublishAll(&client, seconds, SENSOR_VALUE, DataStruct); 00288 wait(2); 00289 uint32_t uploadTimeFramePeriod = SEND_TIME_INTERVAL; 00290 if (MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod) == MQTT::SUCCESS) { 00291 } 00292 else { 00293 MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod); 00294 } 00295 } 00296 else { 00297 wait(2); 00298 uint32_t uploadTimeFramePeriod = SEND_TIME_INTERVAL; 00299 if (MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod) == MQTT::SUCCESS) { 00300 } 00301 else { 00302 MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod); 00303 } 00304 } 00305 wait(2); 00306 isFirstUpload = false; 00307 } 00308 /* Periodic upload */ 00309 if ((uint32_t)(UploadTimer.read() - lastRead) >= READ_SECOND) { // Read timer every readSecond(s) 00310 /* Start uploading data */ 00311 if (!isUploading) { 00312 wd.Service(); 00313 uploadPeriodCounter++; 00314 if (uploadPeriodCounter == DataStruct.CONFIG_UploadInterval) { 00315 uploadPeriodCounter = 0; 00316 isUploading = true; 00317 intervalSecondCounter = INTERVAL_BETWEEN_EACH_UPLOAD_TYPE; 00318 } 00319 else if ((uploadPeriodCounter % SEND_TIME_INTERVAL) == 0) { 00320 uint32_t uploadTimeFramePeriod = SEND_TIME_INTERVAL; 00321 if (MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod) == MQTT::SUCCESS) { 00322 myled = 1; 00323 } 00324 else { 00325 if (MQTT_PublishDeviceManage(&client, seconds, DataStruct.CONFIG_UploadInterval, uploadTimeFramePeriod) == MQTT::SUCCESS) { 00326 myled = 1; 00327 } 00328 else { 00329 myled = 0; 00330 } 00331 } 00332 } 00333 } 00334 else { 00335 wd.Service(); 00336 if (intervalSecondCounter == INTERVAL_BETWEEN_EACH_UPLOAD_TYPE) { 00337 isSendingData = true; 00338 if (MQTT_PublishAll(&client, seconds, uploadType, DataStruct) == MQTT::SUCCESS) { 00339 myled = 1; 00340 uploadType++; 00341 if (uploadType > CONFIG_VALUE) { 00342 isUploading = false; 00343 uploadType = SENSOR_VALUE; 00344 commandID++; 00345 UploadTimer.reset(); 00346 } 00347 } 00348 else { 00349 /* Try to reupload */ 00350 if (MQTT_PublishAll(&client, seconds, uploadType, DataStruct) == MQTT::SUCCESS) { 00351 myled = 1; 00352 uploadType++; 00353 if (uploadType > RELAY_STATE) { 00354 isUploading = false; 00355 uploadType = SENSOR_VALUE; 00356 commandID++; 00357 UploadTimer.reset(); 00358 } 00359 } 00360 else { 00361 myled = 0; 00362 client.disconnect(); 00363 mqttNetwork.disconnect(); 00364 /* if we have lost the connection */ 00365 MQTT_AttemptConnect(&client, &mqttNetwork, network, DataStruct); 00366 } 00367 } 00368 isSendingData = false; 00369 intervalSecondCounter = 0; 00370 } 00371 else { 00372 intervalSecondCounter++; 00373 } 00374 } 00375 lastRead = UploadTimer.read(); 00376 } 00377 /* allow the MQTT client to receive subscribe messages and manage keep alive */ 00378 wd.Service(); 00379 client.yield(500); 00380 } 00381 else if (connected == false) { 00382 connected = true; 00383 } 00384 } 00385 else { 00386 wd.Service(); 00387 if ((uint32_t)(UploadTimer.read() - noWiFilastRead) >= RECONNECT_WIFI) { 00388 wifiConnected = true; 00389 network = easy_connect(true); 00390 MQTT_AttemptConnect(&client, &mqttNetwork, network, DataStruct); 00391 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { 00392 printf ("---ERROR line : %d, error type %d\n\r", __LINE__, connack_rc); 00393 wifiConnected = false; 00394 // while (true) 00395 // wait(1.0); // Permanent failures - don't retry 00396 } 00397 noWiFilastRead = UploadTimer.read(); 00398 } 00399 } 00400 } 00401 } 00402
Generated on Tue Jul 12 2022 20:06:04 by 1.7.2