Sergey Vlasov / Mbed 2 deprecated MyDrive

Dependencies:   Watson-IoT-MQTT-WiFi-MEMS NDefLib NetworkSocketAPI X_NUCLEO_IDW01M1v2 X_NUCLEO_IKS01A2 mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }