Duy tran / Mbed OS iot_water_monitor_v2

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

main.cpp

Committer:
DuyLionTran
Date:
2017-12-01
Revision:
9:268373df20d7
Parent:
8:844796296dea
Child:
10:5d45f805080a

File content as of revision 9:268373df20d7:

/***************************************************************
 * Includes
 ***************************************************************/
#include "mbed.h"
#include "easy-connect.h"
#include "MQTTNetwork.h"
#include "MQTTmbed.h"
#include "MQTTClient.h"
#include "string.h"

/***************************************************************
 * Definitions
 ***************************************************************/
#define logMessage printf
#define MQTTCLIENT_QOS2 (0)
 
#define SENSOR_1_PIN  (A0)
#define SENSOR_2_PIN  (A1)
#define SENSOR_3_PIN  (A3)
#define SENSOR_4_PIN  (A4)
#define RELAY_1_PIN   (D11)
#define RELAY_2_PIN   (D12)

#define ORG           "a4nvkh"
#define DEVICE_TYPE   "Nucleo_8266"
#define DEVICE_ID     "PROEVN"
#define TOKEN         "PROEVN2017"

#define MAX_FAIL_ATTEMPT    (5)

typedef enum {
    MQTT_SUCCESS      =  0,
    MQTT_NETWORK_FAIL = -1,
    MQTT_FAIL         = -2    
} mqtt_ret_val;

/***************************************************************
 * Variables
 ***************************************************************/
/* MQTT Varialbles */
float firmwareVersion = 0.91;  
char server[]     = ORG ".messaging.internetofthings.ibmcloud.com";
char topicCMD[]   = "iot-2/cmd/command/fmt/json";
char topicEvent[] = "iot-2/evt/status_update/fmt/json";
char authMethod[] = "use-token-auth";
char token[]      = TOKEN;
char clientId[]   = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID;
int  ibmPort      = 1883;

/* Internet Varialbles */
bool     internetState = false;
uint8_t  failAttempt   = 0;
uint16_t cmdID         = 0;

/* Time Handles */
uint32_t uploadPeriod = 6;
uint32_t lastRead;

/* Analog Handles */
float ADC_PHVal;
float ADC_DOVal;
float voltageValue;

/***************************************************************
 * Structs/Classess
 ***************************************************************/
NetworkInterface* network = easy_connect(true);
MQTTNetwork mqttNetwork(network);
MQTT::Client<MQTTNetwork, Countdown> client(mqttNetwork);

Timer  readTime;
Ticker readADC;

AnalogIn phSensor(SENSOR_1_PIN);
AnalogIn DOSensor(SENSOR_2_PIN);

Serial serial(USBTX, USBRX);

/***************************************************************
 * Unity function definitions
 ***************************************************************/
/**
  * @brief  Establish a connection to the internet.
  * @retval MQTT_SUCCESS if connected to the internet, MQTT_NETWORK_FAIL if failed to establish the connection
  */
int MQTT_internetConnect();

/**
  * @brief  Connect to the MQTT data and subscribe to the topic.
  * @retval MQTT_SUCCESS if connected to the data and subscribed the topic successfully.
  */
int MQTT_networkConnect();

/**
  * @brief  Connect to the internet and then MQTT network.
  * @retval MQTT_SUCCESS if the 2 above functions succeeded.
  */
int MQTT_init();

/**
  * @brief  Publish a message to the MQTT topic.
  * @param  sendMessage[in]: the message to be sent.
  * @retval MQTT_SUCCESS if the message is sent.
  */
int MQTT_publish(char *sendMessage);

/**
  * @brief  Publish the information about the device when start up.
  * @retval None.
  */
void MQTT_publishDeviceInfo();

/**
  * @brief  Read ADC values 
  * @retval None.
  */
void getADC();

/**
  * @brief  Start the timer 
  * @retval None.
  */
void setTimer();

/***************************************************************
 * Callbacks
 ***************************************************************/
void messageArrived(MQTT::MessageData& md) {
    MQTT::Message &message = md.message;
    logMessage("Message arrived: qos %d, retained %d, dup %d, packetid %d\r\n", message.qos, message.retained, message.dup, message.id);
    logMessage("Payload %.*s\r\n", message.payloadlen, (char*)message.payload);
}

/***************************************************************
 * Unity function declarations
 ***************************************************************/
