Duy tran / Mbed OS iot_water_monitor_v2

Dependencies:   easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code

Files at this revision

API Documentation at this revision

Comitter:
DuyLionTran
Date:
Wed Feb 14 14:45:35 2018 +0000
Parent:
35:fc800d35c1ba
Child:
37:338e3bc04e57
Commit message:
* version 2.6 02-14-2017: DO Sensor added, calibration is still on the way

Changed in this revision

Application/CommandExecution.cpp Show annotated file Show diff for this revision Revisions of this file
Application/main.cpp Show annotated file Show diff for this revision Revisions of this file
Sensor/ReadSensor.cpp Show annotated file Show diff for this revision Revisions of this file
Sensor/ReadSensor.h Show annotated file Show diff for this revision Revisions of this file
Simple-MQTT/SimpleMQTT.h Show annotated file Show diff for this revision Revisions of this file
--- a/Application/CommandExecution.cpp	Wed Feb 14 04:28:24 2018 +0000
+++ b/Application/CommandExecution.cpp	Wed Feb 14 14:45:35 2018 +0000
@@ -12,6 +12,6 @@
 }
 
 void CE_SetRTCTime(uint32_t CurrentEpochTime) {
-    printf("New local time value set");
+    printf("New local time value set\r\n");
     set_time(CurrentEpochTime);
 }
\ No newline at end of file
--- a/Application/main.cpp	Wed Feb 14 04:28:24 2018 +0000
+++ b/Application/main.cpp	Wed Feb 14 14:45:35 2018 +0000
@@ -2,7 +2,8 @@
   * Revision
   * version 1.0
   * ....
-  * version 2.5 02-14-2017: 3rd relay and remote time setting are added
+  * 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
   */
 
 /***************************************************************
@@ -22,6 +23,8 @@
 #define INTERVAL_BETWEEN_EACH_UPLOAD_TYPE	5   /* The interval between each upload type in second */
 #define RECONNECT_WIFI                      60  /* Try to reconnect to wifi */
 
+#define READ_ANALOG_MS						30
+#define PROCESS_DO_VALUE_S					1
 /***************************************************************
  * Variables
  ***************************************************************/
@@ -32,9 +35,11 @@
 uint32_t    noWiFilastRead 			= 0;
 uint16_t    intervalSecondCounter   = 0;  
 uint32_t    uploadPeriodCounter 	= 0;
+uint32_t 	lastReadAnalog			= 0;
 
 struct UploadValue DataStruct;
 
+extern float doValue;
 
 /***************************************************************
  * Structs/Classess
@@ -45,12 +50,14 @@
 DigitalOut  espEn(D2);
 DigitalOut  espRs(D7);
 
-Timer UploadTimer;
+Timer 		UploadTimer;
+Timer 		ReadAnalogTimer;
+Ticker 		DisplayDO;
 /***************************************************************
  * Unity function definitions
  ***************************************************************/
 void ReadAllFlashValues();
- 
+void ProcessDOVal(); 
 /***************************************************************
  * Unity function declarations
  ***************************************************************/ 
@@ -58,10 +65,10 @@
 	DataStruct.ADC_PHVal = 0.85;
 	DataStruct.ADC_DOVal = 0.95;
 	DataStruct.SENSOR_PHVal = 17.8;
-	DataStruct.SENSOR_D0Val = 18.9;
+	DataStruct.SENSOR_DOVal = 18.9;
 	DataStruct.RELAY_State_1			= FP_ReadValue(RELAY1_ADDRESS);
 	DataStruct.RELAY_State_2			= FP_ReadValue(RELAY2_ADDRESS);
-	DataStruct.RELAY_State_2			= FP_ReadValue(RELAY3_ADDRESS);
+	DataStruct.RELAY_State_3			= FP_ReadValue(RELAY3_ADDRESS);
 	DataStruct.CONFIG_Mode				= FP_ReadValue(MODE_ADDRESS);
 	DataStruct.CONFIG_MinOxi			= FP_ReadValue(MIN_OXI_ADDRESS);
 	DataStruct.CONFIG_MaxOxi			= FP_ReadValue(MAX_OXI_ADDRESS);
