Local copy

Dependencies:   C12832_lcd ConfigFile EthernetInterface LM75B MMA7660 MQTTPacket mbed-rtos mbed

Fork of IBMIoTClientExampleForLPC1768 by Sam Danbury

Files at this revision

API Documentation at this revision

Comitter:
samdanbury
Date:
Mon Jun 23 13:37:46 2014 +0000
Child:
1:dd948ce80918
Child:
2:25ddff75a8c7
Commit message:
initial commit

Changed in this revision

C12832_lcd.lib Show annotated file Show diff for this revision Revisions of this file
EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
LM75B.lib Show annotated file Show diff for this revision Revisions of this file
MMA7660.lib Show annotated file Show diff for this revision Revisions of this file
MQTTPacket.lib Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
src/QuickstartClient.cpp Show annotated file Show diff for this revision Revisions of this file
src/QuickstartClient.h Show annotated file Show diff for this revision Revisions of this file
src/QuickstartMessage.cpp Show annotated file Show diff for this revision Revisions of this file
src/QuickstartMessage.h Show annotated file Show diff for this revision Revisions of this file
src/main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C12832_lcd.lib	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,1 @@
+https://mbed.org/users/dreschpe/code/C12832_lcd/#8f86576007d6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetInterface.lib	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/EthernetInterface/#e6b79f0ccd95
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LM75B.lib	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/chris/code/LM75B/#6a70c9303bbe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA7660.lib	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Sissors/code/MMA7660/#36a163511e34
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MQTTPacket.lib	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/teams/mqtt/code/MQTTPacket/#68a06bea5429
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#5dfe422a963d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/QuickstartClient.cpp	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,136 @@
+/*******************************************************************************
+* Copyright (c) 2014 IBM Corporation and other Contributors.
+*
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors: Sam Danbury
+* IBM - Initial Contribution
+*******************************************************************************/
+
+#include "QuickstartClient.h"
+
+QuickstartClient::QuickstartClient(string mac) {
+    connected = false;
+    macAddress = mac;
+    
+    //Generate topic string from mac address
+    memcpy(topic, "iot-1/d/", 8);
+    memcpy(topic + 8, macAddress.c_str(), macAddress.size());
+    memcpy(topic + 8 + macAddress.size(), "/evt/mbed-quickstart/json", 25);
+    topic[8 + macAddress.size() + 25] = '\0';
+    
+    tryMqttConnect();
+}
+
+int QuickstartClient::reconnectDelay(int i) {
+    if (i < 10) {
+        return 3; //First 10 attempts try within 3 seconds
+    } else if (i < 20) {
+        return 60; //Next 10 attempts retry after every 1 minute
+    } else {
+        return 600; //After 20 attempts, retry every 10 minutes
+    }
+}
+
+void QuickstartClient::tryMqttConnect() {
+    int retryAttempt = 0;
+    
+    //Reinstantiate TCP socket connection object
+    mysock = TCPSocketConnection();
+    
+    while (connected == false) {
+        lcd.cls();
+        lcd.locate(0,0);
+        lcd.printf("Trying to connect...");
+        
+        //Based on number of connection attempts, determine timeout
+        int connDelayTimeout = reconnectDelay(++retryAttempt);
+        
+        //Attempt to reconnect
+        connect();
+        
+        //If connection was not established, continue retry
+        if (connected == false) {
+            wait(connDelayTimeout);
+        } else {
+            break;
+        }
+    }
+}
+
+void QuickstartClient::connect() {
+    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
+    int  rc = 0;
+    int  len = 0;
+    char buf[200];
+    int  buflen = sizeof(buf);
+    
+    //Connect to TCP socket
+    mysock.connect(IBM_IOT_BROKER, IBM_IOT_PORT);
+    
+    //Construct clientId from mac address
+    char clientId[23];
+    memcpy(clientId, "quickstart:", 11);
+    memcpy(clientId + 11, macAddress.c_str(), macAddress.size() + 1);
+    
+    //Set MQTT connect options
+    data.clientID.cstring = clientId;
+    data.keepAliveInterval = 20;
+    data.cleansession = 1;
+    data.MQTTVersion = 3;
+    
+    //Attempt MQTT connect
+    len = MQTTSerialize_connect(buf, buflen, &data);
+    rc = 0;
+    while (rc < len) {
+        int rc1 = mysock.send(buf, len);
+        if (rc1 == -1) {
+            connected = false;
+            break;
+        } else {
+            rc += rc1;
+        }
+    }
+    if (rc == len) {
+        connected = true;
+    }
+}
+
+void QuickstartClient::publish(string thePayload) {
+    int  rc = 0;
+    int  len = 0;
+    char buf[250];
+    int  buflen = sizeof(buf);
+    
+    MQTTString topicString = MQTTString_initializer;
+    
+    topicString.cstring = topic;
+    
+    //Convert payload from string to char array
+    char* payload = new char [thePayload.length()+1];
+    std::strcpy (payload, thePayload.c_str());
+    int payloadlen = strlen(payload);
+    
+    //Attempt MQTT publish
+    len = MQTTSerialize_publish(buf, buflen, 0, 0, 0, 0, topicString, payload, payloadlen);
+    rc = 0;
+    while (rc < len) {
+        int rc1 = mysock.send(buf, len);
+        if (rc1 == -1) {
+            //If return code from MQTT publish is -1, attempt reconnect
+            connected = false;
+            tryMqttConnect();
+            break;
+        } else {
+            rc += rc1;
+        }
+    }
+    wait(0.2);
+    
+    if (payload) {
+        delete payload;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/QuickstartClient.h	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,44 @@
+/*******************************************************************************
+* Copyright (c) 2014 IBM Corporation and other Contributors.
+*
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors: Sam Danbury
+* IBM - Initial Contribution
+*******************************************************************************/
+
+#include "MQTTPacket.h"
+#include "rtos.h"
+#include "EthernetInterface.h"
+#include "C12832_lcd.h"
+
+#include <iostream>
+#include <string>
+#include <vector>
+#include <map>
+#include <sstream>
+#include <algorithm>
+
+#define IBM_IOT_BROKER "m.qs.internetofthings.ibmcloud.com"
+#define IBM_IOT_PORT 1883
+
+using namespace std;
+
+class QuickstartClient {
+    public:
+        bool connected;
+        C12832_LCD lcd;
+        TCPSocketConnection mysock;
+        string macAddress;
+        char topic[55];
+        int reconnectDelay(int attempt);
+                
+        QuickstartClient(string mac);
+        void tryMqttConnect();
+        void connect();
+        void publish(string payload);
+        bool getConnection();
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/QuickstartMessage.cpp	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,62 @@
+/*******************************************************************************
+* Copyright (c) 2014 IBM Corporation and other Contributors.
+*
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors: Sam Danbury
+* IBM - Initial Contribution
+*******************************************************************************/
+
+#include "QuickstartMessage.h"
+
+QuickstartMessage::QuickstartMessage() {
+    
+}
+
+void QuickstartMessage::add(string key, string value) {
+    //Add datapoint to map of datapoints
+    data[key] = value;
+}
+
+void QuickstartMessage::add(string key, float value) {
+    char temp[7];
+    
+    //Format value to an accuracy of four decimal places
+    sprintf(temp, "%0.4f", value);
+    
+    //Add datapoint to map of datapoints
+    data[key] = temp;
+}
+
+string QuickstartMessage::convertToJson() {
+    string message;
+    
+    //Construct json message using map of datapoints
+    string data_points = "\"myName\": \"IoT mbed\",";
+    map<string, string>::iterator itr;
+    for (itr=data.begin();itr!=data.end();itr++) {
+        if (itr!=data.begin()) {
+            data_points+=",";
+        }
+        
+        float f;
+        char* cstr = new char[(itr->second).length()+1];
+        strcpy(cstr, (itr->second).c_str());
+        
+        int validNumber = sscanf(cstr, "%f", &f);
+        if (validNumber) {
+            data_points+="\"" + itr->first + "\":" + itr->second;
+        } else {
+            data_points+="\"" + itr->first + "\":\"" + itr->second + "\"";
+        }
+        
+        if (cstr) {
+            delete[] cstr;
+        }
+    }
+    message = "{\"d\":{" + data_points + "}}";
+    return message;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/QuickstartMessage.h	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* Copyright (c) 2014 IBM Corporation and other Contributors.
+*
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors: Sam Danbury
+* IBM - Initial Contribution
+*******************************************************************************/
+
+#include <string>
+#include <vector>
+#include <map>
+#include <stdio.h>
+
+using namespace std;
+
+typedef map<string, string> MbedSensorsDataHolder;
+
+class QuickstartMessage {
+    public:
+        MbedSensorsDataHolder data;
+    
+        QuickstartMessage();
+        void add(string key, string value);
+        void add(string key, float value);
+        string convertToJson();
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main.cpp	Mon Jun 23 13:37:46 2014 +0000
@@ -0,0 +1,129 @@
+/*******************************************************************************
+* Copyright (c) 2014 IBM Corporation and other Contributors.
+*
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors: Sam Danbury
+* IBM - Initial Contribution
+*******************************************************************************/
+
+#include "stdio.h"
+#include "mbed.h"
+#include "rtos.h"
+#include "EthernetInterface.h"
+#include "C12832_lcd.h"
+#include "LM75B.h"
+#include "MMA7660.h"
+#include "C12832_lcd.h"
+#include "QuickstartClient.h"
+#include "QuickstartMessage.h"
+
+#include <string>
+
+using namespace std;
+
+//LCD
+C12832_LCD lcd;
+
+//LED
+DigitalOut led1(LED1);
+
+//Accelerometer
+MMA7660 MMA(p28, p27);
+
+//Temperature sensor
+LM75B tmp(p28, p27);
+
+//Joystick
+BusIn Down(p12);
+BusIn Left(p13);
+BusOut Click(p14);
+BusIn Up(p15);
+BusIn Right(p16);
+string joystickPos;
+void joystickThread(void const *args);
+
+//Potentiometer
+AnalogIn ain1(p19);
+AnalogIn ain2(p20);
+float pot1;
+float pot2;
+
+int main()
+{
+    //Connect to the network
+    EthernetInterface eth;
+    eth.init();
+    eth.connect();
+    
+    //Obtain mac address of mbed
+    string mac = eth.getMACAddress();
+    
+    //Remove colons from mac address
+    mac.erase(remove(mac.begin(), mac.end(), ':'), mac.end());
+    
+    //Start thread to read data from joystick
+    Thread jThd(joystickThread);
+    joystickPos = "CENTRE";
+    
+    QuickstartClient* c = new QuickstartClient(mac);
+    
+    while(1) 
+    {
+        //Initialize lcd
+        lcd.cls();
+        lcd.locate(0,0);
+        
+        lcd.printf("Mac address: %s\n", mac);
+        
+        //Flash led to show message has been sent successfully
+        led1 = 1;
+        
+        //Construct quickstart message with desired datapoints
+        QuickstartMessage* m = new QuickstartMessage();
+        m->add("accelX", MMA.x());
+        m->add("accelY", MMA.y());
+        m->add("accelZ", MMA.z());
+        m->add("temp", tmp.read());
+        m->add("joystick", joystickPos);
+        
+        pot1 = ain1;
+        pot2 = ain2;
+        m->add("potentiometer1", pot1);
+        m->add("potentiometer2", pot2);
+        
+        //Message is converted from datapoints into json format and then published
+        c->publish(m->convertToJson());
+        
+        if (m) {
+            delete m;
+        }
+        
+        led1 = 0;
+        
+        //Message published every second
+        wait(1);
+    }
+    
+    eth.disconnect();
+}
+
+void joystickThread(void const *args) {
+    while (1) {
+        if (Down)
+            joystickPos = "DOWN";
+        else if (Left)
+            joystickPos = "LEFT";
+        else if (Click)
+            joystickPos = "CLICK";
+        else if (Up)
+            joystickPos = "UP";
+        else if (Right)
+            joystickPos = "RIGHT";
+        else
+            joystickPos = "CENTRE";
+    }
+}
\ No newline at end of file