Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: easy-connect-v16 Watchdog FP MQTTPacket RecordType-v-16 watersenor_and_temp_code
Application/main.cpp
- Committer:
- DuyLionTran
- Date:
- 2018-03-30
- Revision:
- 56:3729bedac5ab
- Parent:
- 55:c405323f8d5a
- Child:
- 57:898fcb6692cd
File content as of revision 56:3729bedac5ab:
/**
* 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
*/
/***************************************************************
* 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
/***************************************************************
* 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");
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
}
if (wd.WatchdogCausedReset()) {
printf("Watchdog caused reset.\r\n");
}
wd.Configure(24.8);
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);
}
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 {
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();
}
}
}
}