Connecting a Multi-Tech Systems Dragonfly™ to Twilio's Sync for IoT Quickstart. Blink a dev board LED.

Dependencies:   MQTT MbedJSONValue mbed mtsas

Fork of DragonflyMQTT by miao zhicheng

Code to connect a Multi-Tech® MultiConnect® Dragonfly™ to Twilio's Sync for IoT: https://www.twilio.com/docs/api/devices

Uses MQTT over TLS and subscribes to a topic where you can control an LED. See also our Quickstart using this code, here: https://www.twilio.com/docs/quickstart/sync-iot/mqtt-multi-tech-multiconnect-dragonfly-sync-iot

Committer:
miaotwilio
Date:
Tue Sep 05 15:00:17 2017 +0000
Revision:
5:ded8fe5991a2
Parent:
3:0a48c984e15b
Child:
6:4a25f3b9caef
add TripDataReader

Who changed what in which revision?

UserRevisionLine numberNew contents of line
miaotwilio 0:b32fa0c757d7 1 #include "MTSCellularManager.hpp"
miaotwilio 5:ded8fe5991a2 2 #include "TripDataReader.hpp"
miaotwilio 0:b32fa0c757d7 3 #include "TlsMQTTClient.hpp"
miaotwilio 0:b32fa0c757d7 4 #include "Certificates.h"
miaotwilio 2:d4dcf1ebaa99 5 #include "config.hpp"
miaotwilio 0:b32fa0c757d7 6 #include <mbed.h>
miaotwilio 0:b32fa0c757d7 7 #include <mtsas.h>
miaotwilio 0:b32fa0c757d7 8 #include <ssl.h>
miaotwilio 0:b32fa0c757d7 9
miaotwilio 0:b32fa0c757d7 10 // This line controls the regulator's battery charger.
miaotwilio 0:b32fa0c757d7 11 // BC_NCE = 0 enables the battery charger
miaotwilio 0:b32fa0c757d7 12 // BC_NCE = 1 disables the battery charger
miaotwilio 0:b32fa0c757d7 13 DigitalOut bc_nce(PB_2);
miaotwilio 5:ded8fe5991a2 14
miaotwilio 1:5a896191c3c4 15 DigitalOut ledMQTTYield(D5);
miaotwilio 5:ded8fe5991a2 16
miaotwilio 1:5a896191c3c4 17 DigitalOut ledGPS(D8);
miaotwilio 1:5a896191c3c4 18
miaotwilio 5:ded8fe5991a2 19 MTSSerial obd(D1, D0);
miaotwilio 5:ded8fe5991a2 20 DigitalOut ledOBD(D6);
miaotwilio 5:ded8fe5991a2 21
miaotwilio 5:ded8fe5991a2 22 static const int VEHICLE_DATA_SAMPLING_PERIOD_MS = 50;
miaotwilio 5:ded8fe5991a2 23 static Ticker vehicleDataSamplingTicker;
miaotwilio 5:ded8fe5991a2 24 static TripDataReader* pTripDataReader = NULL;
miaotwilio 5:ded8fe5991a2 25 static void vehicleDataSamplingCallback();
miaotwilio 5:ded8fe5991a2 26
miaotwilio 5:ded8fe5991a2 27 static const int VEHICLE_DATA_REPORTING_PERIOD_MS = 3000;
miaotwilio 0:b32fa0c757d7 28
miaotwilio 0:b32fa0c757d7 29 static bool exitCmd = false;
miaotwilio 0:b32fa0c757d7 30
miaotwilio 5:ded8fe5991a2 31 static void sendVehicleData(const MTSCellularManager::GPSStatus& gpsStatus,
miaotwilio 5:ded8fe5991a2 32 const TripDataReader::TripData& tripData);
miaotwilio 5:ded8fe5991a2 33
miaotwilio 5:ded8fe5991a2 34 //static void test2Handler(MQTT::MessageData& data);
miaotwilio 0:b32fa0c757d7 35
miaotwilio 0:b32fa0c757d7 36 int main() {
miaotwilio 0:b32fa0c757d7 37 // Disable the battery charger unless a battery is attached.
miaotwilio 0:b32fa0c757d7 38 bc_nce = 1;
miaotwilio 1:5a896191c3c4 39
miaotwilio 1:5a896191c3c4 40 ledMQTTYield = 1;
miaotwilio 1:5a896191c3c4 41 ledGPS = 1;
miaotwilio 0:b32fa0c757d7 42
miaotwilio 0:b32fa0c757d7 43 // Change the baud rate of the debug port from the default 9600 to 115200.
miaotwilio 0:b32fa0c757d7 44 Serial debug(USBTX, USBRX);
miaotwilio 0:b32fa0c757d7 45 debug.baud(115200);
miaotwilio 0:b32fa0c757d7 46
miaotwilio 0:b32fa0c757d7 47 //Sets the log level to INFO, higher log levels produce more log output.
miaotwilio 0:b32fa0c757d7 48 //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
miaotwilio 0:b32fa0c757d7 49 mts::MTSLog::setLogLevel(mts::MTSLog::TRACE_LEVEL);
miaotwilio 0:b32fa0c757d7 50
miaotwilio 1:5a896191c3c4 51 logInfo("Program started");
miaotwilio 1:5a896191c3c4 52
miaotwilio 1:5a896191c3c4 53 logInfo("Initializing cellular");
miaotwilio 0:b32fa0c757d7 54 MTSCellularManager cellularManager("wireless.twilio.com");
miaotwilio 0:b32fa0c757d7 55 if (! cellularManager.init()) {
miaotwilio 0:b32fa0c757d7 56 while (true) {
miaotwilio 0:b32fa0c757d7 57 logError("failed to initialize cellular radio");
miaotwilio 0:b32fa0c757d7 58 wait(1);
miaotwilio 0:b32fa0c757d7 59 }
miaotwilio 0:b32fa0c757d7 60 }
miaotwilio 0:b32fa0c757d7 61
miaotwilio 1:5a896191c3c4 62 {
miaotwilio 1:5a896191c3c4 63 logInfo("Initializing GPS");
miaotwilio 1:5a896191c3c4 64 cellularManager.enableGps();
miaotwilio 1:5a896191c3c4 65 logInfo("GPS Initialized");
miaotwilio 1:5a896191c3c4 66 }
miaotwilio 1:5a896191c3c4 67
miaotwilio 5:ded8fe5991a2 68 TripDataReader tripDataReader(obd, ledOBD);
miaotwilio 5:ded8fe5991a2 69 pTripDataReader = &tripDataReader;
miaotwilio 5:ded8fe5991a2 70 while (true) {
miaotwilio 5:ded8fe5991a2 71 logInfo("Initializing OBD");
miaotwilio 5:ded8fe5991a2 72 int r = tripDataReader.init();
miaotwilio 5:ded8fe5991a2 73 logInfo("OBD Initialization result: %d", r);
miaotwilio 5:ded8fe5991a2 74 if (0 == r) {
miaotwilio 5:ded8fe5991a2 75 logInfo("Initializing OBD sampling ticker");
miaotwilio 5:ded8fe5991a2 76 vehicleDataSamplingTicker.attach(
miaotwilio 5:ded8fe5991a2 77 &vehicleDataSamplingCallback,
miaotwilio 5:ded8fe5991a2 78 VEHICLE_DATA_SAMPLING_PERIOD_MS / 1000.);
miaotwilio 5:ded8fe5991a2 79 logInfo("OBD sampling ticker initialized");
miaotwilio 5:ded8fe5991a2 80 break;
miaotwilio 5:ded8fe5991a2 81 }
miaotwilio 5:ded8fe5991a2 82 wait_ms(100);
miaotwilio 5:ded8fe5991a2 83 }
miaotwilio 5:ded8fe5991a2 84
miaotwilio 1:5a896191c3c4 85 logInfo("Initializing CyaSSL");
miaotwilio 0:b32fa0c757d7 86 CyaSSL_Init();
miaotwilio 0:b32fa0c757d7 87
miaotwilio 1:5a896191c3c4 88 while (!exitCmd) {
miaotwilio 5:ded8fe5991a2 89 wait_ms(VEHICLE_DATA_REPORTING_PERIOD_MS);
miaotwilio 5:ded8fe5991a2 90 TripDataReader::TripData tripData = tripDataReader.getTripData();
miaotwilio 5:ded8fe5991a2 91 tripDataReader.resetAverageWindow();
miaotwilio 1:5a896191c3c4 92 MTSCellularManager::GPSStatus gpsStatus = cellularManager.gpsPollStatus();
miaotwilio 1:5a896191c3c4 93 if (gpsStatus.success) {
miaotwilio 1:5a896191c3c4 94 ledGPS = 0;
miaotwilio 5:ded8fe5991a2 95 sendVehicleData(gpsStatus, tripData);
miaotwilio 1:5a896191c3c4 96 } else {
miaotwilio 1:5a896191c3c4 97 ledGPS = 1;
miaotwilio 1:5a896191c3c4 98 }
miaotwilio 1:5a896191c3c4 99 }
miaotwilio 1:5a896191c3c4 100
miaotwilio 1:5a896191c3c4 101 logInfo("Cleaning up CyaSSL");
miaotwilio 1:5a896191c3c4 102 CyaSSL_Cleanup();
miaotwilio 1:5a896191c3c4 103
miaotwilio 1:5a896191c3c4 104 logInfo("Shutting down cellular");
miaotwilio 1:5a896191c3c4 105 cellularManager.uninit();
miaotwilio 1:5a896191c3c4 106
miaotwilio 1:5a896191c3c4 107 logInfo("Program finished");
miaotwilio 1:5a896191c3c4 108 wait(1E12);
miaotwilio 1:5a896191c3c4 109 return 0;
miaotwilio 1:5a896191c3c4 110 }
miaotwilio 1:5a896191c3c4 111
miaotwilio 5:ded8fe5991a2 112 static void vehicleDataSamplingCallback() {
miaotwilio 5:ded8fe5991a2 113 pTripDataReader->sample();
miaotwilio 5:ded8fe5991a2 114 }
miaotwilio 5:ded8fe5991a2 115
miaotwilio 5:ded8fe5991a2 116 static void sendVehicleData(const MTSCellularManager::GPSStatus& gpsStatus,
miaotwilio 5:ded8fe5991a2 117 const TripDataReader::TripData& tripData) {
miaotwilio 1:5a896191c3c4 118 ledMQTTYield = 0;
miaotwilio 1:5a896191c3c4 119
miaotwilio 1:5a896191c3c4 120 logInfo("Connecting MQTT Client");
miaotwilio 0:b32fa0c757d7 121 TlsMQTTClient client = TlsMQTTClient();
miaotwilio 0:b32fa0c757d7 122 MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
miaotwilio 2:d4dcf1ebaa99 123 data.clientID.cstring = VEHICLE_ID;
miaotwilio 2:d4dcf1ebaa99 124 data.username.cstring = VEHICLE_KEY;
miaotwilio 2:d4dcf1ebaa99 125 data.password.cstring = VEHICLE_SECRET;
miaotwilio 3:0a48c984e15b 126 int result = client.connect(MQTT_GATEWAY_HOST, MQTT_GATEWAY_PORT, MQTT_GATEWAY_PROD_ROOT_CA_PEM, data);
miaotwilio 3:0a48c984e15b 127 if (MQTT::SUCCESS == result) {
miaotwilio 0:b32fa0c757d7 128 MQTT::Message message;
miaotwilio 0:b32fa0c757d7 129 char buf[512];
miaotwilio 0:b32fa0c757d7 130
miaotwilio 1:5a896191c3c4 131 logInfo("MQTT connected");
miaotwilio 0:b32fa0c757d7 132
miaotwilio 1:5a896191c3c4 133 sprintf(buf, "{"
miaotwilio 5:ded8fe5991a2 134 "\"driver_id\": %s,"
miaotwilio 5:ded8fe5991a2 135 "\"runtime\": %d,"
miaotwilio 5:ded8fe5991a2 136 "\"miles\": %d,"
miaotwilio 1:5a896191c3c4 137 "\"speed\": %f,"
miaotwilio 5:ded8fe5991a2 138 "\"minT\": %f,"
miaotwilio 5:ded8fe5991a2 139 "\"maxT\": %f,"
miaotwilio 5:ded8fe5991a2 140 "\"avgT\": %f,"
miaotwilio 5:ded8fe5991a2 141 "\"fuel\": %d,"
miaotwilio 5:ded8fe5991a2 142 "\"brake\": %d,"
miaotwilio 1:5a896191c3c4 143 "\"lat\": %lf,"
miaotwilio 1:5a896191c3c4 144 "\"lon\": %lf"
miaotwilio 1:5a896191c3c4 145 "}",
miaotwilio 5:ded8fe5991a2 146 VEHICLE_ID,
miaotwilio 5:ded8fe5991a2 147 tripData.runtime,
miaotwilio 5:ded8fe5991a2 148 tripData.distance,
miaotwilio 5:ded8fe5991a2 149 tripData.averageSpeed,
miaotwilio 5:ded8fe5991a2 150 tripData.minimumThrottle,
miaotwilio 5:ded8fe5991a2 151 tripData.maximumThrottle,
miaotwilio 5:ded8fe5991a2 152 tripData.averageThrottle,
miaotwilio 5:ded8fe5991a2 153 tripData.fuel,
miaotwilio 5:ded8fe5991a2 154 tripData.hardBrakeCount,
miaotwilio 1:5a896191c3c4 155 gpsStatus.latitudeVal,
miaotwilio 1:5a896191c3c4 156 gpsStatus.longitudeVal);
miaotwilio 0:b32fa0c757d7 157 message.qos = MQTT::QOS1;
miaotwilio 0:b32fa0c757d7 158 message.payload = (void*)buf;
miaotwilio 0:b32fa0c757d7 159 message.payloadlen = strlen(buf) + 1;
miaotwilio 1:5a896191c3c4 160 logInfo("MQTT message publishing buf: %s", buf);
miaotwilio 2:d4dcf1ebaa99 161 int rc = client.publish("sync/lists/vehicle-" VEHICLE_ID "-data", message);
miaotwilio 1:5a896191c3c4 162 logInfo("MQTT message publish result: %d", rc);
miaotwilio 0:b32fa0c757d7 163
miaotwilio 1:5a896191c3c4 164 logInfo("MQTT disconnecting");
miaotwilio 0:b32fa0c757d7 165 client.disconnect();
miaotwilio 3:0a48c984e15b 166 } else {
miaotwilio 3:0a48c984e15b 167 logError("MQTT connection failed %d", result);
miaotwilio 0:b32fa0c757d7 168 }
miaotwilio 1:5a896191c3c4 169 ledMQTTYield = 1;
miaotwilio 1:5a896191c3c4 170 }
miaotwilio 0:b32fa0c757d7 171
miaotwilio 1:5a896191c3c4 172 /*
miaotwilio 1:5a896191c3c4 173 static void subscribeToTest2() {
miaotwilio 1:5a896191c3c4 174 rc = client.subscribe("sync/lists/test2", MQTT::QOS1, test2Handler);
miaotwilio 1:5a896191c3c4 175 logInfo("MQTT subscription result: %d", rc);
miaotwilio 0:b32fa0c757d7 176 }
miaotwilio 0:b32fa0c757d7 177
miaotwilio 0:b32fa0c757d7 178 static void test2Handler(MQTT::MessageData& data) {
miaotwilio 0:b32fa0c757d7 179 static const size_t MAX_DISPLAY_MESSAGE_SIZE = 30;
miaotwilio 0:b32fa0c757d7 180 char buf[MAX_DISPLAY_MESSAGE_SIZE + 1];
miaotwilio 0:b32fa0c757d7 181 if (data.message.payloadlen <= MAX_DISPLAY_MESSAGE_SIZE) {
miaotwilio 0:b32fa0c757d7 182 strncpy(buf, (char*)data.message.payload, data.message.payloadlen);
miaotwilio 0:b32fa0c757d7 183 buf[data.message.payloadlen] = '\0';
miaotwilio 0:b32fa0c757d7 184 } else {
miaotwilio 0:b32fa0c757d7 185 strncpy(buf, (char*)data.message.payload, MAX_DISPLAY_MESSAGE_SIZE - 3);
miaotwilio 0:b32fa0c757d7 186 buf[MAX_DISPLAY_MESSAGE_SIZE-3] = '.';
miaotwilio 0:b32fa0c757d7 187 buf[MAX_DISPLAY_MESSAGE_SIZE-2] = '.';
miaotwilio 0:b32fa0c757d7 188 buf[MAX_DISPLAY_MESSAGE_SIZE-1] = '.';
miaotwilio 0:b32fa0c757d7 189 buf[MAX_DISPLAY_MESSAGE_SIZE] = '\0';
miaotwilio 0:b32fa0c757d7 190 }
miaotwilio 0:b32fa0c757d7 191 logDebug("topic %s payload received len %d data %s", data.topicName.lenstring.data, data.message.payloadlen, buf);
miaotwilio 0:b32fa0c757d7 192
miaotwilio 0:b32fa0c757d7 193 // sync client can send binary data using payload format:
miaotwilio 0:b32fa0c757d7 194 // {
miaotwilio 0:b32fa0c757d7 195 // "payload": "ZXhpdA==", # base64 encoded "exit"
miaotwilio 0:b32fa0c757d7 196 // "_iot_meta": {
miaotwilio 0:b32fa0c757d7 197 // "payload_encoding": "base64",
miaotwilio 0:b32fa0c757d7 198 // "payload_type": "application/octet-stream",
miaotwilio 0:b32fa0c757d7 199 // }
miaotwilio 0:b32fa0c757d7 200 // }
miaotwilio 0:b32fa0c757d7 201 if (0 == strncmp((char*)data.message.payload, "exit", data.message.payloadlen)) {
miaotwilio 0:b32fa0c757d7 202 exitCmd = true;
miaotwilio 0:b32fa0c757d7 203 }
miaotwilio 1:5a896191c3c4 204 }*/