Connect through Wifi to IBM MQTT cloud https://quickstart.internetofthings.ibmcloud.com

Dependencies:   MQTT NetworkSocketAPI X_NUCLEO_IDW01M1v2 X_NUCLEO_IKS01A1 mbed NDefLib X_NUCLEO_NFC01A1

Fork of IDW01M1_Cloud_IBM by ST Expansion SW Team

To start the demo the following expansion boards are required

X_NUCLEO_IDW01M1v2, X_NUCLEO_IKS01A1, X_NUCLEO_NFC01A1

After having mounted the board stack on the Nucleo board the below steps should be followed:

  • Program in the application source code you local WiFi SSID and password and flash the binary. Make sure the Wifi network has visible SSID.
  • Reset the Nucleo board and after few seconds the Nucleo green led will be on (it means the Nucleo is connected to the local Wifi and to the IBM cloud server)
  • Read the NFC tag with an Android device and the browser will be automatically opened and directed to the specific brocker IBM demo page where the environmental values are displayed in form of a x-y graph. The values are updated every few seconds. On the Hyperterminal is possible to see the values sent to the IBM cloud server and the board mac address to be entered on the IBM quickstart web page if a manual connection is needed (eg. to connect from a PC browser).
Revision:
23:43f9e34781f2
Parent:
22:d278e4bb5ded
Child:
24:a59eb8bdc431
--- a/main.cpp	Wed Oct 19 09:46:27 2016 +0000
+++ b/main.cpp	Wed Oct 26 15:28:35 2016 +0000
@@ -21,6 +21,9 @@
 #include "MQTTWiFi.h"
 #include <ctype.h>
 #include "x_nucleo_iks01a1.h"
+#include "X_NUCLEO_NFC01A1.h"
+#include "NDefLib/NDefNfcTag.h"
+#include "NDefLib/RecordType/RecordURI.h"
 
 //------------------------------------
 // Hyperterminal configuration
@@ -31,23 +34,27 @@
 SpwfSAInterface spwf(D8, D2, false);
 bool quickstartMode = true;    
 
-#define ORG_QUICKSTART  // comment to connect to play.internetofthings.ibmcloud.com
+#define ORG_QUICKSTART           // comment to connect to play.internetofthings.ibmcloud.com
+//#define SUBSCRIBE              // uncomment to subscribe to broker msgs (not to be used with IBM broker) 
+#define X_NUCLEO_NFC01A1_PRESENT // uncomment to add NFC support
     
 #define MQTT_MAX_PACKET_SIZE 250   
 #define MQTT_MAX_PAYLOAD_SIZE 300 
 
  // Configuration values needed to connect to IBM IoT Cloud
+#define BROKER_URL ".messaging.internetofthings.ibmcloud.com";     
 #ifdef ORG_QUICKSTART
 #define ORG "quickstart"     // connect to quickstart.internetofthings.ibmcloud.com/ For a registered connection, replace with your org 
 #define ID ""
 #define AUTH_TOKEN ""
 #define DEFAULT_TYPE_NAME "iotsample-mbed-Nucleo"
-#else
+#else   // not def ORG_QUICKSTART
 #define ORG "play"             // connect to play.internetofthings.ibmcloud.com/ For a registered connection, replace with your org
-#define ID "testnucleo2"       // For a registered connection, replace with your id
-#define AUTH_TOKEN "centrallab"// For a registered connection, replace with your auth-token
+#define ID ""       // For a registered connection, replace with your id
+#define AUTH_TOKEN ""// For a registered connection, replace with your auth-token
 #define DEFAULT_TYPE_NAME "sensor"
 #endif
+#define TOPIC  "iot-2/evt/status/fmt/json" 
 
 #define TYPE DEFAULT_TYPE_NAME       // For a registered connection, replace with your type
 #define MQTT_PORT 1883
@@ -66,50 +73,71 @@
 char type[30] = TYPE;
 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode
 bool netConnecting = false;
-//int connectTimeout = 1000;
-int connectTimeout = 10;
+int connectTimeout = 1000;
 bool mqttConnecting = false;
 bool netConnected = false;
 bool connected = false;
 int retryAttempt = 0;
+char subscription_url[MQTT_MAX_PAYLOAD_SIZE];
 
 PressureSensor *pressure_sensor;
 HumiditySensor *humidity_sensor;
 TempSensor *temp_sensor1;
 
+MQTT::Message message;
+MQTTString TopicName={TOPIC};
+MQTT::MessageData MsgData(TopicName, message);
+
+void subscribe_cb(MQTT::MessageData & msgMQTT) {
+    char msg[MQTT_MAX_PAYLOAD_SIZE];
+    msg[0]='\0';
+    strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen);
+    printf ("--->>> subscribe_cb msg: %s\n\r", msg);
+}
+
+int subscribe(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack)
+{
+    char* pubTopic = TOPIC;    
+    return client->subscribe(pubTopic, MQTT::QOS1, subscribe_cb);
+}
 
 int connect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack)
