Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MQTT NDefLib X_NUCLEO_IKS01A2 X_NUCLEO_NFC01A1
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 "easy-connect.h" 00019 #include "MQTTClient.h" 00020 #include "XNucleoIKS01A2.h" 00021 #include "XNucleoNFC01A1.h" 00022 #include "NDefLib/NDefNfcTag.h" 00023 #include "NDefLib/RecordType/RecordURI.h" 00024 #include "MQTTNetwork.h" 00025 #include "MQTTmbed.h" 00026 00027 00028 //------------------------------------ 00029 // Hyperterminal configuration 00030 // 9600 bauds, 8-bit data, no parity 00031 //------------------------------------ 00032 static Serial pc(SERIAL_TX, SERIAL_RX); 00033 static DigitalOut myled(LED1); 00034 static bool quickstartMode = true; // set to false to connect with authentication tocken 00035 static bool BlueButtonToggle = false; 00036 00037 #define ORG_QUICKSTART // comment to connect to play.internetofthings.ibmcloud.com 00038 //#define SUBSCRIBE // uncomment to subscribe to broker msgs (not to be used with IBM broker) 00039 //#define X_NUCLEO_NFC01A1_PRESENT // uncomment to add NFC support 00040 00041 #define MQTT_MAX_PACKET_SIZE 400 00042 #define MQTT_MAX_PAYLOAD_SIZE 300 00043 00044 // Configuration values needed to connect to IBM IoT Cloud 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 00057 #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type 00058 #define IBM_IOT_PORT MQTT_PORT 00059 00060 static char id[30] = ID; // mac without colons 00061 static char org[12] = ORG; 00062 static int connack_rc = 0; // MQTT connack return code 00063 static char type[30] = TYPE; 00064 static char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode 00065 static bool netConnecting = false; 00066 static int connectTimeout = 1000; 00067 static bool mqttConnecting = false; 00068 static bool netConnected = false; 00069 static bool connected = false; 00070 static int retryAttempt = 0; 00071 static char subscription_url[MQTT_MAX_PAYLOAD_SIZE]; 00072 00073 static LPS22HBSensor *pressure_sensor; 00074 static HTS221Sensor *humidity_sensor; 00075 static HTS221Sensor *temp_sensor1; 00076 00077 #ifndef TARGET_SENSOR_TILE 00078 static void BlueButtonPressed () 00079 { 00080 BlueButtonToggle = true; 00081 } 00082 #endif 00083 00084 #ifdef SUBSCRIBE 00085 void subscribe_cb(MQTT::MessageData & msgMQTT) { 00086 char msg[MQTT_MAX_PAYLOAD_SIZE]; 00087 msg[0]='\0'; 00088 strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen); 00089 printf ("--->>> subscribe_cb msg: %s\n\r", msg); 00090 } 00091 00092 int subscribe(char *pubTopic, MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client) 00093 { 00094 return client->subscribe(pubTopic, MQTT::QOS1, subscribe_cb); 00095 } 00096 #endif 00097 00098 int connect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) 00099 { 00100 const char* iot_ibm = MQTT_BROKER_URL; 00101 char hostname[strlen(org) + strlen(iot_ibm) + 1]; 00102 00103 sprintf(hostname, "%s%s", org, iot_ibm); 00104 // Construct clientId - d:org:type:id 00105 char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; 00106 sprintf(clientId, "d:%s:%s:%s", org, type, id); 00107 sprintf(subscription_url, "%s.%s/#/device/%s/sensor/", org, "internetofthings.ibmcloud.com",id); 00108 00109 // Network debug statements 00110 LOG("=====================================\n\r"); 00111 LOG("Nucleo IP ADDRESS: %s\n\r", network->get_ip_address()); 00112 LOG("Nucleo MAC ADDRESS: %s\n\r", network->get_mac_address()); 00113 LOG("Server Hostname: %s port: %d\n\r", hostname, IBM_IOT_PORT); 00114 // for(int i = 0; clientId[i]; i++){ // set lowercase mac 00115 // clientId[i] = tolower(clientId[i]); 00116 // } 00117 LOG("Client ID: %s\n\r", clientId); 00118 LOG("Topic: %s\n\r",MQTT_TOPIC); 00119 LOG("Subscription URL: %s\n\r", subscription_url); 00120 LOG("=====================================\n\r"); 00121 netConnecting = true; 00122 int rc = mqttNetwork->connect(hostname, IBM_IOT_PORT); 00123 if (rc != 0) 00124 { 00125 printf("rc from TCP connect is %d\r\n", rc); 00126 return rc; 00127 } 00128 00129 printf ("--->TCP Connected\n\r"); 00130 netConnected = true; 00131 netConnecting = false; 00132 00133 // MQTT Connect 00134 mqttConnecting = true; 00135 MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 00136 data.MQTTVersion = 4; 00137 data.struct_version=0; 00138 data.clientID.cstring = clientId; 00139 data.keepAliveInterval = MQTT_KEEPALIVE; // in Sec 00140 if (!quickstartMode) 00141 { 00142 data.username.cstring = "use-token-auth"; 00143 data.password.cstring = auth_token; 00144 } 00145 if ((rc = client->connect(data)) != 0) { 00146 printf("rc from MQTT connect is %d\r\n", rc); 00147 connack_rc = rc; 00148 return rc; 00149 } 00150 connected = true; 00151 printf ("--->MQTT Connected\n\r"); 00152 #ifdef SUBSCRIBE 00153 int rc=0; 00154 if ((rc=subscribe(MQTT_TOPIC, client)) == 0) LOG ("--->>>MQTT subscribed to: %s\n\r",MQTT_TOPIC); 00155 else LOG ("--->>>ERROR MQTT subscribe : %s\n\r",MQTT_TOPIC); 00156 #endif 00157 mqttConnecting = false; 00158 connack_rc = rc; 00159 return rc; 00160 } 00161 00162 00163 int getConnTimeout(int attemptNumber) 00164 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute 00165 // after 20 attempts, retry every 10 minutes 00166 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; 00167 } 00168 00169 00170 void attemptConnect(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTNetwork *mqttNetwork, NetworkInterface* network) 00171 { 00172 connected = false; 00173 00174 while (connect(client, mqttNetwork, network) != MQTT_CONNECTION_ACCEPTED) 00175 { 00176 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { 00177 printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc); 00178 return; // don't reattempt to connect if credentials are wrong 00179 } 00180 int timeout = getConnTimeout(++retryAttempt); 00181 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); 00182 00183 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed 00184 // or maybe just add the proper members to do this disconnect and call attemptConnect(...) 00185 // this works - reset the system when the retry count gets to a threshold 00186 if (retryAttempt == 5) 00187 NVIC_SystemReset(); 00188 else 00189 wait(timeout); 00190 } 00191 } 00192 00193 int publish(MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE>* client) 00194 { 00195 MQTT::Message message; 00196 const char* pubTopic = MQTT_TOPIC; 00197 00198 char buf[MQTT_MAX_PAYLOAD_SIZE]; 00199 float temp, press, hum; 00200 00201 if (!client->isConnected()) { printf ("---> MQTT DISCONNECTED\n\r"); return MQTT::FAILURE; } 00202 temp_sensor1->get_temperature(&temp); 00203 pressure_sensor->get_pressure(&press); 00204 humidity_sensor->get_humidity(&hum); 00205 sprintf(buf, 00206 "{\"d\":{\"ST\":\"Nucleo-IoT-mbed\",\"Temp\":%0.4f,\"Pressure\":%0.4f,\"Humidity\":%0.4f}}", 00207 temp, press, hum); 00208 message.qos = MQTT::QOS0; 00209 message.retained = false; 00210 message.dup = false; 00211 message.payload = (void*)buf; 00212 message.payloadlen = strlen(buf); 00213 00214 if( (message.payloadlen + strlen(pubTopic)+1) >= MQTT_MAX_PACKET_SIZE ) 00215 printf("message too long!\r\n"); 00216 00217 LOG("Publishing %s\n\r", buf); 00218 return client->publish(pubTopic, message); 00219 } 00220 00221 int main() 00222 { 00223 myled=0; 00224 DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL); 00225 i2c->frequency(400000); 00226 00227 XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(i2c); 00228 pressure_sensor = mems_expansion_board->pt_sensor; 00229 temp_sensor1 = mems_expansion_board->ht_sensor; 00230 humidity_sensor = mems_expansion_board->ht_sensor; 00231 pressure_sensor->enable(); 00232 temp_sensor1->enable(); 00233 humidity_sensor->enable(); 00234 00235 #if !defined (TARGET_SENSOR_TILE) 00236 InterruptIn BlueButton(USER_BUTTON); 00237 BlueButton.fall(&BlueButtonPressed); 00238 BlueButtonToggle = false; 00239 #endif 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 NetworkInterface* network = easy_connect(true); 00247 if (!network) { 00248 printf ("Error easy_connect\n\r"); 00249 return -1; 00250 } 00251 MQTTNetwork mqttNetwork(network); 00252 MQTT::Client<MQTTNetwork, Countdown, MQTT_MAX_PACKET_SIZE> client(mqttNetwork); 00253 00254 if (quickstartMode){ 00255 char mac[50]; // remove all : from mac 00256 char *digit=NULL; 00257 sprintf (id,"%s", ""); 00258 sprintf (mac,"%s",network->get_mac_address()); 00259 digit = strtok (mac,":"); 00260 while (digit != NULL) 00261 { 00262 strcat (id, digit); 00263 digit = strtok (NULL, ":"); 00264 } 00265 } 00266 printf ("ATTEMPT CONNECT\n\r"); 00267 attemptConnect(&client, &mqttNetwork, network); 00268 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) 00269 { 00270 printf ("---ERROR line : %d\n\r", __LINE__); 00271 while (true) 00272 wait(1.0); // Permanent failures - don't retry 00273 } 00274 #ifdef X_NUCLEO_NFC01A1_PRESENT 00275 // program NFC with broker URL 00276 XNucleoNFC01A1 *nfcNucleo = XNucleoNFC01A1::instance(*i2c, NULL, XNucleoNFC01A1::DEFAULT_GPO_PIN, XNucleoNFC01A1::DEFAULT_RF_DISABLE_PIN, NC,NC,NC); 00277 NDefLib::NDefNfcTag& tag = nfcNucleo->get_M24SR().get_NDef_tag(); 00278 printf("NFC Init done: !\r\n"); 00279 //open the i2c session with the nfc chip 00280 if(tag.open_session()){ 00281 //create the NDef message and record 00282 NDefLib::Message msg; 00283 NDefLib::RecordURI rUri(NDefLib::RecordURI::HTTPS, subscription_url); 00284 msg.add_record(&rUri); 00285 //write the tag 00286 if(tag.write(msg)){ 00287 printf("Tag writed \r\n"); 00288 } 00289 //close the i2c session 00290 if(!tag.close_session()){ 00291 printf("Error Closing the session\r\n"); 00292 } 00293 }else printf("Error open Session\r\n"); 00294 #endif 00295 myled=1; 00296 int count = 0; 00297 while (true) 00298 { 00299 if (BlueButtonToggle == false && connected == true) { 00300 if (++count == 6) 00301 { // Publish a message every 3 second 00302 if (publish(&client) != MQTT::SUCCESS) { 00303 myled=0; 00304 count=0; 00305 client.disconnect(); 00306 mqttNetwork.disconnect(); 00307 attemptConnect(&client, &mqttNetwork, network); // if we have lost the connection 00308 } else { 00309 myled=1; 00310 count=0; 00311 } 00312 } 00313 client.yield(500); // allow the MQTT client to receive subscribe messages and manage keep alive 00314 } else if (BlueButtonToggle == true && connected == true){ // disconnect MQTT 00315 printf ("--->> Disconnect\n\r"); 00316 connected = false; 00317 count = 0; 00318 BlueButtonToggle = false; 00319 #ifdef SUBSCRIBE 00320 // unsubscribe(const char* topicFilter); // unsubscribe if subscribed 00321 #endif 00322 client.disconnect(); 00323 mqttNetwork.disconnect(); 00324 } else if (BlueButtonToggle == true && connected == false) { 00325 connected = true; 00326 BlueButtonToggle = false; 00327 } else wait (0.5); 00328 } 00329 } 00330
Generated on Thu Jul 21 2022 14:36:04 by
1.7.2