A program for IoT demonstration with mbed, EnOcean and MQTT.

Dependencies:   IBMIoTClientEthernetExample C12832 EthernetInterface MQTT USB400Serial USBHost mbed

Fork of IBMIoTClientEthernetExample by IBM Watson IoT

Revision:
1:1f187285667c
Parent:
0:cae064bcbe5e
Child:
2:d8fddda78c38
--- a/main.cpp	Wed Jul 16 12:03:54 2014 +0000
+++ b/main.cpp	Fri Jul 18 07:57:45 2014 +0000
@@ -20,6 +20,7 @@
 #include "MQTTEthernetIoT.h"
 #include "MQTTClient.h"
 #include "ConfigFile.h"
+#include "Arial12x12.h"
 
 #include <string>
 #include <sstream>
@@ -33,9 +34,10 @@
 
 LocalFileSystem local("local");
 C12832 lcd(p5, p7, p6, p8, p11);
-DigitalOut led1(LED1);
 DigitalOut led2(LED2);
-DigitalOut led3(LED3);
+PwmOut r (p23);
+PwmOut g (p24);
+PwmOut b (p25);
 MMA7660 MMA(p28, p27);
 LM75B sensor(p28, p27);
 DigitalIn Down(p12);
@@ -57,9 +59,10 @@
 //#define AUTHTOKEN "<auth-token>";
 
 C12832 lcd(D11, D13, D12, D7, D10);
-DigitalOut led1(LED_RED);
-DigitalOut led2(LED_GREEN);
-DigitalOut led3(LED_BLUE);
+PwmOut r (D5);
+PwmOut g (D8);
+PwmOut b (D9);
+DigitalOut led2(LED2);
 MMA7660 MMA(PTE25, PTE24);
 LM75B sensor(PTE25, PTE24);
 DigitalIn Up(A2);
@@ -99,8 +102,12 @@
 };
 command getCommand (std::string const& command);
 void messageArrived(MQTT::MessageData& md);
-int interval;
-string getUUID48();
+
+//MQTT
+void connect();
+void attemptConnect();
+int getConnTimeout(int attemptNumber);
+void subscribe();
 
 //Config
 void parseConfig();
@@ -112,6 +119,17 @@
 string auth_token = "";
 string mac = "";
 