-{   
-    const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com";
+{ 
+    const char* iot_ibm = BROKER_URL; 
+
     
     char hostname[strlen(org) + strlen(iot_ibm) + 1];
     sprintf(hostname, "%s%s", org, iot_ibm);
     SpwfSAInterface& WiFi = ipstack->getWiFi();
     ip_addr = WiFi.get_ip_address();
-    printf ("ID: %s\n\r",id);
     // Construct clientId - d:org:type:id
-    char clientId[strlen(org) + strlen(type) + strlen(id) + 5];
-    sprintf(clientId, "d:%s:%s:%s", org, type, id);    
+    char clientId[strlen(org) + strlen(type) + strlen(id) + 5];  
+    sprintf(clientId, "d:%s:%s:%s", org, type, id);  
+    sprintf(subscription_url, "%s.%s/#/device/%s/sensor/", org, "internetofthings.ibmcloud.com",id);
+
     // Network debug statements 
     LOG("=====================================\n\r");
     LOG("Connecting WiFi.\n\r");
-    LOG("IP ADDRESS: %s\n\r", WiFi.get_ip_address());
-    LOG("MAC ADDRESS: %s\n\r", WiFi.get_mac_address());
-    LOG("Server Hostname: %s\n\r", hostname);
+    LOG("Nucleo IP ADDRESS: %s\n\r", WiFi.get_ip_address());
+    LOG("Nucleo MAC ADDRESS: %s\n\r", WiFi.get_mac_address());
+    LOG("Server Hostname: %s port: %d\n\r", hostname, IBM_IOT_PORT);
 //    for(int i = 0; clientId[i]; i++){
 //       clientId[i] = tolower(clientId[i]);
 //    }    
-    LOG("Client ID: %s\n\r", clientId);
+    LOG("Client ID: %s id: %s\n\r", clientId, id);
+    LOG("Topic: %s\n\r",TOPIC);
+    LOG("Subscription URL: %s\n\r", subscription_url);
     LOG("=====================================\n\r");
     
     netConnecting = true;
     ipstack->open(&ipstack->getWiFi());
-    int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout);
+    int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout);    
     if (rc != 0)
     {
         WARN("IP Stack connect returned: %d\n", rc);    
         return rc;
     }
+    printf ("--->TCP Connected\n\r");
     netConnected = true;
     netConnecting = false;
 
@@ -124,11 +152,14 @@
     {        
         data.username.cstring = "use-token-auth";
         data.password.cstring = auth_token;
-    }    
+    }   
     if ((rc = client->connect(data)) == 0) 
     {       
         connected = true;
-        printf ("--->Connected\n\r");
+        printf ("--->MQTT Connected\n\r");
+#ifdef SUBSCRIBE
+        if (!subscribe(client, ipstack)) printf ("--->>>MQTT subscribed to: %s\n\r",TOPIC);
+#endif           
     }
     else {
         WARN("MQTT connect returned %d\n", rc);        
@@ -152,15 +183,14 @@
     while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED) 
     {    
         if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) {
-            printf ("File: %s, Line: %d\n\r",__FILE__,__LINE__);        
+            printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc);        
             return; // don't reattempt to connect if credentials are wrong
-        }          
+        } 
         int timeout = getConnTimeout(++retryAttempt);
         WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout);
         
         // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed
-        //  or maybe just add the proper members to do this disconnect and call attemptConnect(...)
-        
+        //  or maybe just add the proper members to do this disconnect and call attemptConnect(...)        
         // this works - reset the system when the retry count gets to a threshold
         if (retryAttempt == 5)
             NVIC_SystemReset();
@@ -172,7 +202,7 @@
 int publish(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack)
 {
     MQTT::Message message;
-    char* pubTopic = "iot-2/evt/status/fmt/json";
+    char* pubTopic = TOPIC;
             
     char buf[MQTT_MAX_PAYLOAD_SIZE];
     float temp, press, hum;
@@ -188,7 +218,7 @@
     message.payload = (void*)buf;
     message.payloadlen = strlen(buf);
     
-    LOG("Publishing %s\n", buf);
+    LOG("Publishing %s\n\r", buf);
     return client->publish(pubTopic, message);
 } 
     
@@ -202,8 +232,7 @@
     DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL);
     i2c->frequency(400000);    
     
-    X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(i2c);
-    
+    X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(i2c);   
     pressure_sensor = mems_expansion_board->pt_sensor;
     temp_sensor1 = mems_expansion_board->ht_sensor;  
     humidity_sensor = mems_expansion_board->ht_sensor;  
@@ -234,14 +263,36 @@
       while (true)
       wait(1.0); // Permanent failures - don't retry
    }
+#ifdef X_NUCLEO_NFC01A1_PRESENT      
+   // program NFC with broker URL        
+   X_NUCLEO_NFC01A1 *nfcNucleo = X_NUCLEO_NFC01A1::Instance(*i2c, NULL, X_NUCLEO_NFC01A1::DEFAULT_GPO_PIN, X_NUCLEO_NFC01A1::DEFAULT_RF_DISABLE_PIN, NC,NC,NC);  
+   NDefLib::NDefNfcTag& tag = nfcNucleo->getM24SR().getNDefTag();
+   printf("NFC Init done: !\r\n");
+   //open the i2c session with the nfc chip
+   if(tag.openSession()){
+       //create the NDef message and record
+       NDefLib::Message msg;
+       NDefLib::RecordURI rUri(NDefLib::RecordURI::HTTPS, subscription_url);
+       msg.addRecord(&rUri);
+        //write the tag
+        if(tag.write(msg)){
+            printf("Tag writed \r\n");
+        }
+        //close the i2c session
+        if(!tag.closeSession()){
+            printf("Error Closing the session\r\n");
+        }
+    }else printf("Error open Session\r\n");             
+#endif             
    int count = 0;    
 //    tyeld.start();    
     while (true)
     {
         if (++count == /*100*/2)
         {               // Publish a message every second
-            if (publish(&client, &ipstack) != 0) 
-                attemptConnect(&client, &ipstack);   // if we have lost the connection
+            if (publish(&client, &ipstack) != 0) { 
+                attemptConnect(&client, &ipstack);   // if we have lost the connection                
+            }
             count = 0;
         }        
 //        int start = tyeld.read_ms();