int MQTT_internetConnect() {
    network = easy_connect(true);
    
    if (!network) {
        printf("Cannot connect to the internet\r\n");
        internetState = false;
        return MQTT_SUCCESS;
    }
    else {
        printf("Reconnected to the internet\r\n");
        internetState = true;
        return MQTT_NETWORK_FAIL;
    }
} 

int MQTT_networkConnect() {
    logMessage("Connecting to %s:%d\r\n", server, ibmPort);
    
    int rc  = MQTT_SUCCESS;
    rc      = mqttNetwork.connect(server, ibmPort);
    
    if (rc != 0) {
        logMessage("rc from TCP connect is %d\r\n", rc);
        return rc;   
    }
          
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.MQTTVersion            = 3;
    data.clientID.cstring       = clientId;
    data.username.cstring       = authMethod;
    data.password.cstring       = token;
    
    if ((rc = client.connect(data)) != 0) {
        logMessage("rc from MQTT connect is %d\r\n", rc);
        return rc;
    }
    
    if ((rc = client.subscribe(topicCMD, MQTT::QOS0, messageArrived)) != 0) {
        logMessage("rc from MQTT subscribe is %d\r\n", rc);        
        return rc;
    }
    
    return rc;
}

int MQTT_init() {
    int ret = MQTT_SUCCESS;
    if (!network) {
        logMessage("Failed to connect to the internet, retrying\r\n");
        ret = MQTT_internetConnect();
        if (ret != MQTT_SUCCESS) {
            return ret;
        }
    }
    internetState = true;
    
    ret = MQTT_networkConnect();
    if (ret != MQTT_SUCCESS) {
        printf("Fail to connect to MQTT or fail to subscribe\r\n");
        internetState = false;
    }
    
    return ret;
}

int MQTT_publish(char *sendMessage) {
    MQTT::Message msg;
    msg.qos        = MQTT::QOS0;
    msg.retained   = false;
    msg.dup        = false;
    msg.payload    = sendMessage;
    msg.payloadlen = strlen(sendMessage);
    return client.publish((char *)topicEvent, msg);        
}

void MQTT_publishDeviceInfo() {
    char greetingMessage[100];
    sprintf(greetingMessage, "{\"Device Name\":\"PROEVN\",\"Firmware Version\":%.2f}", firmwareVersion);   
    printf("Sending payload: %s\r\n", greetingMessage);
    if (!MQTT_publish((char *)greetingMessage)) {
        printf("Publish ok\r\n");
        failAttempt = 0;
    }    
    else {
        printf("Publish failed\r\n");
        failAttempt++;
    }   
}

void upload() {
    char payload[100];
    sprintf(payload, "{\"Type\":1,\"Command ID\":%d,\"ADC0\":%.2f,\"Voltage 1\":%.2f}", cmdID, ADC_PHVal, voltageValue);
    if (!MQTT_publish(payload)) {
        cmdID++;
    }    
}

void getADC() {
    ADC_PHVal    = phSensor.read();
//    ADC_DOVal    = DOSensor.read();
    voltageValue = (ADC_PHVal * 5.0);  
}

void setTimer() {
    readTime.start();  
    readADC.attach(&getADC, 1);
}

/***************************************************************
 * Main
 ***************************************************************/
void main(int argc, char* argv[]) {
    serial.baud(115200);
    
    logMessage("IoT Water Monitor project, firmware version is %.2f\r\n", firmwareVersion);
    
    MQTT_init();
    wait(0.5);
    MQTT_publishDeviceInfo();
    
    
    setTimer();
    
    uploadPeriod    = 6;
    printf("Get into loop\r\n");
    
    
    while(true) {   
        if ((uint32_t)(readTime.read() - lastRead) > uploadPeriod) {
            char payload[100];
            sprintf(payload, "{\"Type\":1,\"Command ID\":%d,\"ADC0\":%.2f,\"Voltage 1\":%.2f}", cmdID, ADC_PHVal, voltageValue);
            printf("MQTT publish %s\r\n", payload);
            if (!MQTT_publish(payload)) {
                printf("Publish ok\r\n");
                cmdID++;
                failAttempt = 0;
            }    
            else {
                printf("Publish failed\r\n");
                failAttempt++;
            }
            if (failAttempt == MAX_FAIL_ATTEMPT) {
                failAttempt = 0;
                internetState = false;
            }
            lastRead = readTime.read();
        }   
        client.yield(100);
    }
        
}