+//LCD menu
+bool connected = false;
+bool menuActivated = false;
+int menu = 0;
+void printMenu();
+
+int interval;
+string getUUID48();
+
+MQTTSocket ipstack;
+MQTT::Client<MQTTSocket, Countdown, 250>* client;
 
 void parseConfig() {
     
@@ -132,7 +150,7 @@
         if (cfg.getValue("type", value1, sizeof(value1))) {
             stringstream ss(value1);
             ss >> type;
-        }        
+        }
         if (cfg.getValue("id", value2, sizeof(value2))) {
             stringstream ss(value2);
             ss >> id;
@@ -183,19 +201,28 @@
 
 int main()
 {
-    lcd.locate(0,0);        
-    lcd.printf("ARM IBM IoT\n");
-    lcd.printf("Network connecting\n");
+    //RGB: yellow
+    r = 0;
+    g = 0;
+    b = 1;
+    
+    lcd.cls();
+    lcd.set_font((unsigned char*) Arial12x12);
+    lcd.locate(0,0);
+    lcd.printf("IBM IoT Cloud");
+    lcd.locate(0,16);
+    lcd.printf("Connecting");
     
     //Connect to network
-    MQTTEthernetIoT ipstack = MQTTEthernetIoT();
-    MQTT::Client<MQTTEthernetIoT, Countdown, 250> client = MQTT::Client<MQTTEthernetIoT, Countdown, 250>(ipstack);
+    EthernetInterface eth;
+    eth.init();
+    eth.connect();
     
     //Obtain mac address of mbed
     #ifdef TARGET_K64F
         mac = getUUID48();
     #else
-        mac = ipstack.getMACAddress();
+        mac = eth.getMACAddress();
         
         //Remove colons from mac address
         mac.erase(remove(mac.begin(), mac.end(), ':'), mac.end());
@@ -204,56 +231,12 @@
     //Parse config file if present
     parseConfig();
     
-    //TCP Connect
-    lcd.printf("Attempting TCP connect");
-    string ip = org + ".messaging.internetofthings.ibmcloud.com";
-    
-    char* hostname = new char[ip.length() + 1];
-    strcpy(hostname, ip.c_str());
-    
-    int port = 1883;
-    int rc = ipstack.connect(hostname, port);
-    if (rc != 0) {
-        lcd.printf("TCP connect failed");
-    }
-    
-    //Construct clientId based on config
-    string str = string("d:") + org + ":" + type + ":" + id;
-    char clientId[str.size()];
-    memcpy(clientId, str.c_str(), str.size() + 1);
-    
-    //MQTT Connect
-    lcd.cls();
-    lcd.locate(0,0);
-    lcd.printf("Attempting MQTT Connect\n");
-    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
-    data.MQTTVersion = 3;
-    data.clientID.cstring = clientId;
+    attemptConnect();
     
     if (!quickstartMode) {
-        char* password = new char[auth_token.length() + 1];
-        strcpy(password, auth_token.c_str());
-        
-        data.username.cstring = "use-token-auth";
-        data.password.cstring = password;
+        subscribe();
     }
     
-    if ((rc = client.connect(&data)) != 0)
-        lcd.printf("rc from MQTT connect is %d\n", rc);
-    
-    if (!quickstartMode) {
-        lcd.printf("Attempting MQTT Subscribe\n");
-        char* subTopic = "iot-2/cmd/+/fmt/json";
-        if ((rc = client.subscribe(subTopic, MQTT::QOS1, messageArrived)) != 0)
-            lcd.printf("rc from MQTT subscribe is %d\n", rc);
-    }
-    
-    //Initialize lcd
-    lcd.cls();
-    lcd.locate(0,0);        
-    lcd.printf("http://ibm.biz/iotcloud\n");
-    lcd.printf("Mac address: %s\n", mac);
-    
     //Start thread to read data from joystick
     joystickPos = "CENTRE";
     Thread jThd(joystickThread);
@@ -261,7 +244,6 @@
     interval = 0;
     int i = 0;
 
-
     while(1)
     {
         //Message published every second
@@ -284,27 +266,135 @@
             message.payload = (void*)buf;
             message.payloadlen = strlen(buf);
             
-            if ((rc = client.publish(pubTopic, &message)) != 0)
-                lcd.printf("MQTT publish failed");
+            int rc = 0;
+            if ((rc = client->publish(pubTopic, &message)) != 0) {
+                connected = false;
+                attemptConnect();   
+            }
                 
             i = 0;
-            led1 = !led1;
         }
         
         if (interval == 0) {
-            led2 = 0;   
+            //led2 = 0;   
         } else {
             if (i%(interval)==0) {
-                led2 = !led2;
+                //led2 = !led2;
             }
         }
         
         wait(0.01);
         i++;
-        client.yield(1);
+        client->yield(1);
+    }
+}
+
+void attemptConnect() {
+    int retryAttempt = 0;
+    menuActivated = false;
+    
+    //RGB: yellow
+    r = 0;
+    g = 0;
+    b = 1;
+    
+    lcd.cls();
+    lcd.locate(0,0);
+    lcd.printf("IBM IoT Cloud");
+    lcd.locate(0,16);
+    lcd.printf("Connecting");
+    
+    while (!connected) {
+        
+        int connTimeout = getConnTimeout(++retryAttempt);
+        
+        connect();
+        
+        if (!connected) {
+            wait(connTimeout);
+        } else {
+            break;
+        }
+    }
+}
+
+int getConnTimeout(int attemptNumber) {
+    if (attemptNumber < 10) {
+        return 3; //First 10 attempts try within 3 seconds
+    } else if (attemptNumber < 20) {
+        return 60; //Next 10 attempts retry after every 1 minute
+    } else {
+        return 600; //After 20 attempts, retry every 10 minutes
     }
 }
 
