Duy tran / Mbed OS 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-03-08
Revision:
47:c3707a4f69a7
Parent:
46:f545b8f7f242
Child:
48:a7ed665844cd

File content as of revision 47:c3707a4f69a7:

/**
  * 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
  */

/***************************************************************
 * Includes
 ***************************************************************/
#include "mbed.h"

#include "ReadSensor.h"
#include "SimpleMQTT.h"
#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

/***************************************************************
 * Variables
 ***************************************************************/
bool        isUploading         = false;
bool		isSendingData       = false;
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;
IWDG_HandleTypeDef IwdgHandle;

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();

/***************************************************************
 * 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);
	printf("All values: %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);
	CE_HandleRelays(DataStruct.RELAY_State_1, DataStruct.RELAY_State_2, DataStruct.RELAY_State_3);
}

void SensorRun() {
	if (!isSendingData) {
		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() {
   	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;	
}
/***************************************************************
 * Main
 ***************************************************************/ 
int main() {   
   	pc.baud(115200);
   	printf("PROGRAM STARTS\r\n");
	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");            
	
   	NetworkInterface* network = easy_connect(true);
   	if (!network) {
       	printf ("Error easy_connect\n\r");
       	wifiConnected = false;
   	} 
	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
	}
	
	DisplayDO.attach(&SensorRun, PROCESS_SENSOR_VALUE_S);
	ReadAllFlashValues();
	SENSOR_ReadDoCharacteristicValues();
   	myled = 1;   
	while (true) {
		time_t seconds = time(NULL);	
		#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)	
		       		printf("Upload time %ds\r\n", DataStruct.CONFIG_UploadInterval);		
					if (!isUploading) {
						uploadPeriodCounter++;
						if (uploadPeriodCounter == DataStruct.CONFIG_UploadInterval) {	
							uploadPeriodCounter 	= 0;
							isUploading         	= true;
							intervalSecondCounter 	= INTERVAL_BETWEEN_EACH_UPLOAD_TYPE;
						}					
					}
					else {
						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 {
								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 */
		    	client.yield(500);                                                        
			} 
			else if (connected == false) {
				connected = true;
			} 			
		}
		else {
			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();
			}
		}
	}
}