iot_water_monitor_v2
Dependencies: easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code
Revision 41:6aed398adcc4, committed 2018-03-04
- Comitter:
- DuyLionTran
- Date:
- Sun Mar 04 07:57:56 2018 +0000
- Parent:
- 40:4356c209c58d
- Child:
- 42:3656e1b2f20a
- Commit message:
- * version 2.7 03-04-2018: DO calibration complete. IDWD is added
Changed in this revision
--- a/Application/CommandExecution.cpp Tue Feb 27 14:51:18 2018 +0000 +++ b/Application/CommandExecution.cpp Sun Mar 04 07:57:56 2018 +0000 @@ -6,6 +6,8 @@ DigitalOut relay2(RELAY_2_PIN); DigitalOut relay3(RELAY_3_PIN); +extern bool isCalibrating; + void CE_HandleRelays(int Relay1State, int Relay2State, int Relay3State) { relay1 = Relay1State; relay2 = Relay2State; @@ -18,5 +20,5 @@ } void CE_Calibrate() { - SENSOR_DoCalibration(); + isCalibrating = true; } \ No newline at end of file
--- a/Application/main.cpp Tue Feb 27 14:51:18 2018 +0000 +++ b/Application/main.cpp Sun Mar 04 07:57:56 2018 +0000 @@ -2,11 +2,12 @@ * Revision * version 1.0 * .... - * version 2.5 02-14-2017: 3rd relay and remote time setting are added - * version 2.6 02-14-2017: DO Sensor added, calibration is still on the way - * version 2.6.3 02-19-2017: developing calibration. the average voltage is ok - * version 2.6.5 02-21-2017: developing calibration. Sensor read is completely ok - * version 2.6.8 02-27-2017: developing DO calibration. DS18B20 temperature sensor is added + * 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. IDWD is added */ /*************************************************************** @@ -19,30 +20,44 @@ #include "CommandExecution.h" #include "flash_programming.h" +#include "stm32l4xx_hal_iwdg.h" + /*************************************************************** * Definitions ***************************************************************/ +//#define READ_ANALOG_SOFTTIMER + #define READ_SECOND 1 /* Read timer every 1 second(s) */ #define INTERVAL_BETWEEN_EACH_UPLOAD_TYPE 5 /* 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 READ_ANALOG_MS 30 -#define PROCESS_DO_VALUE_S 1 /*************************************************************** * Variables ***************************************************************/ bool isUploading = false; uint8_t uploadType = ADC_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; -uint32_t lastReadAnalog = 0; + +#ifdef READ_ANALOG_SOFTTIMER + uint32_t lastReadAnalog = 0; +#endif struct UploadValue DataStruct; +IWDG_HandleTypeDef IwdgHandle; extern float doValue; +extern bool isCalibrating; /*************************************************************** * Structs/Classess @@ -55,25 +70,28 @@ DigitalOut espRs(D7); Timer UploadTimer; -Timer ReadAnalogTimer; +#ifdef READ_ANALOG_SOFTTIMER + Timer ReadAnalogTimer; +#endif +Ticker DisplayDO; -Ticker DisplayDO; /*************************************************************** * Unity function definitions ***************************************************************/ void ReadAllFlashValues(); -void ProcessDOVal(); +void SensorRun(); void enableESP(); void BinkLEDStart(); + /*************************************************************** * Unity function declarations ***************************************************************/ void ReadAllFlashValues() { - DataStruct.ADC_PHVal = 0.85; - DataStruct.ADC_DOVal = 0.95; - DataStruct.SENSOR_PHVal = 17.8; - DataStruct.SENSOR_DOVal = 18.9; + DataStruct.ADC_PHVal = 0; + DataStruct.ADC_DOVal = 0; + DataStruct.SENSOR_PHVal = 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); @@ -87,9 +105,25 @@ CE_HandleRelays(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3); } -void ProcessDOVal() { +void SensorRun() { + for (uint8_t j = 0; j < SCOUNT; j++) { + SENSOR_AnalogRead(); + } SENSOR_GetDOValue(); DataStruct.SENSOR_DOVal = doValue; + 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++; + } + } } void enableESP() { @@ -99,18 +133,11 @@ } void BinkLEDStart() { - myled = 0; - wait(0.2); myled = 1; - wait(0.2); - myled = 0; - wait(0.2); - myled = 1; - wait(0.2); - myled = 0; - wait(0.2); - myled = 1; - wait(0.2); + for (uint8_t j = 0; j < 8; j++) { + myled = !myled; + wait(0.2); + } myled = 0; } /*************************************************************** @@ -120,12 +147,16 @@ pc.baud(115200); enableESP(); UploadTimer.start(); - ReadAnalogTimer.start(); - DisplayDO.attach(&ProcessDOVal, PROCESS_DO_VALUE_S); + + #ifdef READ_ANALOG_SOFTTIMER + ReadAnalogTimer.start(); + #endif + + DisplayDO.attach(&SensorRun, PROCESS_SENSOR_VALUE_S); BinkLEDStart(); lastRead = 0; - pc.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n"); + pc.printf("\r\nViKa IoT Water Monitor mbed Application\r\n"); pc.printf("\r\nconnecting to AP\r\n"); NetworkInterface* network = easy_connect(true); @@ -149,10 +180,12 @@ myled = 1; while (true) { time_t seconds = time(NULL); - if ((uint32_t)(ReadAnalogTimer.read_ms() - lastReadAnalog) > READ_ANALOG_MS) { - SENSOR_AnalogRead(); - lastReadAnalog = ReadAnalogTimer.read_ms(); - } + #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) { if ((uint32_t)(UploadTimer.read() - lastRead) >= READ_SECOND) { // Read timer every readSecond(s)
--- a/Flash/flash_programming.h Tue Feb 27 14:51:18 2018 +0000 +++ b/Flash/flash_programming.h Sun Mar 04 07:57:56 2018 +0000 @@ -158,50 +158,50 @@ /** - * @brief Gets the page of a given address - * @param Addr: Address of the FLASH Memory - * @retval The page of a given address - */ + * @brief Gets the page of a given address + * @param Addr: Address of the FLASH Memory + * @retval The page of a given address + */ uint32_t FP_GetPage(uint32_t Addr); /** - * @brief Read the value stored in a specific address - * @param Addr: Address of the FLASH Memory - * @retval The result read from the memory - */ + * @brief Read the value stored in a specific address + * @param Addr: Address of the FLASH Memory + * @retval The result read from the memory + */ uint32_t FP_ReadValue(uint32_t Addr); /** - * @brief Write the states of relays into the flash memory - * @param RelayState1: Relay 1 state - * @param RelayState2: Relay 2 state - * @param RelayState3: Relay 3 state - * @retval FLASH result - */ + * @brief Write the states of relays into the flash memory + * @param RelayState1: Relay 1 state + * @param RelayState2: Relay 2 state + * @param RelayState3: Relay 3 state + * @retval FLASH result + */ int FP_WriteRelayStates(uint8_t RelayState1, uint8_t RelayState2, uint8_t RelayState3); /** - * @brief Write the time to activate an event into the flash memory - * @param WriteTimeValue: Current working mode of the device - * @retval FLASH result - */ + * @brief Write the time to activate an event into the flash memory + * @param WriteTimeValue: Current working mode of the device + * @retval FLASH result + */ int FP_WriteTime(uint32_t WriteTimeValue); /** - * @brief Write the value to control the switches into the flash memory - * @param Mode: Current working mode of the device - * @param MinOxi: Current working mode of the device - * @param MaxOxi: Current working mode of the device - * @param UploadPeriod: Current working mode of the device - * @retval FLASH result - */ + * @brief Write the value to control the switches into the flash memory + * @param Mode: Current working mode of the device + * @param MinOxi: Current working mode of the device + * @param MaxOxi: Current working mode of the device + * @param UploadPeriod: Current working mode of the device + * @retval FLASH result + */ int FP_WriteConfigValues(uint8_t Mode ,uint8_t MinOxi, uint8_t MaxOxi, uint32_t UploadPeriod); /** - * @brief Write the calibration value to the flash memory - * @param SaturationDoVoltagex10: - * @retval FLASH result - */ + * @brief Write the calibration value to the flash memory + * @param SaturationDoVoltagex10: + * @retval FLASH result + */ int FP_WriteConfigValues(uint32_t SaturationDoVoltage); #endif /* __FLASH_PROGRAMMING_H__ */ \ No newline at end of file
--- a/Sensor/ReadSensor.cpp Tue Feb 27 14:51:18 2018 +0000 +++ b/Sensor/ReadSensor.cpp Sun Mar 04 07:57:56 2018 +0000 @@ -4,7 +4,7 @@ #include "flash_programming.h" const float SaturationValueTab[41] = { /* saturation dissolved oxygen concentrations at various temperatures */ -14.46, 14.22, 13.82, 13.44, 13.09, +14.46, 14.22, 13.82, 13.44, 13.09, /* 0 degree Celcius */ 12.74, 12.42, 12.11, 11.81, 11.53, 11.26, 11.01, 10.77, 10.53, 10.30, 10.08, 9.86, 9.66, 9.46, 9.27, @@ -12,18 +12,30 @@ 8.25, 8.11, 7.96, 7.82, 7.69, 7.56, 7.43, 7.30, 7.18, 7.07, 6.95, 6.84, 6.73, 6.63, 6.53, -6.41, +6.41, /* 40 degree Celcius */ }; -float doValue; /* current dissolved oxygen value, unit; mg/L */ -float temperature = 25; /* default temperature is 25^C, you can use a temperature sensor to read it */ +enum { + CALIBRATION = 1, + SATCAL, + EXIT +} Calibration_Mode; + +float doValue; /* current dissolved oxygen value, unit; mg/L or ppm */ +#ifdef PROBE_EXIST + float temperature; +#else + float temperature = 25.0; /* default temperature is 25^C, you can use a temperature sensor to read it */ +#endif int analogBuffer[SCOUNT]; /* store the analog value in the array, readed from ADC */ int analogBufferTemp[SCOUNT]; -int analogBufferIndex = 0; -int copyIndex = 0; -float SaturationDoVoltage; /* mV */ -float SaturationDoTemperature = 27.0; /* ^C */ -float averageVoltage; +int analogBufferIndex = 0; +int copyIndex = 0; +float SaturationDoVoltage; /* mV */ +float SaturationDoTemperature; /* ^C */ +float averageVoltage; +bool isCalibrating = false; + AnalogIn DOSensor(SENSOR_1_PIN); DS1820 probe(SENSOR_2_PIN); @@ -53,9 +65,12 @@ } void SENSOR_AnalogRead() { + /* Convert from 0 - 1 (float) resolution to 10-bit ADC resolution */ + /* Same as the example from DFRobot Arduino */ float analogReadRaw = DOSensor.read(); float voltageRaw = analogReadRaw*3.3; analogBuffer[analogBufferIndex] = (int)((voltageRaw * 1023.0)/5.0); + printf("Analog read %d %d\r\n", analogBufferIndex, analogBuffer[analogBufferIndex]); analogBufferIndex++; if(analogBufferIndex == SCOUNT) { @@ -64,6 +79,12 @@ } void SENSOR_GetDOValue() { + /* Read temperature */ + #ifdef PROBE_EXIST + probe.convertTemperature(true, DS1820::all_devices); + temperature = probe.temperature(); + #endif + for(copyIndex = 0; copyIndex < SCOUNT; copyIndex++) { analogBufferTemp[copyIndex]= analogBuffer[copyIndex]; } @@ -71,17 +92,65 @@ averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF/1024.0; printf("Average voltage %.2f\r\n", averageVoltage); /* calculate the do value, doValue = Voltage / SaturationDoVoltage * SaturationDoValue(with temperature compensation) */ + SaturationDoTemperature = temperature; doValue = (SaturationValueTab[(int)(SaturationDoTemperature + 0.5)] * averageVoltage) / (float)(SaturationDoVoltage); float a = 1; printf("SaturationDoVoltage %.2f; DO Value %.2f mg/L\r\n", SaturationDoVoltage, doValue/a); } -void SENSOR_DoCalibration() { +void SENSOR_DoCalibration(uint8_t CurrentCalibrationMode) { + static bool doCalibrationFinishFlag = false, enterCalibrationFlag = false; + float voltageValueStore; + switch (CurrentCalibrationMode) { + case 0: + if(enterCalibrationFlag) { + printf("Command Error\r\n"); + } + break; + + case CALIBRATION: + enterCalibrationFlag = true; + doCalibrationFinishFlag = false; + printf(">>>Enter Calibration Mode<<<\r\n"); + printf(">>>Please put the probe into the saturation oxygen water!<<<\r\n\r\n"); + break; + + case SATCAL: + if (enterCalibrationFlag) { + printf("\r\n>>>Saturation Calibration Finish!<<<\r\n\r\n"); + /* Convert from float to uint32_t */ + uint32_t tempAverageVoltage = (uint32_t)averageVoltage; + if ((averageVoltage - 0.5) >= (float)(tempAverageVoltage)) { + tempAverageVoltage++; + } + printf("averageVoltage %d\r\n", (uint32_t)tempAverageVoltage); + + FP_WriteConfigValues((uint32_t)(tempAverageVoltage)); + SaturationDoVoltage = averageVoltage; + doCalibrationFinishFlag = true; + } + break; + + case EXIT: + if (enterCalibrationFlag) { + if(doCalibrationFinishFlag) { + printf("\r\n>>>Calibration Successful\r\n"); + } + else { + printf(">>>Calibration Failed\r\n"); + } + printf("Exit Calibration Mode<<<\r\n\r\n"); + doCalibrationFinishFlag = false; + enterCalibrationFlag = false; + } + break; + + default: break; + } } void SENSOR_ReadDoCharacteristicValues() { - FP_WriteConfigValues(1255); uint32_t int_SaturationDoVoltage = FP_ReadValue(SAT_DO_VOLT_ADDRESS); printf("Read SaturationDoVoltage %d\r\n", int_SaturationDoVoltage); SaturationDoVoltage = (float)int_SaturationDoVoltage;
--- a/Sensor/ReadSensor.h Tue Feb 27 14:51:18 2018 +0000 +++ b/Sensor/ReadSensor.h Sun Mar 04 07:57:56 2018 +0000 @@ -8,7 +8,9 @@ #define VREF 5000 #define SCOUNT 30 /* sum of sample point */ -void SENSOR_DoCalibration(); +//#define PROBE_EXIST + +void SENSOR_DoCalibration(uint8_t CurrentCalibrationMode); void SENSOR_AnalogRead(); void SENSOR_GetDOValue(); void SENSOR_ReadDoCharacteristicValues();