+void connect() {
+    ipstack = MQTTSocket();
+    client = new MQTT::Client<MQTTSocket, Countdown, 250>(ipstack);
+    
+    //TCP Connect
+    string ip = org + ".messaging.internetofthings.ibmcloud.com";
+    
+    char* hostname = new char[ip.length() + 1];
+    strcpy(hostname, ip.c_str());
+    
+    int port = 1883;
+    int rc = ipstack.connect(hostname, port);
+    if (rc != 0) {
+        lcd.printf("TCP connect failed");
+    }
+    
+    //Construct clientId based on config
+    string str = string("d:") + org + ":" + type + ":" + id;
+    char clientId[str.size()];
+    memcpy(clientId, str.c_str(), str.size() + 1);
+    
+    //MQTT Connect
+    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
+    data.MQTTVersion = 3;
+    data.clientID.cstring = clientId;
+    
+    if (!quickstartMode) {
+        char* password = new char[auth_token.length() + 1];
+        strcpy(password, auth_token.c_str());
+        
+        data.username.cstring = "use-token-auth";
+        data.password.cstring = password;
+    }
+    
+    if ((rc = client->connect(&data)) != 0) {
+        lcd.printf("rc from MQTT connect is %d\n", rc);
+    } else {
+        connected = true;
+        
+        //RGB: green
+        r = 1;
+        g = 0;
+        b = 1;
+        
+        lcd.locate(0,0);        
+        lcd.printf("IBM IoT Cloud");
+        lcd.locate(0,16);
+        lcd.printf("Connected");
+        
+        wait(2);
+        
+        lcd.locate(0,0);        
+        lcd.printf("IBM IoT Cloud");
+        lcd.locate(0,16);
+        lcd.printf("Scroll with joystick");
+        
+        menuActivated = true;
+    }
+}
+
+void subscribe() {
+    char* subTopic = "iot-2/cmd/+/fmt/json";
+    int rc = 0;
+    if ((rc = client->subscribe(subTopic, MQTT::QOS1, messageArrived)) != 0)
+        lcd.printf("rc from MQTT subscribe is %d\n", rc);   
+}
+
 void messageArrived(MQTT::MessageData& md) {
     MQTT::Message &message = md.message;
     
@@ -355,18 +445,65 @@
 
 void joystickThread(void const *args) {
     while (true) {
-        if (Down)
+        
+        if (!menuActivated) {
+            menu = 0;
+        }
+        
+        if (Down) {
             joystickPos = "DOWN";
-        else if (Left)
+            if (menu >= 0 && menu < 3) {
+                menu++;
+                printMenu();
+            }
+        } else if (Left) {
             joystickPos = "LEFT";
-        else if (Click)
+        } else if (Click) {
             joystickPos = "CLICK";
-        else if (Up)
+        } else if (Up) {
             joystickPos = "UP";
-        else if (Right)
+            if (menu <= 3 && menu > 0) {
+                menu--;
+                printMenu();
+            }
+        } else if (Right) {
             joystickPos = "RIGHT";
-        else
+        } else {
             joystickPos = "CENTRE";
+        }
+        wait(0.2);
+    }
+}
+
+void printMenu() {
+    if (menuActivated) {
+        lcd.cls();
+        lcd.locate(0,0);
+    
+        switch(menu) {
+            case 0:
+                lcd.printf("IBM IoT Cloud");
+                lcd.locate(0,16);
+                lcd.printf("Scroll with joystick");
+                break;
+            case 1:
+                lcd.printf("Go to:");
+                lcd.locate(0,16);
+                lcd.printf("http://ibm.biz/iotqstart");
+                break;
+            case 2:
+                lcd.printf("Device Identity:");
+                lcd.locate(0,16);
+                lcd.printf("%s", mac);
+                break;
+            case 3:
+                lcd.printf("Status:");
+                lcd.locate(0,16);
+                lcd.printf("Connected");
+                break;
+        }
+    } else {
+        menu = 0;   
     }
 }
 
@@ -375,7 +512,6 @@
     unsigned int UUID_LOC_WORD0 = 0x40048060;
     unsigned int UUID_LOC_WORD1 = 0x4004805C;
  
-    
     // Fetch word 0
     uint32_t Word0 = *(uint32_t *)UUID_LOC_WORD0;