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: Watson-IoT-MQTT-WiFi-MEMS NDefLib NetworkSocketAPI X_NUCLEO_IDW01M1v2 X_NUCLEO_IKS01A2 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 "XNucleoIKS01A2.h" 00024 //#include "x_nucleo_iks01a1.h" 00025 //#include "X_NUCLEO_NFC01A1.h" 00026 #include "NDefLib/NDefNfcTag.h" 00027 #include "NDefLib/RecordType/RecordURI.h" 00028 00029 //------------------------------------ 00030 // Hyperterminal configuration 00031 // 9600 bauds, 8-bit data, no parity 00032 //------------------------------------ 00033 Serial pc(SERIAL_TX, SERIAL_RX); 00034 DigitalOut myled(LED1); 00035 bool quickstartMode = true; 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 250 00042 #define MQTT_MAX_PAYLOAD_SIZE 300 00043 00044 // Configuration values needed to connect to IBM IoT Cloud 00045 #define BROKER_URL ".messaging.internetofthings.ibmcloud.com"; 00046 #ifdef ORG_QUICKSTART 00047 #define ORG "quickstart" // connect to quickstart.internetofthings.ibmcloud.com/ For a registered connection, replace with your org 00048 #define ID "" 00049 #define AUTH_TOKEN "" 00050 #define DEFAULT_TYPE_NAME "iotsample-mbed-Nucleo" 00051 #else // not def ORG_QUICKSTART 00052 #define ORG "play" // connect to play.internetofthings.ibmcloud.com/ For a registered connection, replace with your org 00053 #define ID "" // For a registered connection, replace with your id 00054 #define AUTH_TOKEN ""// For a registered connection, replace with your auth-token 00055 #define DEFAULT_TYPE_NAME "sensor" 00056 #endif 00057 #define TOPIC "iot-2/evt/status/fmt/json" 00058 00059 #define TYPE DEFAULT_TYPE_NAME // For a registered connection, replace with your type 00060 #define MQTT_PORT 1883 00061 #define MQTT_TLS_PORT 8883 00062 #define IBM_IOT_PORT MQTT_PORT 00063 // WiFi network credential 00064 #define SSID "" // Network must be visible otherwise it can't connect 00065 #define PASSW "" 00066 #warning "Wifi SSID & password empty" 00067 00068 char id[30] = ID; // mac without colons 00069 char org[12] = ORG; 00070 int connack_rc = 0; // MQTT connack return code 00071 const char* ip_addr = ""; 00072 char* host_addr = ""; 00073 char type[30] = TYPE; 00074 char auth_token[30] = AUTH_TOKEN; // Auth_token is only used in non-quickstart mode 00075 bool netConnecting = false; 00076 int connectTimeout = 1000; 00077 bool mqttConnecting = false; 00078 bool netConnected = false; 00079 bool connected = false; 00080 int retryAttempt = 0; 00081 char subscription_url[MQTT_MAX_PAYLOAD_SIZE]; 00082 /* 00083 PressureSensor *pressure_sensor; 00084 HumiditySensor *humidity_sensor; 00085 TempSensor *temp_sensor1; 00086 */ 00087 00088 /* Instantiate the expansion board */ 00089 static XNucleoIKS01A2 *mems_expansion_board = XNucleoIKS01A2::instance(D14, D15, D4, D5); 00090 00091 /* Retrieve the composing elements of the expansion board */ 00092 static LSM303AGRMagSensor *magnetometer = mems_expansion_board->magnetometer; 00093 static HTS221Sensor *hum_temp = mems_expansion_board->ht_sensor; 00094 static LPS22HBSensor *press_temp = mems_expansion_board->pt_sensor; 00095 static LSM6DSLSensor *acc_gyro = mems_expansion_board->acc_gyro; 00096 static LSM303AGRAccSensor *accelerometer = mems_expansion_board->accelerometer; 00097 00098 InterruptIn mybutton(USER_BUTTON); 00099 00100 volatile int mems_event = 0; 00101 volatile int toggle_hw_event_enable = 0; 00102 static int hw_event_is_enabled = 1; 00103 uint16_t step_count = 0; 00104 00105 /* User button callback. */ 00106 void pressed_cb() { 00107 toggle_hw_event_enable = 1; 00108 } 00109 00110 /* Interrupt 1 callback. */ 00111 void int1_cb() { 00112 mems_event = 1; 00113 } 00114 00115 /* Interrupt 2 callback. */ 00116 void int2_cb() { 00117 mems_event = 1; 00118 } 00119 00120 /* Print the orientation. */ 00121 void send_orientation() { 00122 uint8_t xl = 0; 00123 uint8_t xh = 0; 00124 uint8_t yl = 0; 00125 uint8_t yh = 0; 00126 uint8_t zl = 0; 00127 uint8_t zh = 0; 00128 00129 acc_gyro->get_6d_orientation_xl(&xl); 00130 acc_gyro->get_6d_orientation_xh(&xh); 00131 acc_gyro->get_6d_orientation_yl(&yl); 00132 acc_gyro->get_6d_orientation_yh(&yh); 00133 acc_gyro->get_6d_orientation_zl(&zl); 00134 acc_gyro->get_6d_orientation_zh(&zh); 00135 00136 if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 1 && zh == 0 ) { 00137 printf( "\r\n ________________ " \ 00138 "\r\n | | " \ 00139 "\r\n | * | " \ 00140 "\r\n | | " \ 00141 "\r\n | | " \ 00142 "\r\n | | " \ 00143 "\r\n | | " \ 00144 "\r\n |________________| \r\n" ); 00145 } 00146 00147 else if ( xl == 1 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 0 ) { 00148 printf( "\r\n ________________ " \ 00149 "\r\n | | " \ 00150 "\r\n | * | " \ 00151 "\r\n | | " \ 00152 "\r\n | | " \ 00153 "\r\n | | " \ 00154 "\r\n | | " \ 00155 "\r\n |________________| \r\n" ); 00156 } 00157 00158 else if ( xl == 0 && yl == 0 && zl == 0 && xh == 1 && yh == 0 && zh == 0 ) { 00159 printf( "\r\n ________________ " \ 00160 "\r\n | | " \ 00161 "\r\n | | " \ 00162 "\r\n | | " \ 00163 "\r\n | | " \ 00164 "\r\n | | " \ 00165 "\r\n | * | " \ 00166 "\r\n |________________| \r\n" ); 00167 } 00168 00169 else if ( xl == 0 && yl == 1 && zl == 0 && xh == 0 && yh == 0 && zh == 0 ) { 00170 printf( "\r\n ________________ " \ 00171 "\r\n | | " \ 00172 "\r\n | | " \ 00173 "\r\n | | " \ 00174 "\r\n | | " \ 00175 "\r\n | | " \ 00176 "\r\n | * | " \ 00177 "\r\n |________________| \r\n" ); 00178 } 00179 00180 else if ( xl == 0 && yl == 0 && zl == 0 && xh == 0 && yh == 0 && zh == 1 ) { 00181 printf( "\r\n __*_____________ " \ 00182 "\r\n |________________| \r\n" ); 00183 } 00184 00185 else if ( xl == 0 && yl == 0 && zl == 1 && xh == 0 && yh == 0 && zh == 0 ) { 00186 printf( "\r\n ________________ " \ 00187 "\r\n |________________| " \ 00188 "\r\n * \r\n" ); 00189 } 00190 00191 else { 00192 printf( "None of the 6D orientation axes is set in LSM6DSL - accelerometer.\r\n" ); 00193 } 00194 } 00195 00196 00197 MQTT::Message message; 00198 MQTTString TopicName={TOPIC}; 00199 MQTT::MessageData MsgData(TopicName, message); 00200 00201 void subscribe_cb(MQTT::MessageData & msgMQTT) { 00202 char msg[MQTT_MAX_PAYLOAD_SIZE]; 00203 msg[0]='\0'; 00204 strncat (msg, (char*)msgMQTT.message.payload, msgMQTT.message.payloadlen); 00205 printf ("--->>> subscribe_cb msg: %s\n\r", msg); 00206 } 00207 00208 int subscribe(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00209 { 00210 char* pubTopic = TOPIC; 00211 return client->subscribe(pubTopic, MQTT::QOS1, subscribe_cb); 00212 } 00213 00214 int connect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00215 { 00216 const char* iot_ibm = BROKER_URL; 00217 00218 00219 char hostname[strlen(org) + strlen(iot_ibm) + 1]; 00220 sprintf(hostname, "%s%s", org, iot_ibm); 00221 SpwfSAInterface& WiFi = ipstack->getWiFi(); 00222 // ip_addr = WiFi.get_ip_address(); 00223 // Construct clientId - d:org:type:id 00224 char clientId[strlen(org) + strlen(type) + strlen(id) + 5]; 00225 sprintf(clientId, "d:%s:%s:%s", org, type, id); 00226 sprintf(subscription_url, "%s.%s/#/device/%s/sensor/", org, "internetofthings.ibmcloud.com",id); 00227 00228 // Network debug statements 00229 LOG("=====================================\n\r"); 00230 LOG("Connecting WiFi.\n\r"); 00231 LOG("Nucleo IP ADDRESS: %s\n\r", WiFi.get_ip_address()); 00232 LOG("Nucleo MAC ADDRESS: %s\n\r", WiFi.get_mac_address()); 00233 LOG("Server Hostname: %s port: %d\n\r", hostname, IBM_IOT_PORT); 00234 // for(int i = 0; clientId[i]; i++){ // set lowercase mac 00235 // clientId[i] = tolower(clientId[i]); 00236 // } 00237 LOG("Client ID: %s\n\r", clientId); 00238 LOG("Topic: %s\n\r",TOPIC); 00239 LOG("Subscription URL: %s\n\r", subscription_url); 00240 LOG("=====================================\n\r"); 00241 00242 netConnecting = true; 00243 ipstack->open(&ipstack->getWiFi()); 00244 int rc = ipstack->connect(hostname, IBM_IOT_PORT, connectTimeout); 00245 if (rc != 0) 00246 { 00247 WARN("IP Stack connect returned: %d\n", rc); 00248 return rc; 00249 } 00250 printf ("--->TCP Connected\n\r"); 00251 netConnected = true; 00252 netConnecting = false; 00253 00254 // MQTT Connect 00255 mqttConnecting = true; 00256 MQTTPacket_connectData data = MQTTPacket_connectData_initializer; 00257 data.MQTTVersion = 4; 00258 data.struct_version=0; 00259 data.clientID.cstring = clientId; 00260 00261 if (!quickstartMode) 00262 { 00263 data.username.cstring = "use-token-auth"; 00264 data.password.cstring = auth_token; 00265 } 00266 if ((rc = client->connect(data)) == 0) 00267 { 00268 connected = true; 00269 printf ("--->MQTT Connected\n\r"); 00270 #ifdef SUBSCRIBE 00271 if (!subscribe(client, ipstack)) printf ("--->>>MQTT subscribed to: %s\n\r",TOPIC); 00272 #endif 00273 } 00274 else { 00275 WARN("MQTT connect returned %d\n", rc); 00276 } 00277 if (rc >= 0) 00278 connack_rc = rc; 00279 mqttConnecting = false; 00280 return rc; 00281 } 00282 00283 int getConnTimeout(int attemptNumber) 00284 { // First 10 attempts try within 3 seconds, next 10 attempts retry after every 1 minute 00285 // after 20 attempts, retry every 10 minutes 00286 return (attemptNumber < 10) ? 3 : (attemptNumber < 20) ? 60 : 600; 00287 } 00288 00289 void attemptConnect(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00290 { 00291 connected = false; 00292 00293 while (connect(client, ipstack) != MQTT_CONNECTION_ACCEPTED) 00294 { 00295 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) { 00296 printf ("File: %s, Line: %d Error: %d\n\r",__FILE__,__LINE__, connack_rc); 00297 return; // don't reattempt to connect if credentials are wrong 00298 } 00299 int timeout = getConnTimeout(++retryAttempt); 00300 WARN("Retry attempt number %d waiting %d\n", retryAttempt, timeout); 00301 00302 // if ipstack and client were on the heap we could deconstruct and goto a label where they are constructed 00303 // or maybe just add the proper members to do this disconnect and call attemptConnect(...) 00304 // this works - reset the system when the retry count gets to a threshold 00305 if (retryAttempt == 5) 00306 NVIC_SystemReset(); 00307 else 00308 wait(timeout); 00309 } 00310 } 00311 00312 int publish(MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE>* client, MQTTWiFi* ipstack) 00313 { 00314 MQTT::Message message; 00315 char* pubTopic = TOPIC; 00316 00317 char buf[MQTT_MAX_PAYLOAD_SIZE]; 00318 float temp, press, hum; 00319 00320 LSM6DSL_Event_Status_t status; 00321 if (mems_event) { 00322 mems_event = 0; 00323 acc_gyro->get_event_status(&status); 00324 if (status.StepStatus) { 00325 /* New step detected, so print the step counter */ 00326 acc_gyro->get_step_counter(&step_count); 00327 printf("Step counter: %d\r\n", step_count); 00328 } 00329 00330 if (status.FreeFallStatus) { 00331 /* Output data. */ 00332 printf("Free Fall Detected!\r\n"); 00333 } 00334 00335 if (status.TapStatus) { 00336 /* Output data. */ 00337 printf("Single Tap Detected!\r\n"); 00338 } 00339 00340 if (status.DoubleTapStatus) { 00341 /* Output data. */ 00342 printf("Double Tap Detected!\r\n"); 00343 } 00344 00345 if (status.D6DOrientationStatus) { 00346 /* Send 6D Orientation */ 00347 send_orientation(); 00348 } 00349 00350 if (status.TiltStatus) { 00351 /* Output data. */ 00352 printf("Tilt Detected!\r\n"); 00353 } 00354 00355 if (status.WakeUpStatus) { 00356 /* Output data. */ 00357 printf("Wake Up Detected!\r\n"); 00358 } 00359 } 00360 00361 if (toggle_hw_event_enable) { 00362 toggle_hw_event_enable = 0; 00363 if (hw_event_is_enabled == 0) { 00364 /* Enable HW events. */ 00365 acc_gyro->enable_pedometer(); 00366 acc_gyro->enable_tilt_detection(); 00367 acc_gyro->enable_free_fall_detection(); 00368 acc_gyro->enable_single_tap_detection(); 00369 acc_gyro->enable_double_tap_detection(); 00370 acc_gyro->enable_6d_orientation(); 00371 acc_gyro->enable_wake_up_detection(); 00372 hw_event_is_enabled = 1; 00373 } else { 00374 acc_gyro->disable_pedometer(); 00375 acc_gyro->disable_tilt_detection(); 00376 acc_gyro->disable_free_fall_detection(); 00377 acc_gyro->disable_single_tap_detection(); 00378 acc_gyro->disable_double_tap_detection(); 00379 acc_gyro->disable_6d_orientation(); 00380 acc_gyro->disable_wake_up_detection(); 00381 hw_event_is_enabled = 0; 00382 } 00383 } 00384 00385 hum_temp->get_temperature(&temp); 00386 //press_temp->get_temperature(&temp); 00387 hum_temp->get_humidity(&hum); 00388 press_temp->get_pressure(&press); 00389 00390 sprintf(buf, 00391 "{\"d\":{\"ST\":\"Nucleo-IoT-mbed\",\"Temp\":%0.4f,\"Pressure\":%0.4f,\"Humidity\":%0.4f,\"FreeFall\":%i,\"DoubleTap\":%i,\"TiltStatus\":%i}}", 00392 temp, press, hum, status.FreeFallStatus, status.DoubleTapStatus, status.TiltStatus); 00393 message.qos = MQTT::QOS0; 00394 message.retained = false; 00395 message.dup = false; 00396 message.payload = (void*)buf; 00397 message.payloadlen = strlen(buf); 00398 00399 // LOG("Publishing %s\n\r", buf); 00400 printf("Publishing %s\n\r", buf); 00401 return client->publish(pubTopic, message); 00402 } 00403 00404 void initSensors(){ 00405 // A2 start 00406 uint8_t id; 00407 //float value1, value2; 00408 //char buffer1[32], buffer2[32]; 00409 //int32_t axes[3]; 00410 00411 /* Enable all sensors */ 00412 hum_temp->enable(); 00413 press_temp->enable(); 00414 magnetometer->enable(); 00415 accelerometer->enable(); 00416 acc_gyro->enable_x(); 00417 acc_gyro->enable_g(); 00418 00419 printf("\r\n--- Starting new run ---\r\n"); 00420 00421 hum_temp->read_id(&id); 00422 printf("HTS221 humidity & temperature = 0x%X\r\n", id); 00423 press_temp->read_id(&id); 00424 printf("LPS22HB pressure & temperature = 0x%X\r\n", id); 00425 magnetometer->read_id(&id); 00426 printf("LSM303AGR magnetometer = 0x%X\r\n", id); 00427 accelerometer->read_id(&id); 00428 printf("LSM303AGR accelerometer = 0x%X\r\n", id); 00429 acc_gyro->read_id(&id); 00430 printf("LSM6DSL accelerometer & gyroscope = 0x%X\r\n", id); 00431 00432 // A2 end 00433 } 00434 00435 00436 int main() 00437 { 00438 /* Attach callback to User button press */ 00439 mybutton.fall(&pressed_cb); 00440 /* Attach callback to LSM6DSL INT1 */ 00441 acc_gyro->attach_int1_irq(&int1_cb); 00442 /* Attach callback to LSM6DSL INT2 */ 00443 acc_gyro->attach_int2_irq(&int2_cb); 00444 00445 /* Enable LSM6DSL accelerometer */ 00446 acc_gyro->enable_x(); 00447 /* Enable HW events. */ 00448 acc_gyro->enable_pedometer(); 00449 acc_gyro->enable_tilt_detection(); 00450 acc_gyro->enable_free_fall_detection(); 00451 acc_gyro->enable_single_tap_detection(); 00452 acc_gyro->enable_double_tap_detection(); 00453 acc_gyro->enable_6d_orientation(); 00454 acc_gyro->enable_wake_up_detection(); 00455 00456 00457 00458 const char * ssid = SSID; // Network must be visible otherwise it can't connect 00459 const char * seckey = PASSW; 00460 SpwfSAInterface spwf(D8, D2, false); 00461 00462 // Timer tyeld; 00463 myled=0; 00464 DevI2C *i2c = new DevI2C(I2C_SDA, I2C_SCL); 00465 i2c->frequency(400000); 00466 00467 //X_NUCLEO_IKS01A2 00468 initSensors(); 00469 /* 00470 X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(i2c); 00471 pressure_sensor = mems_expansion_board->pt_sensor; 00472 temp_sensor1 = mems_expansion_board->ht_sensor; 00473 humidity_sensor = mems_expansion_board->ht_sensor; 00474 */ 00475 pc.printf("\r\nX-NUCLEO-IDW01M1 mbed Application\r\n"); 00476 pc.printf("\r\nconnecting to AP\r\n"); 00477 00478 quickstartMode=false; 00479 if (strcmp(org, "quickstart") == 0){quickstartMode = true;} 00480 MQTTWiFi ipstack(spwf, ssid, seckey, NSAPI_SECURITY_WPA2); 00481 MQTT::Client<MQTTWiFi, Countdown, MQTT_MAX_PACKET_SIZE> client(ipstack); 00482 if (quickstartMode){ 00483 char mac[50]; // remove all : from mac 00484 char *digit=NULL; 00485 sprintf (id,"%s", ""); 00486 sprintf (mac,"%s",ipstack.getWiFi().get_mac_address()); 00487 digit = strtok (mac,":"); 00488 while (digit != NULL) 00489 { 00490 strcat (id, digit); 00491 digit = strtok (NULL, ":"); 00492 } 00493 } 00494 attemptConnect(&client, &ipstack); 00495 if (connack_rc == MQTT_NOT_AUTHORIZED || connack_rc == MQTT_BAD_USERNAME_OR_PASSWORD) 00496 { 00497 while (true) 00498 wait(1.0); // Permanent failures - don't retry 00499 } 00500 #ifdef X_NUCLEO_NFC01A1_PRESENT 00501 // program NFC with broker URL 00502 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); 00503 NDefLib::NDefNfcTag& tag = nfcNucleo->getM24SR().getNDefTag(); 00504 printf("NFC Init done: !\r\n"); 00505 //open the i2c session with the nfc chip 00506 if(tag.openSession()){ 00507 //create the NDef message and record 00508 NDefLib::Message msg; 00509 NDefLib::RecordURI rUri(NDefLib::RecordURI::HTTPS, subscription_url); 00510 msg.addRecord(&rUri); 00511 //write the tag 00512 if(tag.write(msg)){ 00513 printf("Tag writed \r\n"); 00514 } 00515 //close the i2c session 00516 if(!tag.closeSession()){ 00517 printf("Error Closing the session\r\n"); 00518 } 00519 }else printf("Error open Session\r\n"); 00520 #endif 00521 myled=1; 00522 int count = 0; 00523 // tyeld.start(); 00524 while (true) 00525 { 00526 if (++count == 100) 00527 { // Publish a message every second 00528 if (publish(&client, &ipstack) != 0) { 00529 myled=0; 00530 attemptConnect(&client, &ipstack); // if we have lost the connection 00531 } else myled=1; 00532 count = 0; 00533 } 00534 // int start = tyeld.read_ms(); 00535 client.yield(10); // allow the MQTT client to receive messages 00536 // printf ("tyeld: %d\n\r",tyeld.read_ms()-start); 00537 } 00538 }
Generated on Fri Jul 15 2022 21:20:58 by
1.7.2