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
main.cpp
- Committer:
- DuyLionTran
- Date:
- 2017-12-07
- Revision:
- 13:344a5e2b2f53
- Parent:
- 11:3802c82a5ae9
- Child:
- 14:0129ac8844ee
File content as of revision 13:344a5e2b2f53:
/***************************************************************
* Includes
***************************************************************/
#include "mbed.h"
#include "easy-connect.h"
#include "MQTTClient.h"
#include "NDefLib/NDefNfcTag.h"
#include "NDefLib/RecordType/RecordURI.h"
#include "MQTTNetwork.h"
#include "MQTTmbed.h"
/***************************************************************
* Definitions
***************************************************************/
// Configuration values needed to connect to IBM IoT Cloud
#define ORG MQTT_ORG_ID // connect to ORG.internetofthings.ibmcloud.com/ For a registered connection, replace with your org
#define ID MQTT_DEVICE_ID // For a registered connection is your device id
#define AUTH_TOKEN MQTT_DEVICE_PASSWORD // For a registered connection is a device auth-token
#define DEFAULT_TYPE_NAME MQTT_DEVICE_TYPE // For a registered connection is device type
#define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type
#define IBM_IOT_PORT MQTT_PORT
#define MQTT_MAX_PACKET_SIZE 400
#define MQTT_MAX_PAYLOAD_SIZE 300
#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)
/***************************************************************
* Variables
***************************************************************/
char *projectName = "WaterMonitor";
uint16_t cmdID = 0;
uint32_t lastRead = 0;
uint32_t uploadInterval = 5;
/* MQTT Varialbles */
static char id[30] = ID; // mac without colons
static char org[12] = ORG;
static char type[30] = TYPE;
static char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
static int connack_rc = 0; // MQTT connack return code
static bool netConnecting = false;
static bool mqttConnecting = false;
static bool netConnected = false;
static bool connected = false;
static int retryAttempt = 0;
static int connectTimeout = 1000;
static char subscription_url[MQTT_MAX_PAYLOAD_SIZE];
char topicCMD[] = "iot-2/cmd/command/fmt/json";
/* Analog Handles */
float ADC_PHVal;
float ADC_DOVal;
/***************************************************************
* Structs/Classess
***************************************************************/
static Serial serial(USBTX, USBRX);
DigitalOut myled(LED1);
AnalogIn phSensor(SENSOR_1_PIN);
AnalogIn DOSensor(SENSOR_2_PIN);
Timer timer;
/***************************************************************
* Unity function definitions
***************************************************************/
void subscribe_cb(MQTT::MessageData & msgMQTT);
int subscribe(char *pubTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client);
int connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network);
int getConnTimeout(int attemptNumber);
void attemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network);
int publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client);
void getADC();
/***************************************************************
* Unity function declarations
***************************************************************/
void subscribe_cb(MQTT::MessageData & msgMQTT) {
char msg[MQTT_MAX_PAYLOAD_SIZE];
msg[0]='\0';
strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen);
printf ("--->>> subscribe_cb msg: %s\n\r", msg);
}
int subscribe(char *pubTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client) {
return client->subscribe(pubTopic, MQTT::QOS1, subscribe_cb);
}
int connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) {
const char* iot_ibm = MQTT_BROKER_URL;
char hostname[strlen(org) + strlen(iot_ibm) + 1];
sprintf(hostname, "%s%s", org, iot_ibm);
// Construct clientId - d:org:type:id
char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
sprintf(clientId, "d:%s:%s:%s", org, type, id);
sprintf(subscription_url, "%s.%s/#/device/%s/%s/", org, "internetofthings.ibmcloud.com", id, DEFAULT_TYPE_NAME);
// Network debug statements
LOG("=====================================\n\r");
LOG("Nucleo IP ADDRESS: %s\n\r", network->get_ip_address());
LOG("Nucleo MAC ADDRESS: %s\n\r", network->get_mac_address());
LOG("Server Hostname: %s port: %d\n\r", hostname, IBM_IOT_PORT);
// for(int i = 0; clientId[i]; i++){ // set lowercase mac
// clientId[i] = tolower(clientId[i]);
// }
LOG("Client ID: %s\n\r", clientId);
LOG("Topic: %s\n\r",MQTT_EVENT_TOPIC);
LOG("Subscription URL: %s\n\r", subscription_url);
LOG("=====================================\n\r");
netConnecting = true;
int rc = mqttNetwork->connect(hostname, IBM_IOT_PORT);
if (rc != 0) {
printf("rc from TCP connect is %d\r\n", rc);
return rc;
}
printf ("--->TCP Connected\n\r");
netConnected = true;
netConnecting = false;
// MQTT Connect
mqttConnecting = true;
MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
data.MQTTVersion = 4;
data.struct_version = 0;
data.clientID.cstring = clientId;
data.keepAliveInterval = MQTT_KEEPALIVE; // in Sec
data.username.cstring = "use-token-auth";
data.password.cstring = auth_token;
printf ("AutToken: %s\n\r", auth_token);
if ((rc = client->connect(data)) != 0) {
printf("rc from MQTT connect is %d\r\n", rc);
connack_rc = rc;
return rc;
}
connected = true;
printf ("--->MQTT Connected\n\r");
if ((rc=subscribe(topicCMD, client)) == 0) {
LOG ("--->>>MQTT subscribed to: %s\n\r", topicCMD);
} else {
LOG ("--->>>ERROR MQTT subscribe : %s\n\r", topicCMD);
}
mqttConnecting = false;
connack_rc = rc;
return rc;
}
int getConnTimeout(int attemptNumber) { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute
// after 20 attempts, retry every 10 minutes
return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600;
}
void attemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) {
connected = false;
while (connect(client, mqttNetwork, network) != MQTT_CONNECTION_ACCEPTED) {
if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) {
printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc);
return; // don't reattempt to connect if credentials are wrong
}
int timeout = getConnTimeout(++retryAttempt);
WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
// if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
// or maybe just add the proper members to do this disconnect and call attemptConnect(...)
// this works - reset the system when the retry count gets to a threshold
if (retryAttempt == 5)
NVIC_SystemReset();
else
wait(timeout);
}
}
int publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client) {
MQTT::Message message;
const char* pubTopic = MQTT_EVENT_TOPIC;
char buf[MQTT_MAX_PAYLOAD_SIZE];
float adc0;
if (!client->isConnected()) {
printf ("---> MQTT DISCONNECTED\n\r"); return MQTT::FAILURE;
}
adc0 = ADC_PHVal;
sprintf(buf,
"{\"Project\":\"%s\",\"Type\":1,\"cmdID\":%d,\"ADC0\":%0.4f}",
projectName, cmdID, adc0);
message.qos = MQTT::QOS0;
message.retained = false;
message.dup = false;
message.payload = (void*)buf;
message.payloadlen = strlen(buf);
if((message.payloadlen + strlen(pubTopic)+1) >= MQTT_MAX_PACKET_SIZE)
printf("message too long!\r\n");
LOG("Publishing %s\n\r", buf);
return client->publish(pubTopic, message);
}
void getADC() {
ADC_PHVal = phSensor.read();
// ADC_DOVal = DOSensor.read();
// voltageValue = (ADC_PHVal * 5.0);
}
/***************************************************************
* Main
***************************************************************/
int main() {
serial.baud(115200);
timer.start();
lastRead = 0;
serial.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n");
serial.printf("\r\nconnecting to AP\r\n");
NetworkInterface* network = easy_connect(true);
if (!network) {
printf ("Error easy_connect\n\r");
return -1;
}
MQTTNetwork mqttNetwork(network);
MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork);
printf ("ATTEMPT CONNECT\n\r");
attemptConnect(&client, &mqttNetwork, network);
if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) {
printf ("---ERROR line : %d\n\r", __LINE__);
while (true)
wait(1.0); // Permanent failures - don't retry
}
myled=1;
int count = 0;
while (true) {
getADC();
if (connected == true) {
if ((uint32_t)(timer.read() - lastRead) >= uploadInterval) { // Publish a message every 3 second
if (publish(&client) != MQTT::SUCCESS) {
myled=0;
count=0;
client.disconnect();
mqttNetwork.disconnect();
attemptConnect(&client, &mqttNetwork, network); // if we have lost the connection
} else {
myled = 1;
count = 0;
cmdID++;
}
lastRead = timer.read();
}
client.yield(500); // allow the MQTT client to receive subscribe messages and manage keep alive
} else if (connected == false) {
connected = true;
} else {
wait(0.5);
}
}
}