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
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).
main.cpp@22:d278e4bb5ded, 2016-10-19 (annotated)
- Committer:
- mapellil
- Date:
- Wed Oct 19 09:46:27 2016 +0000
- Revision:
- 22:d278e4bb5ded
- Parent:
- 21:78fac4c1b0fa
- Child:
- 23:43f9e34781f2
minor fix
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mridup | 10:c7b62ce013ad | 1 | /* SpwfInterface NetworkSocketAPI Example Program |
mridup | 10:c7b62ce013ad | 2 | * Copyright (c) 2015 ARM Limited |
mridup | 10:c7b62ce013ad | 3 | * |
mridup | 10:c7b62ce013ad | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
mridup | 10:c7b62ce013ad | 5 | * you may not use this file except in compliance with the License. |
mridup | 10:c7b62ce013ad | 6 | * You may obtain a copy of the License at |
mridup | 10:c7b62ce013ad | 7 | * |
mridup | 10:c7b62ce013ad | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
mridup | 10:c7b62ce013ad | 9 | * |
mridup | 10:c7b62ce013ad | 10 | * Unless required by applicable law or agreed to in writing, software |
mridup | 10:c7b62ce013ad | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
mridup | 10:c7b62ce013ad | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
mridup | 10:c7b62ce013ad | 13 | * See the License for the specific language governing permissions and |
mridup | 10:c7b62ce013ad | 14 | * limitations under the License. |
mridup | 10:c7b62ce013ad | 15 | */ |
mridup | 10:c7b62ce013ad | 16 | |
mridup | 0:cbf8bc43bc9e | 17 | #include "mbed.h" |
mapellil | 14:641560b57584 | 18 | #include "SpwfInterface.h" |
mridup | 4:1ed7f173eec5 | 19 | #include "TCPSocket.h" |
fabiombed | 13:0b31131bf711 | 20 | #include "MQTTClient.h" |
mapellil | 14:641560b57584 | 21 | #include "MQTTWiFi.h" |
mapellil | 14:641560b57584 | 22 | #include <ctype.h> |
mapellil | 14:641560b57584 | 23 | #include "x_nucleo_iks01a1.h" |
fabiombed | 13:0b31131bf711 | 24 | |
mridup | 0:cbf8bc43bc9e | 25 | //------------------------------------ |
mridup | 0:cbf8bc43bc9e | 26 | // Hyperterminal configuration |
mridup | 0:cbf8bc43bc9e | 27 | // 9600 bauds, 8-bit data, no parity |
mridup | 0:cbf8bc43bc9e | 28 | //------------------------------------ |
mridup | 8:6df01cb43137 | 29 | Serial pc(SERIAL_TX, SERIAL_RX); |
mridup | 3:dfb8c6c8c31b | 30 | DigitalOut myled(LED1); |
mapellil | 14:641560b57584 | 31 | SpwfSAInterface spwf(D8, D2, false); |
mapellil | 14:641560b57584 | 32 | bool quickstartMode = true; |
mapellil | 17:83d0cd810ed3 | 33 | |
mapellil | 17:83d0cd810ed3 | 34 | #define ORG_QUICKSTART // comment to connect to play.internetofthings.ibmcloud.com |
mapellil | 14:641560b57584 | 35 | |
mapellil | 14:641560b57584 | 36 | #define MQTT_MAX_PACKET_SIZE 250 |
mapellil | 14:641560b57584 | 37 | #define MQTT_MAX_PAYLOAD_SIZE 300 |
mapellil | 17:83d0cd810ed3 | 38 | |
mapellil | 14:641560b57584 | 39 | // Configuration values needed to connect to IBM IoT Cloud |
mapellil | 17:83d0cd810ed3 | 40 | #ifdef ORG_QUICKSTART |
mapellil | 17:83d0cd810ed3 | 41 | #define ORG "quickstart" // connect to quickstart.internetofthings.ibmcloud.com/ For a registered connection, replace with your org |
mapellil | 17:83d0cd810ed3 | 42 | #define ID "" |
mapellil | 17:83d0cd810ed3 | 43 | #define AUTH_TOKEN "" |
mapellil | 21:78fac4c1b0fa | 44 | #define DEFAULT_TYPE_NAME "iotsample-mbed-Nucleo" |
mapellil | 17:83d0cd810ed3 | 45 | #else |
mapellil | 17:83d0cd810ed3 | 46 | #define ORG "play" // connect to play.internetofthings.ibmcloud.com/ For a registered connection, replace with your org |
mapellil | 17:83d0cd810ed3 | 47 | #define ID "testnucleo2" // For a registered connection, replace with your id |
mapellil | 17:83d0cd810ed3 | 48 | #define AUTH_TOKEN "centrallab"// For a registered connection, replace with your auth-token |
mapellil | 17:83d0cd810ed3 | 49 | #define DEFAULT_TYPE_NAME "sensor" |
mapellil | 17:83d0cd810ed3 | 50 | #endif |
mapellil | 17:83d0cd810ed3 | 51 | |
mapellil | 14:641560b57584 | 52 | #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type |
mapellil | 14:641560b57584 | 53 | #define MQTT_PORT 1883 |
mapellil | 14:641560b57584 | 54 | #define MQTT_TLS_PORT 8883 |
mapellil | 14:641560b57584 | 55 | #define IBM_IOT_PORT MQTT_PORT |
mapellil | 16:233b89a6b72f | 56 | // WiFi network credential |
mapellil | 22:d278e4bb5ded | 57 | #define SSID "" // Network must be visible otherwise it can't connect |
mapellil | 22:d278e4bb5ded | 58 | #define PASSW "" |
nikapov | 20:517b559ce91d | 59 | #warning "Wifi SSID & password empty" |
mapellil | 14:641560b57584 | 60 | |
mapellil | 14:641560b57584 | 61 | char id[30] = ID; // mac without colons |
mapellil | 14:641560b57584 | 62 | char org[12] = ORG; |
mapellil | 14:641560b57584 | 63 | int connack_rc = 0; // MQTT connack return code |
mapellil | 14:641560b57584 | 64 | const char* ip_addr = ""; |
mapellil | 14:641560b57584 | 65 | char* host_addr = ""; |
mapellil | 14:641560b57584 | 66 | char type[30] = TYPE; |
mapellil | 14:641560b57584 | 67 | char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode |
mapellil | 14:641560b57584 | 68 | bool netConnecting = false; |
mapellil | 14:641560b57584 | 69 | //int connectTimeout = 1000; |
mapellil | 14:641560b57584 | 70 | int connectTimeout = 10; |
mapellil | 14:641560b57584 | 71 | bool mqttConnecting = false; |
mapellil | 14:641560b57584 | 72 | bool netConnected = false; |
mapellil | 14:641560b57584 | 73 | bool connected = false; |
mapellil | 14:641560b57584 | 74 | int retryAttempt = 0; |
mapellil | 14:641560b57584 | 75 | |
mapellil | 14:641560b57584 | 76 | PressureSensor *pressure_sensor; |
mapellil | 14:641560b57584 | 77 | HumiditySensor *humidity_sensor; |
mapellil | 14:641560b57584 | 78 | TempSensor *temp_sensor1; |
mapellil | 14:641560b57584 | 79 | |
mapellil | 14:641560b57584 | 80 | |
mapellil | 14:641560b57584 | 81 | int connect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) |
mapellil | 14:641560b57584 | 82 | { |
mapellil | 14:641560b57584 | 83 | const char* iot_ibm = ".messaging.internetofthings.ibmcloud.com"; |
mapellil | 14:641560b57584 | 84 | |
mapellil | 14:641560b57584 | 85 | char hostname[strlen(org) + strlen(iot_ibm) + 1]; |
mapellil | 14:641560b57584 | 86 | sprintf(hostname, "%s%s", org, iot_ibm); |
mapellil | 14:641560b57584 | 87 | SpwfSAInterface& WiFi = ipstack->getWiFi(); |
mapellil | 14:641560b57584 | 88 | ip_addr = WiFi.get_ip_address(); |
mapellil | 14:641560b57584 | 89 | printf ("ID: %s\n\r",id); |
mapellil | 14:641560b57584 | 90 | // Construct clientId - d:org:type:id |
mapellil | 14:641560b57584 | 91 | char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; |
mapellil | 14:641560b57584 | 92 | sprintf(clientId, "d:%s:%s:%s", org, type, id); |
mapellil | 14:641560b57584 | 93 | // Network debug statements |
mapellil | 14:641560b57584 | 94 | LOG("=====================================\n\r"); |
mapellil | 14:641560b57584 | 95 | LOG("Connecting WiFi.\n\r"); |
mapellil | 14:641560b57584 | 96 | LOG("IP ADDRESS: %s\n\r", WiFi.get_ip_address()); |
mapellil | 14:641560b57584 | 97 | LOG("MAC ADDRESS: %s\n\r", WiFi.get_mac_address()); |
mapellil | 14:641560b57584 | 98 | LOG("Server Hostname: %s\n\r", hostname); |
mapellil | 17:83d0cd810ed3 | 99 | // for(int i = 0; clientId[i]; i++){ |
mapellil | 17:83d0cd810ed3 | 100 | // clientId[i] = tolower(clientId[i]); |
mapellil | 17:83d0cd810ed3 | 101 | // } |
mapellil | 14:641560b57584 | 102 | LOG("Client ID: %s\n\r", clientId); |
mapellil | 14:641560b57584 | 103 | LOG("=====================================\n\r"); |
mapellil | 14:641560b57584 | 104 | |
mapellil | 14:641560b57584 | 105 | netConnecting = true; |
mapellil | 14:641560b57584 | 106 | ipstack->open(&ipstack->getWiFi()); |
mapellil | 14:641560b57584 | 107 | int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout); |
mapellil | 14:641560b57584 | 108 | if (rc != 0) |
mapellil | 14:641560b57584 | 109 | { |
mapellil | 14:641560b57584 | 110 | WARN("IP Stack connect returned: %d\n", rc); |
mapellil | 14:641560b57584 | 111 | return rc; |
mapellil | 14:641560b57584 | 112 | } |
mapellil | 14:641560b57584 | 113 | netConnected = true; |
mapellil | 14:641560b57584 | 114 | netConnecting = false; |
mapellil | 14:641560b57584 | 115 | |
mapellil | 14:641560b57584 | 116 | // MQTT Connect |
mapellil | 14:641560b57584 | 117 | mqttConnecting = true; |
mapellil | 14:641560b57584 | 118 | MQTTPacket_connectData data = MQTTPacket_connectData_initializer; |
mapellil | 17:83d0cd810ed3 | 119 | data.MQTTVersion = 4; |
mapellil | 17:83d0cd810ed3 | 120 | data.struct_version=0; |
mapellil | 14:641560b57584 | 121 | data.clientID.cstring = clientId; |
mapellil | 14:641560b57584 | 122 | |
mapellil | 14:641560b57584 | 123 | if (!quickstartMode) |
mapellil | 14:641560b57584 | 124 | { |
mapellil | 14:641560b57584 | 125 | data.username.cstring = "use-token-auth"; |
mapellil | 14:641560b57584 | 126 | data.password.cstring = auth_token; |
mapellil | 14:641560b57584 | 127 | } |
mapellil | 14:641560b57584 | 128 | if ((rc = client->connect(data)) == 0) |
mapellil | 14:641560b57584 | 129 | { |
mapellil | 14:641560b57584 | 130 | connected = true; |
mapellil | 14:641560b57584 | 131 | printf ("--->Connected\n\r"); |
mapellil | 14:641560b57584 | 132 | } |
mapellil | 14:641560b57584 | 133 | else { |
mapellil | 14:641560b57584 | 134 | WARN("MQTT connect returned %d\n", rc); |
mapellil | 14:641560b57584 | 135 | } |
mapellil | 14:641560b57584 | 136 | if (rc >= 0) |
mapellil | 14:641560b57584 | 137 | connack_rc = rc; |
mapellil | 14:641560b57584 | 138 | mqttConnecting = false; |
mapellil | 14:641560b57584 | 139 | return rc; |
mapellil | 14:641560b57584 | 140 | } |
mapellil | 14:641560b57584 | 141 | |
mapellil | 14:641560b57584 | 142 | int getConnTimeout(int attemptNumber) |
mapellil | 14:641560b57584 | 143 | { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute |
mapellil | 14:641560b57584 | 144 | // after 20 attempts, retry every 10 minutes |
mapellil | 14:641560b57584 | 145 | return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; |
mapellil | 14:641560b57584 | 146 | } |
mapellil | 14:641560b57584 | 147 | |
mapellil | 14:641560b57584 | 148 | void attemptConnect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) |
mapellil | 14:641560b57584 | 149 | { |
mapellil | 14:641560b57584 | 150 | connected = false; |
mapellil | 14:641560b57584 | 151 | |
mapellil | 14:641560b57584 | 152 | while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED) |
mapellil | 14:641560b57584 | 153 | { |
mapellil | 14:641560b57584 | 154 | if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { |
mapellil | 14:641560b57584 | 155 | printf ("File: %s, Line: %d\n\r",__FILE__,__LINE__); |
mapellil | 14:641560b57584 | 156 | return; // don't reattempt to connect if credentials are wrong |
mapellil | 14:641560b57584 | 157 | } |
mapellil | 14:641560b57584 | 158 | int timeout = getConnTimeout(++retryAttempt); |
mapellil | 14:641560b57584 | 159 | WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); |
mapellil | 14:641560b57584 | 160 | |
mapellil | 14:641560b57584 | 161 | // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed |
mapellil | 14:641560b57584 | 162 | // or maybe just add the proper members to do this disconnect and call attemptConnect(...) |
mapellil | 14:641560b57584 | 163 | |
mapellil | 14:641560b57584 | 164 | // this works - reset the system when the retry count gets to a threshold |
mapellil | 14:641560b57584 | 165 | if (retryAttempt == 5) |
mapellil | 14:641560b57584 | 166 | NVIC_SystemReset(); |
mapellil | 14:641560b57584 | 167 | else |
mapellil | 14:641560b57584 | 168 | wait(timeout); |
mapellil | 14:641560b57584 | 169 | } |
mapellil | 14:641560b57584 | 170 | } |
mapellil | 14:641560b57584 | 171 | |
mapellil | 14:641560b57584 | 172 | int publish(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) |
mapellil | 14:641560b57584 | 173 | { |
mapellil | 14:641560b57584 | 174 | MQTT::Message message; |
mapellil | 14:641560b57584 | 175 | char* pubTopic = "iot-2/evt/status/fmt/json"; |
mapellil | 14:641560b57584 | 176 | |
mapellil | 14:641560b57584 | 177 | char buf[MQTT_MAX_PAYLOAD_SIZE]; |
mapellil | 14:641560b57584 | 178 | float temp, press, hum; |
mapellil | 14:641560b57584 | 179 | temp_sensor1->GetTemperature(&temp); |
mapellil | 14:641560b57584 | 180 | pressure_sensor->GetPressure(&press); |
mapellil | 14:641560b57584 | 181 | humidity_sensor->GetHumidity(&hum); |
mapellil | 14:641560b57584 | 182 | sprintf(buf, |
mapellil | 21:78fac4c1b0fa | 183 | "{\"d\":{\"ST\":\"Nucleo-IoT-mbed\",\"Temp\":%0.4f,\"Pressure\":%0.4f,\"Humidity\":%0.4f}}", |
mapellil | 14:641560b57584 | 184 | temp, press, hum); |
mapellil | 14:641560b57584 | 185 | message.qos = MQTT::QOS0; |
mapellil | 14:641560b57584 | 186 | message.retained = false; |
mapellil | 14:641560b57584 | 187 | message.dup = false; |
mapellil | 14:641560b57584 | 188 | message.payload = (void*)buf; |
mapellil | 14:641560b57584 | 189 | message.payloadlen = strlen(buf); |
mapellil | 14:641560b57584 | 190 | |
mapellil | 14:641560b57584 | 191 | LOG("Publishing %s\n", buf); |
mapellil | 14:641560b57584 | 192 | return client->publish(pubTopic, message); |
mapellil | 14:641560b57584 | 193 | } |
mridup | 4:1ed7f173eec5 | 194 | |
fabiombed | 13:0b31131bf711 | 195 | int main() |
fabiombed | 13:0b31131bf711 | 196 | { |
mapellil | 16:233b89a6b72f | 197 | const char * ssid = SSID; // Network must be visible otherwise it can't connect |
mapellil | 16:233b89a6b72f | 198 | const char * seckey = PASSW; |
mapellil | 14:641560b57584 | 199 | |
mapellil | 14:641560b57584 | 200 | // Timer tyeld; |
mapellil | 14:641560b57584 | 201 | |
mapellil | 14:641560b57584 | 202 | DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL); |
mapellil | 14:641560b57584 | 203 | i2c->frequency(400000); |
mapellil | 14:641560b57584 | 204 | |
mapellil | 14:641560b57584 | 205 | X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(i2c); |
mapellil | 14:641560b57584 | 206 | |
mapellil | 14:641560b57584 | 207 | pressure_sensor = mems_expansion_board->pt_sensor; |
mapellil | 14:641560b57584 | 208 | temp_sensor1 = mems_expansion_board->ht_sensor; |
mapellil | 14:641560b57584 | 209 | humidity_sensor = mems_expansion_board->ht_sensor; |
mridup | 4:1ed7f173eec5 | 210 | |
mridup | 6:0d838d564181 | 211 | pc.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n"); |
mapellil | 14:641560b57584 | 212 | pc.printf("\r\nconnecting to AP\r\n"); |
fabiombed | 13:0b31131bf711 | 213 | |
mapellil | 17:83d0cd810ed3 | 214 | quickstartMode=false; |
mapellil | 16:233b89a6b72f | 215 | if (strcmp(org, "quickstart") == 0){quickstartMode = true;} |
mapellil | 16:233b89a6b72f | 216 | MQTTWiFi ipstack(spwf, ssid, seckey, NSAPI_SECURITY_WPA2); |
mapellil | 16:233b89a6b72f | 217 | MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); |
mapellil | 16:233b89a6b72f | 218 | if (quickstartMode){ |
mapellil | 14:641560b57584 | 219 | char mac[50]; |
mapellil | 17:83d0cd810ed3 | 220 | char *digit=NULL; |
mapellil | 17:83d0cd810ed3 | 221 | sprintf (id,"%s", ""); |
mapellil | 14:641560b57584 | 222 | sprintf (mac,"%s",ipstack.getWiFi().get_mac_address()); |
mapellil | 14:641560b57584 | 223 | strcpy (mac, ipstack.getWiFi().get_mac_address()); |
mapellil | 14:641560b57584 | 224 | digit = strtok (mac,":"); |
mapellil | 14:641560b57584 | 225 | while (digit != NULL) |
mapellil | 14:641560b57584 | 226 | { |
mapellil | 14:641560b57584 | 227 | strcat (id, digit); |
mapellil | 14:641560b57584 | 228 | digit = strtok (NULL, ":"); |
mapellil | 17:83d0cd810ed3 | 229 | } |
mapellil | 16:233b89a6b72f | 230 | } |
mapellil | 16:233b89a6b72f | 231 | attemptConnect(&client, &ipstack); |
mapellil | 16:233b89a6b72f | 232 | if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) |
mapellil | 16:233b89a6b72f | 233 | { |
mapellil | 16:233b89a6b72f | 234 | while (true) |
mapellil | 16:233b89a6b72f | 235 | wait(1.0); // Permanent failures - don't retry |
mapellil | 16:233b89a6b72f | 236 | } |
mapellil | 16:233b89a6b72f | 237 | int count = 0; |
mapellil | 16:233b89a6b72f | 238 | // tyeld.start(); |
mapellil | 14:641560b57584 | 239 | while (true) |
mridup | 8:6df01cb43137 | 240 | { |
mapellil | 14:641560b57584 | 241 | if (++count == /*100*/2) |
mapellil | 14:641560b57584 | 242 | { // Publish a message every second |
mapellil | 14:641560b57584 | 243 | if (publish(&client, &ipstack) != 0) |
mapellil | 14:641560b57584 | 244 | attemptConnect(&client, &ipstack); // if we have lost the connection |
mapellil | 14:641560b57584 | 245 | count = 0; |
mapellil | 14:641560b57584 | 246 | } |
mapellil | 14:641560b57584 | 247 | // int start = tyeld.read_ms(); |
mapellil | 14:641560b57584 | 248 | client.yield(/*10*/1); // allow the MQTT client to receive messages |
mapellil | 14:641560b57584 | 249 | // printf ("tyeld: %d\n\r",tyeld.read_ms()-start); |
mridup | 3:dfb8c6c8c31b | 250 | } |
mridup | 4:1ed7f173eec5 | 251 | } |