@@ -72,37 +79,50 @@
 	CE_HandleRelays(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3);
 }
 
+void ProcessDOVal() {
+	SENSOR_GetDOValue();
+	DataStruct.SENSOR_DOVal = doValue;
+}
 /***************************************************************
  * Main
  ***************************************************************/ 
 int main() {   
    	pc.baud(115200);
    	UploadTimer.start();
+   	ReadAnalogTimer.start();
+   	DisplayDO.attach(&ProcessDOVal, PROCESS_DO_VALUE_S);
    	espEn = 1;
    	espRs = 1;
    	lastRead = 0;
    	pc.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n");     
    	pc.printf("\r\nconnecting to AP\r\n");            
-
+	
    	NetworkInterface* network = easy_connect(true);
    	if (!network) {
        	printf ("Error easy_connect\n\r");
+       	wifiConnected = false;
    	} 
-   	MQTTNetwork mqttNetwork(network);	
-   	MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork);		
-   	printf ("ATTEMPT CONNECT\n\r");
-   	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
-   	}
+	printf ("ATTEMPT CONNECT\n\r");
+	MQTTNetwork mqttNetwork(network);	
+	MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork);	
+	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
+	}
+
 	ReadAllFlashValues();
+	SENSOR_Calib();
    	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();
+		}
 		if (wifiConnected) {
 			if(connected == true) {
 		       	if ((uint32_t)(UploadTimer.read() - lastRead) >= READ_SECOND) {               // Read timer every readSecond(s)	
--- a/Sensor/ReadSensor.cpp	Wed Feb 14 04:28:24 2018 +0000
+++ b/Sensor/ReadSensor.cpp	Wed Feb 14 14:45:35 2018 +0000
@@ -1,7 +1,7 @@
 #include "mbed.h"
 #include "ReadSensor.h"
 
-const float saturationValueTab[41] = {      //saturation dissolved oxygen concentrations at various temperatures
+const float SaturationValueTab[41] = {      /* saturation dissolved oxygen concentrations at various temperatures */
 14.46, 14.22, 13.82, 13.44, 13.09,
 12.74, 12.42, 12.11, 11.81, 11.53,
 11.26, 11.01, 10.77, 10.53, 10.30,
@@ -13,21 +13,61 @@
 6.41,
 };
 
-float saturationDoVoltage; 
-float saturationDoTemperature;
-float averageVoltage;
+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 */
+int     analogBuffer[SCOUNT];                   /* store the analog value in the array, readed from ADC */
+int     analogBufferTemp[SCOUNT];
+int     analogBufferIndex = 0;
+int     copyIndex = 0;
+float   SaturationDoVoltage = 1127.6;           /* mV */
+float   SaturationDoTemperature = 25.0;         /* ^C */
+float   averageVoltage;
+AnalogIn    DOSensor(SENSOR_1_PIN);
 
-AnalogIn    phSensor(SENSOR_1_PIN);
-AnalogIn    DOSensor(SENSOR_2_PIN);
+int getMedianNum(int bArray[], int iFilterLen) {
+    int bTab[iFilterLen];
+    for (uint8_t i = 0; i < iFilterLen; i++) {
+        bTab[i] = bArray[i];
+    }
+    int i, j, bTemp;
+    for (j = 0; j < iFilterLen - 1; j++) {
+        for (i = 0; i < iFilterLen - j - 1; i++) {
+            if (bTab[i] > bTab[i + 1]) {
+                bTemp = bTab[i];
+                bTab[i] = bTab[i + 1];
+                bTab[i + 1] = bTemp;
+            }
+        }
+    }
+    if ((iFilterLen & 1) > 0) {
+        bTemp = bTab[(iFilterLen - 1) / 2];
+    }
+    else {
+        bTemp = (bTab[iFilterLen / 2] + bTab[iFilterLen / 2 - 1]) / 2;
+    }
+    return bTemp;
+}
+
+void SENSOR_AnalogRead() {
+    analogBuffer[analogBufferIndex] = (int)(DOSensor.read() * 100);
+    printf("Analog read %d \r\n", analogBuffer[analogBufferIndex]);
+    analogBufferIndex++;
+    if(analogBufferIndex == SCOUNT) {
+        analogBufferIndex = 0;
+    }
+}
+
+void SENSOR_GetDOValue() {
+    for(copyIndex = 0; copyIndex < SCOUNT; copyIndex++) {
+        analogBufferTemp[copyIndex]= analogBuffer[copyIndex];
+    }   
+    /* read the value more stable by the median filtering algorithm */
+    averageVoltage = getMedianNum(analogBufferTemp, SCOUNT) * (float)VREF; 
+    /* calculate the do value, doValue = Voltage / SaturationDoVoltage * SaturationDoValue(with temperature compensation) */
+    doValue = (SaturationValueTab[0] + (int)(SaturationDoTemperature + 0.5)) * averageVoltage / SaturationDoVoltage;  
+    printf("DO Value %.2f mg/L\r\n", doValue);
+}
 
 void SENSOR_Calib() {
     
-}
-
-float SENSOR_ReadPHADC() {
-    return phSensor.read();
-}
-
-float SENSOR_GetPHValue() {
-    
 }
\ No newline at end of file
--- a/Sensor/ReadSensor.h	Wed Feb 14 04:28:24 2018 +0000
+++ b/Sensor/ReadSensor.h	Wed Feb 14 14:45:35 2018 +0000
@@ -1,30 +1,15 @@
 #ifndef __READSENSOR_H__
 #define __READSENSOR_H__
 
-#define SENSOR_1_PIN  (A0)
-#define SENSOR_2_PIN  (A1)
+#define SENSOR_1_PIN  (A5)
+#define SENSOR_2_PIN  (A4)
 #define SENSOR_3_PIN  (A3)
-#define SENSOR_4_PIN  (A4)
-
-#define SaturationDoVoltageAddress     12          //the address of the Saturation Oxygen voltage stored in the Flash
-#define SaturationDoTemperatureAddress 16      //the address of the Saturation Oxygen temperature stored in the Flash
-
-#define VREF           3.3 
-#define SCOUNT         30 
 
-/** brief   Perform calibration for pH sensor
- *  retral  None 
- */
-void SENSOR_Calib();
+#define VREF           33 
+#define SCOUNT         30   /* sum of sample point */
 
-/** brief   Read the analog value of pH sensor
- *  retral  pH ADC value 
- */
-float SENSOR_ReadPHADC();
-
-/** brief   Convert the ADC value read from pH sensor into pH value
- *  retral  pH value 
- */
-float SENSOR_GetPHValue();
-
+void SENSOR_Calib();
+void SENSOR_AnalogRead();
+void SENSOR_GetDOValue();
+          
 #endif /* __READSENSOR_H__ */
\ No newline at end of file
--- a/Simple-MQTT/SimpleMQTT.h	Wed Feb 14 04:28:24 2018 +0000
+++ b/Simple-MQTT/SimpleMQTT.h	Wed Feb 14 14:45:35 2018 +0000
@@ -45,7 +45,7 @@
     float ADC_DOVal;
     
     float SENSOR_PHVal;
-    float SENSOR_D0Val;
+    float SENSOR_DOVal;
     
     uint8_t   RELAY_State_1;
     uint8_t   RELAY_State_2;
@@ -126,7 +126,7 @@
  *  param[in]   pHVal         The pHVal value to be sent
  *  retral      returnCode from MQTTClient.h 
  */
-int MQTT_PublishSensorVal(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, float pHVal);
+int MQTT_PublishSensorVal(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, float DOVal);
 
 /** brief       Publish relay states to the server
  *  param[in]   client        MQTT client 
@@ -135,7 +135,7 @@
  *  param[in]   relay2        Relay 2 state
  *  retral      returnCode from MQTTClient.h 
  */
-int MQTT_PublishRelayState(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, int relay1, int relay2);
+int MQTT_PublishRelayState(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, int relay1, int relay2, int relay3);
 
 /** brief       Publish relay states to the server
  *  param[in]   client        MQTT client 
@@ -367,7 +367,7 @@
     return client->publish(pubTopic, message);    
 }
 
-int MQTT_PublishSensorVal(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, float pHVal) {
+int MQTT_PublishSensorVal(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, float DOVal) {
     MQTT::Message message;
     const char* pubTopic = MQTT_EVENT_TOPIC;
             
@@ -379,8 +379,8 @@
     }
     
     strftime(timeBuf, 50, "%Y/%m/%d %H:%M:%S", localtime(&inputTime));
-    sprintf(buf, "{\"type\":2,\"deviceId\":\"PROEVN\",\"time\":\"%s\",\"cmdId\":%d,\"pH0\":%.1f}",
-                timeBuf, commandID, pHVal);
+    sprintf(buf, "{\"type\":2,\"deviceId\":\"PROEVN\",\"time\":\"%s\",\"cmdId\":%d,\"DO\":%.2f}",
+                timeBuf, commandID, DOVal);
     message.qos        = MQTT::QOS0;
     message.retained   = false;
     message.dup        = false;
@@ -394,7 +394,7 @@
     return client->publish(pubTopic, message);  	
 }
 
-int MQTT_PublishRelayState(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, int relay1, int relay2) {
+int MQTT_PublishRelayState(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, int relay1, int relay2, int relay3) {
     MQTT::Message message;
     const char* pubTopic = MQTT_EVENT_TOPIC;         
     char buf[MQTT_MAX_PAYLOAD_SIZE];
@@ -405,8 +405,8 @@
         return MQTT::FAILURE; 
     }
     strftime(timeBuf, 50, "%Y/%m/%d %H:%M:%S", localtime(&inputTime));
-    sprintf(buf, "{\"type\":3,\"deviceId\":\"PROEVN\",\"time\":\"%s\",\"cmdId\":%d,\"relay1\":%d,\"relay2\":%d}",
-                timeBuf, commandID, relay1, relay2);
+    sprintf(buf, "{\"type\":3,\"deviceId\":\"PROEVN\",\"time\":\"%s\",\"cmdId\":%d,\"relay1\":%d,\"relay2\":%d,\"relay3\":%d}",
+                timeBuf, commandID, relay1, relay2, relay3);
     message.qos        = MQTT::QOS0;
     message.retained   = false;
     message.dup        = false;
@@ -449,11 +449,11 @@
 int MQTT_PublishAll(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, time_t inputTime, uint8_t uploadType, struct UploadValue uploadStruct) {
 	int retVal;
     switch (uploadType) {
-        case (ADC_VALUE): 		retVal = MQTT_PublishADC(client, inputTime, uploadStruct.ADC_PHVal);
+        case (ADC_VALUE): 		retVal = MQTT_PublishADC(client, inputTime, uploadStruct.ADC_DOVal);
             break;
-        case (SENSOR_VALUE): 	retVal =  MQTT_PublishSensorVal(client, inputTime, uploadStruct.SENSOR_PHVal);
+        case (SENSOR_VALUE): 	retVal =  MQTT_PublishSensorVal(client, inputTime, uploadStruct.SENSOR_DOVal);
             break;
-        case (RELAY_STATE):		retVal = MQTT_PublishRelayState(client, inputTime, uploadStruct.RELAY_State_1, uploadStruct.RELAY_State_2);
+        case (RELAY_STATE):		retVal = MQTT_PublishRelayState(client, inputTime, uploadStruct.RELAY_State_1, uploadStruct.RELAY_State_2, uploadStruct.RELAY_State_3);
             break;
         case (CONFIG_VALUE): 	retVal = MQTT_PublishConfigValue(client, inputTime, uploadStruct.CONFIG_Mode, uploadStruct.CONFIG_MinOxi, uploadStruct.CONFIG_MaxOxi);
         	break;