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: MEMES_MQTT_IBM NDefLib NetworkSocketAPI X_NUCLEO_IDW01M1v2 X_NUCLEO_IKS01A1 mbed
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 "STM" // Network must be visible otherwise it can't connect 00064 #define PASSW "STMdemoPWD" 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 static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(D14, D15); 00082 static PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor; 00083 static TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor; 00084 static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor; 00085 00086 00087 MQTT::Message message; 00088 MQTTString TopicName={TOPIC}; 00089 MQTT::MessageData MsgData(TopicName, message); 00090 static GyroSensor *gyroscope = mems_expansion_board->GetGyroscope(); 00091 static MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer(); 00092 static MagneticSensor *magnetometer = mems_expansion_board->magnetometer; 00093 00094 00095 void subscribe_cb(MQTT::MessageData & msgMQTT) { 00096 char msg[MQTT_MAX_PAYLOAD_SIZE]; 00097 msg[0]='\0'; 00098 strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen); 00099 printf ("--->>> subscribe_cb msg: %s\n\r", msg); 00100 } 00101 00102 int subscribe(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00103 { 00104 char* pubTopic = TOPIC; 00105 return client->subscribe(pubTopic, MQTT::QOS1, subscribe_cb); 00106 } 00107 00108 int connect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00109 { 00110 const char* iot_ibm = BROKER_URL; 00111 00112 00113 char hostname[strlen(org) + strlen(iot_ibm) + 1]; 00114 sprintf(hostname, "%s%s", org, iot_ibm); 00115 SpwfSAInterface& WiFi = ipstack->getWiFi(); 00116 // ip_addr = WiFi.get_ip_address(); 00117 // Construct clientId - d:org:type:id 00118 char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; 00119 sprintf(clientId, "d:%s:%s:%s", org, type, id); 00120 sprintf(subscription_url, "%s.%s/#/device/%s/sensor/", org, "internetofthings.ibmcloud.com",id); 00121 00122 // Network debug statements 00123 LOG("=====================================\n\r"); 00124 LOG("Connecting WiFi.\n\r"); 00125 LOG("Nucleo IP ADDRESS: %s\n\r", WiFi.get_ip_address()); 00126 LOG("Nucleo MAC ADDRESS: %s\n\r", WiFi.get_mac_address()); 00127 LOG("Server Hostname: %s port: %d\n\r", hostname, IBM_IOT_PORT); 00128 // for(int i = 0; clientId[i]; i++){ // set lowercase mac 00129 // clientId[i] = tolower(clientId[i]); 00130 // } 00131 LOG("Client ID: %s\n\r", clientId); 00132 LOG("Topic: %s\n\r",TOPIC); 00133 LOG("Subscription URL: %s\n\r", subscription_url); 00134 LOG("=====================================\n\r"); 00135 00136 netConnecting = true; 00137 ipstack->open(&ipstack->getWiFi()); 00138 int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout); 00139 if (rc != 0) 00140 { 00141 WARN("IP Stack connect returned: %d\n", rc); 00142 return rc; 00143 } 00144 printf ("--->TCP Connected\n\r"); 00145 netConnected = true; 00146 netConnecting = false; 00147 00148 // MQTT Connect 00149 mqttConnecting = true; 00150 MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 00151 data.MQTTVersion = 4; 00152 data.struct_version=0; 00153 data.clientID.cstring = clientId; 00154 00155 if (!quickstartMode) 00156 { 00157 data.username.cstring = "use-token-auth"; 00158 data.password.cstring = auth_token; 00159 } 00160 if ((rc = client->connect(data)) == 0) 00161 { 00162 connected = true; 00163 printf ("--->MQTT Connected\n\r"); 00164 #ifdef SUBSCRIBE 00165 if (!subscribe(client, ipstack)) printf ("--->>>MQTT subscribed to: %s\n\r",TOPIC); 00166 #endif 00167 } 00168 else { 00169 WARN("MQTT connect returned %d\n", rc); 00170 } 00171 if (rc >= 0) 00172 connack_rc = rc; 00173 mqttConnecting = false; 00174 return rc; 00175 } 00176 00177 int getConnTimeout(int attemptNumber) 00178 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute 00179 // after 20 attempts, retry every 10 minutes 00180 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; 00181 } 00182 00183 void attemptConnect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00184 { 00185 connected = false; 00186 00187 while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED) 00188 { 00189 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { 00190 printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc); 00191 return; // don't reattempt to connect if credentials are wrong 00192 } 00193 int timeout = getConnTimeout(++retryAttempt); 00194 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); 00195 00196 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed 00197 // or maybe just add the proper members to do this disconnect and call attemptConnect(...) 00198 // this works - reset the system when the retry count gets to a threshold 00199 if (retryAttempt == 5) 00200 NVIC_SystemReset(); 00201 else 00202 wait(timeout); 00203 } 00204 } 00205 00206 int publish(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00207 { 00208 MQTT::Message message; 00209 char* pubTopic = TOPIC; 00210 00211 char buf[MQTT_MAX_PAYLOAD_SIZE]; 00212 float temp, press, hum; 00213 int32_t axes[3]; 00214 temp_sensor1->get_temperature(&temp); 00215 pressure_sensor->get_pressure(&press); 00216 humidity_sensor->get_humidity(&hum); 00217 accelerometer->get_x_axes(axes); 00218 gyroscope->get_g_axes(axes); 00219 float axesx = axes[0] ; 00220 float axesy = axes[1]; 00221 float axesz = axes[2]; 00222 gyroscope->get_g_axes(axes); 00223 float g_axesx= axes[0]; 00224 float g_axesy= axes[1]; 00225 00226 sprintf(buf, 00227 "{\"d\":{\"ST\":\"Nucleo-IoT-mbed\",\"Temp\":%0.4f,\"Pressure\":%0.4f,\"Humidity\":%0.4f,\"Accelox\":%0.4f,\"Acceloy\":%0.4f,\"Acceloz\":%0.4f,\"Magnetox\":%0.4f,\"Magnetoy\":%0.4f}}", 00228 temp, press, hum,axesx,axesy,axesz, g_axesx,g_axesy); 00229 message.qos = MQTT::QOS0; 00230 message.retained = false; 00231 message.dup = false; 00232 message.payload = (void*)buf; 00233 message.payloadlen = strlen(buf); 00234 00235 // LOG("Publishing %s\n\r", buf); 00236 printf("Publishing %s\n\r", buf); 00237 return client->publish(pubTopic, message); 00238 } 00239 00240 int main() 00241 { 00242 const char * ssid = SSID; // Network must be visible otherwise it can't connect 00243 const char * seckey = PASSW; 00244 SpwfSAInterface spwf(D8, D2, false); 00245 00246 // Timer tyeld; 00247 myled=0; 00248 DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL); 00249 i2c->frequency(400000); 00250 00251 00252 00253 pc.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n"); 00254 pc.printf("\r\nconnecting to AP\r\n"); 00255 00256 quickstartMode=false; 00257 if (strcmp(org, "quickstart") == 0){quickstartMode = true;} 00258 MQTTWiFi ipstack(spwf, ssid, seckey, NSAPI_SECURITY_WPA2); 00259 MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); 00260 if (quickstartMode){ 00261 char mac[50]; // remove all : from mac 00262 char *digit=NULL; 00263 sprintf (id,"%s", ""); 00264 sprintf (mac,"%s",ipstack.getWiFi().get_mac_address()); 00265 digit = strtok (mac,":"); 00266 while (digit != NULL) 00267 { 00268 strcat (id, digit); 00269 digit = strtok (NULL, ":"); 00270 } 00271 } 00272 attemptConnect(&client, &ipstack); 00273 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) 00274 { 00275 while (true) 00276 wait(1.0); // Permanent failures - don't retry 00277 } 00278 00279 myled=1; 00280 int count = 0; 00281 // tyeld.start(); 00282 while (true) 00283 { 00284 if (++count == 100) 00285 { // Publish a message every second 00286 if (publish(&client, &ipstack) != 0) { 00287 myled=0; 00288 attemptConnect(&client, &ipstack); // if we have lost the connection 00289 } else myled=1; 00290 count = 0; 00291 } 00292 // int start = tyeld.read_ms(); 00293 client.yield(10); // allow the MQTT client to receive messages 00294 // printf ("tyeld: %d\n\r",tyeld.read_ms()-start); 00295 } 00296 }
Generated on Sun Jul 17 2022 04:53:57 by
1.7.2