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