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
main.cpp
00001 /* SpwfInterface NetworkSocketAPI Example Program 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" 00018 #include "SpwfInterface.h" 00019 #include "TCPSocket.h" 00020 #include "MQTTClient.h" 00021 #include "MQTTWiFi.h" 00022 #include <ctype.h> 00023 #include "x_nucleo_iks01a1.h" 00024 #include "X_NUCLEO_NFC01A1.h" 00025 #include "NDefLib/NDefNfcTag.h" 00026 #include "NDefLib/RecordType/RecordURI.h" 00027 00028 //------------------------------------ 00029 // Hyperterminal configuration 00030 // 9600 bauds, 8-bit data, no parity 00031 //------------------------------------ 00032 Serial pc(SERIAL_TX, SERIAL_RX); 00033 DigitalOut myled(LED1); 00034 bool quickstartMode = true; 00035 00036 #define ORG_QUICKSTART // comment to connect to play.internetofthings.ibmcloud.com 00037 //#define SUBSCRIBE // uncomment to subscribe to broker msgs (not to be used with IBM broker) 00038 #define X_NUCLEO_NFC01A1_PRESENT // uncomment to add NFC support 00039 00040 #define MQTT_MAX_PACKET_SIZE 250 00041 #define MQTT_MAX_PAYLOAD_SIZE 300 00042 00043 // Configuration values needed to connect to IBM IoT Cloud 00044 #define BROKER_URL ".messaging.internetofthings.ibmcloud.com"; 00045 #ifdef ORG_QUICKSTART 00046 #define ORG "quickstart" // connect to quickstart.internetofthings.ibmcloud.com/ For a registered connection, replace with your org 00047 #define ID "" 00048 #define AUTH_TOKEN "" 00049 #define DEFAULT_TYPE_NAME "iotsample-mbed-Nucleo" 00050 #else // not def ORG_QUICKSTART 00051 #define ORG "play" // connect to play.internetofthings.ibmcloud.com/ For a registered connection, replace with your org 00052 #define ID "" // For a registered connection, replace with your id 00053 #define AUTH_TOKEN ""// For a registered connection, replace with your auth-token 00054 #define DEFAULT_TYPE_NAME "sensor" 00055 #endif 00056 #define TOPIC "iot-2/evt/status/fmt/json" 00057 00058 #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type 00059 #define MQTT_PORT 1883 00060 #define MQTT_TLS_PORT 8883 00061 #define IBM_IOT_PORT MQTT_PORT 00062 // WiFi network credential 00063 #define SSID "" // Network must be visible otherwise it can't connect 00064 #define PASSW "" 00065 #warning "Wifi SSID & password empty" 00066 00067 char id[30] = ID; // mac without colons 00068 char org[12] = ORG; 00069 int connack_rc = 0; // MQTT connack return code 00070 const char* ip_addr = ""; 00071 char* host_addr = ""; 00072 char type[30] = TYPE; 00073 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode 00074 bool netConnecting = false; 00075 int connectTimeout = 1000; 00076 bool mqttConnecting = false; 00077 bool netConnected = false; 00078 bool connected = false; 00079 int retryAttempt = 0; 00080 char subscription_url[MQTT_MAX_PAYLOAD_SIZE]; 00081 00082 PressureSensor *pressure_sensor; 00083 HumiditySensor *humidity_sensor; 00084 TempSensor *temp_sensor1; 00085 00086 MQTT::Message message; 00087 MQTTString TopicName={TOPIC}; 00088 MQTT::MessageData MsgData(TopicName, message); 00089 00090 void subscribe_cb(MQTT::MessageData & msgMQTT) { 00091 char msg[MQTT_MAX_PAYLOAD_SIZE]; 00092 msg[0]='\0'; 00093 strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen); 00094 printf ("--->>> subscribe_cb msg: %s\n\r", msg); 00095 } 00096 00097 int subscribe(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00098 { 00099 char* pubTopic = TOPIC; 00100 return client->subscribe(pubTopic, MQTT::QOS1, subscribe_cb); 00101 } 00102 00103 int connect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00104 { 00105 const char* iot_ibm = BROKER_URL; 00106 00107 00108 char hostname[strlen(org) + strlen(iot_ibm) + 1]; 00109 sprintf(hostname, "%s%s", org, iot_ibm); 00110 SpwfSAInterface& WiFi = ipstack->getWiFi(); 00111 // ip_addr = WiFi.get_ip_address(); 00112 // Construct clientId - d:org:type:id 00113 char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; 00114 sprintf(clientId, "d:%s:%s:%s", org, type, id); 00115 sprintf(subscription_url, "%s.%s/#/device/%s/sensor/", org, "internetofthings.ibmcloud.com",id); 00116 00117 // Network debug statements 00118 LOG("=====================================\n\r"); 00119 LOG("Connecting WiFi.\n\r"); 00120 LOG("Nucleo IP ADDRESS: %s\n\r", WiFi.get_ip_address()); 00121 LOG("Nucleo MAC ADDRESS: %s\n\r", WiFi.get_mac_address()); 00122 LOG("Server Hostname: %s port: %d\n\r", hostname, IBM_IOT_PORT); 00123 // for(int i = 0; clientId[i]; i++){ // set lowercase mac 00124 // clientId[i] = tolower(clientId[i]); 00125 // } 00126 LOG("Client ID: %s\n\r", clientId); 00127 LOG("Topic: %s\n\r",TOPIC); 00128 LOG("Subscription URL: %s\n\r", subscription_url); 00129 LOG("=====================================\n\r"); 00130 00131 netConnecting = true; 00132 ipstack->open(&ipstack->getWiFi()); 00133 int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout); 00134 if (rc != 0) 00135 { 00136 WARN("IP Stack connect returned: %d\n", rc); 00137 return rc; 00138 } 00139 printf ("--->TCP Connected\n\r"); 00140 netConnected = true; 00141 netConnecting = false; 00142 00143 // MQTT Connect 00144 mqttConnecting = true; 00145 MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 00146 data.MQTTVersion = 4; 00147 data.struct_version=0; 00148 data.clientID.cstring = clientId; 00149 00150 if (!quickstartMode) 00151 { 00152 data.username.cstring = "use-token-auth"; 00153 data.password.cstring = auth_token; 00154 } 00155 if ((rc = client->connect(data)) == 0) 00156 { 00157 connected = true; 00158 printf ("--->MQTT Connected\n\r"); 00159 #ifdef SUBSCRIBE 00160 if (!subscribe(client, ipstack)) printf ("--->>>MQTT subscribed to: %s\n\r",TOPIC); 00161 #endif 00162 } 00163 else { 00164 WARN("MQTT connect returned %d\n", rc); 00165 } 00166 if (rc >= 0) 00167 connack_rc = rc; 00168 mqttConnecting = false; 00169 return rc; 00170 } 00171 00172 int getConnTimeout(int attemptNumber) 00173 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute 00174 // after 20 attempts, retry every 10 minutes 00175 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; 00176 } 00177 00178 void attemptConnect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00179 { 00180 connected = false; 00181 00182 while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED) 00183 { 00184 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { 00185 printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc); 00186 return; // don't reattempt to connect if credentials are wrong 00187 } 00188 int timeout = getConnTimeout(++retryAttempt); 00189 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); 00190 00191 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed 00192 // or maybe just add the proper members to do this disconnect and call attemptConnect(...) 00193 // this works - reset the system when the retry count gets to a threshold 00194 if (retryAttempt == 5) 00195 NVIC_SystemReset(); 00196 else 00197 wait(timeout); 00198 } 00199 } 00200 00201 int publish(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00202 { 00203 MQTT::Message message; 00204 char* pubTopic = TOPIC; 00205 00206 char buf[MQTT_MAX_PAYLOAD_SIZE]; 00207 float temp, press, hum; 00208 temp_sensor1->GetTemperature(&temp); 00209 pressure_sensor->GetPressure(&press); 00210 humidity_sensor->GetHumidity(&hum); 00211 sprintf(buf, 00212 "{\"d\":{\"ST\":\"Nucleo-IoT-mbed\",\"Temp\":%0.4f,\"Pressure\":%0.4f,\"Humidity\":%0.4f}}", 00213 temp, press, hum); 00214 message.qos = MQTT::QOS0; 00215 message.retained = false; 00216 message.dup = false; 00217 message.payload = (void*)buf; 00218 message.payloadlen = strlen(buf); 00219 00220 // LOG("Publishing %s\n\r", buf); 00221 printf("Publishing %s\n\r", buf); 00222 return client->publish(pubTopic, message); 00223 } 00224 00225 int main() 00226 { 00227 const char * ssid = SSID; // Network must be visible otherwise it can't connect 00228 const char * seckey = PASSW; 00229 SpwfSAInterface spwf(D8, D2, false); 00230 00231 // Timer tyeld; 00232 myled=0; 00233 DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL); 00234 i2c->frequency(400000); 00235 00236 X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(i2c); 00237 pressure_sensor = mems_expansion_board->pt_sensor; 00238 temp_sensor1 = mems_expansion_board->ht_sensor; 00239 humidity_sensor = mems_expansion_board->ht_sensor; 00240 00241 pc.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n"); 00242 pc.printf("\r\nconnecting to AP\r\n"); 00243 00244 quickstartMode=false; 00245 if (strcmp(org, "quickstart") == 0){quickstartMode = true;} 00246 MQTTWiFi ipstack(spwf, ssid, seckey, NSAPI_SECURITY_WPA2); 00247 MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); 00248 if (quickstartMode){ 00249 char mac[50]; // remove all : from mac 00250 char *digit=NULL; 00251 sprintf (id,"%s", ""); 00252 sprintf (mac,"%s",ipstack.getWiFi().get_mac_address()); 00253 digit = strtok (mac,":"); 00254 while (digit != NULL) 00255 { 00256 strcat (id, digit); 00257 digit = strtok (NULL, ":"); 00258 } 00259 } 00260 attemptConnect(&client, &ipstack); 00261 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) 00262 { 00263 while (true) 00264 wait(1.0); // Permanent failures - don't retry 00265 } 00266 #ifdef X_NUCLEO_NFC01A1_PRESENT 00267 // program NFC with broker URL 00268 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); 00269 NDefLib::NDefNfcTag& tag = nfcNucleo->getM24SR().getNDefTag(); 00270 printf("NFC Init done: !\r\n"); 00271 //open the i2c session with the nfc chip 00272 if(tag.openSession()){ 00273 //create the NDef message and record 00274 NDefLib::Message msg; 00275 NDefLib::RecordURI rUri(NDefLib::RecordURI::HTTPS, subscription_url); 00276 msg.addRecord(&rUri); 00277 //write the tag 00278 if(tag.write(msg)){ 00279 printf("Tag writed \r\n"); 00280 } 00281 //close the i2c session 00282 if(!tag.closeSession()){ 00283 printf("Error Closing the session\r\n"); 00284 } 00285 }else printf("Error open Session\r\n"); 00286 #endif 00287 myled=1; 00288 int count = 0; 00289 // tyeld.start(); 00290 while (true) 00291 { 00292 if (++count == 100) 00293 { // Publish a message every second 00294 if (publish(&client, &ipstack) != 0) { 00295 myled=0; 00296 attemptConnect(&client, &ipstack); // if we have lost the connection 00297 } else myled=1; 00298 count = 0; 00299 } 00300 // int start = tyeld.read_ms(); 00301 client.yield(10); // allow the MQTT client to receive messages 00302 // printf ("tyeld: %d\n\r",tyeld.read_ms()-start); 00303 } 00304 }
Generated on Sat Jul 16 2022 22:46:01 by 1.7.2