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: BufferedSoftSerial SDFileSystem
Fork of ATT_AWS_IoT_demo by
main.cpp
- Committer:
- RaghuT
- Date:
- 2017-08-31
- Revision:
- 34:b153e7a4e2d5
- Parent:
- 33:48172a2972b6
File content as of revision 34:b153e7a4e2d5:
#include <cstdlib>
#include "mbed.h"
// Serial extension
#include "MODSERIAL.h"
#include "SoftSerial.h"
#include "BufferedSoftSerial.h"
// Network includes
#include "WNCInterface.h"
#include "network_interface.h"
#include "WncControllerK64F/WncController/WncController.h"
// AWS includes
#include "aws_iot_log.h"
#include "aws_iot_version.h"
#include "aws_iot_shadow_interface.h"
#include "aws_iot_shadow_json_data.h"
#include "aws_iot_config.h"
#include "aws_iot_mqtt_interface.h"
#if DEBUG_LEVEL > 0
#include "mbedtls/debug.h"
#endif
//=====================================================================================================================
//
// Defines
//
//=====================================================================================================================
// LED Colors
#define COLOR_OFF 0x00
#define COLOR_RED 0x01
#define COLOR_GREEN 0x02
#define COLOR_BLUE 0x04
#define COLOR_WHITE 0x07
#define NUM_COLORS 5
// AWS defines
#define PATH_MAX 1024
#define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 500 // NOTE: Be wary of this if your JSON doc grows
#define SHADOW_SYNC_INTERVAL 5.0 // How often we sync with AWS Shadow (in seconds)
// Comment out the following line if color is not supported on the terminal
//#define USE_COLOR
#ifdef USE_COLOR
#define BLK "\033[30m"
#define RED "\033[31m"
#define GRN "\033[32m"
#define YEL "\033[33m"
#define BLU "\033[34m"
#define MAG "\033[35m"
#define CYN "\033[36m"
#define WHT "\033[37m"
#define DEF "\033[39m"
#else
#define BLK
#define RED
#define GRN
#define YEL
#define BLU
#define MAG
#define CYN
#define WHT
#define DEF
#endif
// Sensor defines
#define CTOF(x) ((x)*1.8+32) // Temperature
//=====================================================================================================================
//
// Globals
//
//=====================================================================================================================
// Controls LED color
unsigned char ledColor = COLOR_OFF;
// These defines are pulled from aws_iot_config.h
char HostAddress[255] = AWS_IOT_MQTT_HOST;
char MqttClientID[32] = AWS_IOT_MQTT_CLIENT_ID;
char ThingName[32] = AWS_IOT_MY_THING_NAME;
char PortString[5] = "8883";
uint32_t port = AWS_IOT_MQTT_PORT;
char iccidName[21] = "12345678901234567890";
// Sensor data
float temperature = 0.0;
float humidity = 0.0;
char slaveData[500];
//Cell signal
int signalQuality = 0;
//Variable to store data usage
unsigned int dataUsage = 0;
//Variable to store latency
unsigned int latency = 0;
unsigned int latencyHistory[10];
int latencyHistoryIndex = 0;
//slave JSON to publish
string slaveJSON = "";
//=====================================================================================================================
//
// Devices
//
//=====================================================================================================================
// GPIOs for RGB LED
DigitalOut led_green(LED_GREEN);
DigitalOut led_red(LED_RED);
DigitalOut led_blue(LED_BLUE);
// USB Serial port (to PC)
MODSERIAL pc(USBTX,USBRX,256,256);
// radio serial
BufferedSoftSerial radio(PTC4, PTA2);
// I2C bus (SDA, SCL)
I2C i2c(PTC11, PTC10);
//Timer
Timer deviceTimer;
Timer updateTimer;
Timer disconnectTimer;
//=====================================================================================================================
//
// Functions
//
//=====================================================================================================================
//*********************************************************************************************************************
//* Prints the given format to the PC serial port. Exposed to all files via aws_iot_log.h
//*********************************************************************************************************************
void pc_print(const char * format, ...)
{
va_list vl;
va_start(vl, format);
pc.vprintf(format, vl);
va_end(vl);
}
//*********************************************************************************************************************
//* Set the RGB LED's Color
//* LED Color 0=Off to 7=White. 3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue)
//*********************************************************************************************************************
void SetLedColor(unsigned char ucColor)
{
//Note that when an LED is on, you write a 0 to it:
led_red = !(ucColor & 0x1); //bit 0
led_green = !(ucColor & 0x2); //bit 1
led_blue = !(ucColor & 0x4); //bit 2
}
//Averages previous latency values in latency array
unsigned int getAverageLatencyHistory()
{
unsigned int total = 0;
for(int i = 0; i < latencyHistoryIndex; i++) {
total += latencyHistory[i];
}
total = total / latencyHistoryIndex;
return total;
}
//=====================================================================================================================
//
// AWS Shadow Callbacks
//
//=====================================================================================================================
//*********************************************************************************************************************
//* This is the callback function that fires when an update is sent. It will print the update response status.
//*********************************************************************************************************************
void ShadowUpdateStatusCallback(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status, const char *pReceivedJsonDocument, void *pContextData)
{
INFO("Shadow Update Status Callback");
if (status == SHADOW_ACK_TIMEOUT) {
INFO("Update Timeout--");
} else if (status == SHADOW_ACK_REJECTED) {
INFO("Update RejectedXX");
} else if (status == SHADOW_ACK_ACCEPTED) {
INFO("Update Accepted!!"); // Good
}
deviceTimer.stop();
latencyHistory[latencyHistoryIndex] = latency;
unsigned int average = getAverageLatencyHistory();
latency = deviceTimer.read_us() * 0.5 + average * 0.5;
latencyHistoryIndex = (latencyHistoryIndex + 1) % 10;
deviceTimer.reset();
}
//Callback when dataUsage stats are updated
void dataUsageCallback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext)
{
INFO("Data usage callback detected");
}
//*********************************************************************************************************************
//* Disconnect handling (used with alternate demo)
//*********************************************************************************************************************
void disconnectCallbackHandler(void)
{
WARN("MQTT Disconnect");
IoT_Error_t rc = NONE_ERROR;
if(aws_iot_is_autoreconnect_enabled()) {
INFO("Auto Reconnect is enabled, Reconnecting attempt will start now");
} else {
WARN("Auto Reconnect not enabled. Starting manual reconnect...");
rc = aws_iot_mqtt_attempt_reconnect();
if(RECONNECT_SUCCESSFUL == rc) {
WARN("Manual Reconnect Successful");
} else {
WARN("Manual Reconnect Failed - %d", rc);
}
}
}
//*********************************************************************************************************************
//* Get slave data over uart interface
//*********************************************************************************************************************
void getSlaveJSON()
{
slaveJSON.clear();
if(radio.writeable()) {
radio.printf("d");
while(radio.readable()) {
slaveJSON += radio.getc();
}
}
strcpy(slaveData, slaveJSON.c_str());
}
//*********************************************************************************************************************
//* Push master data over to radio
//*********************************************************************************************************************
void sendMasterData()
{
if(radio.writeable()) {
radio.printf("*%d,%d,%d\n", dataUsage, latency, signalQuality);
}
}
//=====================================================================================================================
//
// Main
//
//=====================================================================================================================
int main()
{
// Set baud rate for PC Serial
pc.baud(115200);
radio.baud(9600);
INFO("Program Start");
IoT_Error_t rc = NONE_ERROR;
char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER];
size_t sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]);
//JSON struct for signal strength readings
jsonStruct_t signalStrengthHandler;
signalStrengthHandler.cb = NULL;
signalStrengthHandler.pKey = "signalStrength";
signalStrengthHandler.pData = &signalQuality;
signalStrengthHandler.type = SHADOW_JSON_INT16;
//JSON struct for data usage
jsonStruct_t dataUsageHandler;
dataUsageHandler.cb = dataUsageCallback;
dataUsageHandler.pKey = "dataUsage";
dataUsageHandler.pData = &dataUsage;
dataUsageHandler.type = SHADOW_JSON_UINT32;
//JSON struct for slave data
jsonStruct_t slaveDataHandler;
slaveDataHandler.cb = NULL;
slaveDataHandler.pKey = "slaves";
slaveDataHandler.pData = slaveData;
slaveDataHandler.type = SHADOW_JSON_STRING;
//JSON struct for latency
jsonStruct_t latencyHandler;
latencyHandler.cb = NULL;
latencyHandler.pKey = "latency";
latencyHandler.pData = &latency;
latencyHandler.type = SHADOW_JSON_UINT32;
INFO("AWS IoT SDK Version(dev) %d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
INFO("Using #defines in aws_iot_config.h and certs from certs.cpp for AWS config.");
// Startup signal - blinks through RGBW then turns off
SetLedColor(COLOR_RED);
wait(.5);
SetLedColor(COLOR_GREEN);
wait(.5);
SetLedColor(COLOR_BLUE);
wait(.5);
SetLedColor(COLOR_WHITE);
wait(.5);
SetLedColor(COLOR_OFF);
// Boot the Avnet Shield before any other operations
INFO("Net Boot...");
net_modem_boot();
// Intialize MQTT/Cert parameters
ShadowParameters_t sp = ShadowParametersDefault;
#ifdef USING_SD_CARD
rc = (IoT_Error_t)mbedtls_mqtt_config_parse_file(&sp, AWS_MQTT_CONFIG_FILENAME);
if (NONE_ERROR != rc) {
ERROR("Failed to initialize mqtt parameters %d", rc);
return rc;
}
sp.pClientCRT = AWS_IOT_CERTIFICATE_FILENAME;
sp.pClientKey = AWS_IOT_PRIVATE_KEY_FILENAME;
sp.pRootCA = AWS_IOT_ROOT_CA_FILENAME;
#else
sp.pMyThingName = AWS_IOT_MY_THING_NAME;
sp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID;
sp.pHost = HostAddress;
sp.port = port;
sp.pClientCRT = AWS_IOT_CERTIFICATE_FILENAME;
sp.pClientKey = AWS_IOT_PRIVATE_KEY_FILENAME;
sp.pRootCA = AWS_IOT_ROOT_CA_FILENAME;
#endif
INFO("Initialize the MQTT client...");
MQTTClient_t mqttClient;
aws_iot_mqtt_init(&mqttClient);
INFO("Shadow Init...");
rc = aws_iot_shadow_init(&mqttClient);
if (NONE_ERROR != rc) {
SetLedColor(COLOR_RED);
ERROR("Shadow Init Error %d", rc);
return rc;
}
INFO("Shadow Connect...");
rc = aws_iot_shadow_connect(&mqttClient, &sp);
if (NONE_ERROR != rc) {
SetLedColor(COLOR_RED);
ERROR("Shadow Connection Error %d", rc);
return rc;
}
// Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
// #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
// #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
rc = mqttClient.setAutoReconnectStatus(true);
if (NONE_ERROR != rc) {
ERROR("Unable to set Auto Reconnect to true - %d", rc);
SetLedColor(COLOR_RED);
return rc;
}
INFO("Shadow Register Delta...");
rc = aws_iot_shadow_register_delta(&mqttClient, &dataUsageHandler);
if (NONE_ERROR != rc) {
ERROR("Shadow Register Delta dataUsage Error");
SetLedColor(COLOR_RED);
return rc;
}
INFO("Will attempt to sync with device shadow every %f seconds.", SHADOW_SYNC_INTERVAL);
updateTimer.start();
disconnectTimer.start();
// Loop and publish changes from the FRDM board
while (NETWORK_ATTEMPTING_RECONNECT == rc || RECONNECT_SUCCESSFUL == rc || NONE_ERROR == rc) {
if(updateTimer.read() < SHADOW_SYNC_INTERVAL) {
continue;
}
updateTimer.reset();
// Looks for incoming socket messages
rc = aws_iot_shadow_yield(&mqttClient, 200);
if (NETWORK_ATTEMPTING_RECONNECT == rc) {
// If the client is attempting to reconnect we will skip the rest of the loop.
INFO("Attempting to reconnect...");
wait(1);
continue;
}
//Read signal quality
signalQuality = WNCInterface::_pwnc->getDbmRssi();
//get slave data
getSlaveJSON();
INFO("\n=======================================================================================\n");
// Initialize JSON shadow document
rc = aws_iot_shadow_init_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
if (rc == NONE_ERROR) {
// Updates the 'reported' color/temp/humidity
rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 4, &signalStrengthHandler,
&dataUsageHandler, &slaveDataHandler, &latencyHandler);
if (rc == NONE_ERROR) {
rc = aws_iot_finalize_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
if (rc == NONE_ERROR) {
INFO("Update Shadow: %s", JsonDocumentBuffer);
deviceTimer.start();
rc = aws_iot_shadow_update(&mqttClient, sp.pMyThingName, JsonDocumentBuffer,
ShadowUpdateStatusCallback, NULL, 15, true);
}
}
}
sendMasterData();
if(disconnectTimer.read() >= 60) {
//WNCInterface::_pwnc->at_reinitialize_mdm();
NVIC_SystemReset();
}
}
if (NONE_ERROR != rc) {
ERROR("An error occurred in the loop %d", rc);
SetLedColor(COLOR_RED);
}
INFO("Disconnecting");
rc = aws_iot_shadow_disconnect(&mqttClient);
if (NONE_ERROR != rc) {
ERROR("Disconnect error %d", rc);
SetLedColor(COLOR_RED);
}
return rc;
}
