Farnell-Element14 Bologna IOT Team / Mbed OS Smart_bin

Dependencies:   BSP_B-L475E-IOT01 MQTT

Fork of Multiprotocol by Farnell-Element14 Bologna IOT Team

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 // main.cpp
00002 #include <string>
00003 
00004 #include "mbed.h"
00005 #include "ISM43362Interface.h"
00006 #include "TCPSocket.h"
00007 //#include "HTS221Sensor.h"
00008 
00009 #include "thingsboard_account.h"
00010 // Sensors drivers present in the BSP library
00011 #include "stm32l475e_iot01_tsensor.h"
00012 #include "stm32l475e_iot01_hsensor.h"
00013 #include "stm32l475e_iot01_psensor.h"
00014 #include "stm32l475e_iot01_magneto.h"
00015 #include "stm32l475e_iot01_gyro.h"
00016 #include "stm32l475e_iot01_accelero.h"
00017 
00018 // laser driver
00019 //#include "lis3mdl_class.h"
00020 #include "VL53L0X.h"
00021 
00022 // H file per MQTT
00023 #include "MQTTmbed.h"
00024 #include "MQTTClient.h"
00025 
00026 // H file per COAP
00027 #include "sn_nsdl.h"
00028 #include "sn_coap_protocol.h"
00029 #include "sn_coap_header.h"
00030 
00031 // Definitions ---------------------------------------------------------
00032 
00033 // Change it with your WiFi network name
00034 //#define WIFI_NETWORK_NAME       "farnell_iot_lab"
00035 #define WIFI_NETWORK_NAME         "rucola"
00036 // Change it with your WiFi password name
00037 //#define WIFI_NETWORK_PASSWORD   "smartlab"
00038 #define WIFI_NETWORK_PASSWORD     "Rosmarino_10"
00039 
00040 #define WIFI_SECURITY             NSAPI_SECURITY_WPA_WPA2
00041 
00042 #define COMM_PROTO                2
00043 
00044 // scegliere il protocollo di trasporto dati
00045 // COMM_PROTO = 0 -> accesso MQTT (default);
00046 // COMM_PROTO = 1 -> access  HTTP;
00047 // COMM_PROTO = 2 -> accesso COAP;
00048 #ifndef COMM_PROTO
00049 #define COMM_PROTO 0
00050 #endif
00051 
00052 // scegliere il token al device
00053 #define DEVICE_ID                 1
00054 #define DEVICE_ACCESS_TOKEN       SMART_BIN_1_DEVICE_ACCESS_TOKEN
00055 
00056 //parametri rilevamento laser
00057 #define MIN_DISTANCE_OBSTACLE     80 //distanza di rilevamento in mm
00058 #define NUMBER_OF_OBSTACLE_FULL   3 //numero di letture per dichiarare il cestino pieno
00059 #define TILT_THRESHOLD            700 //valore di soglia per ribaltamento pari a sin(angolo)*1000
00060 
00061 // ciclo di frequenza lettura
00062 #define SENSOR_READING_PERIOD     5000 //in ms
00063 
00064 #if COMM_PROTO==0    //MQTT protocol
00065 
00066   #define MQTT_HOST               "demo.thingsboard.io"
00067   #define MQTT_PORT               1883
00068   #define MQTT_TOPIC              "v1/devices/me/telemetry"
00069   #define MQTT_MAX_MSG_LENGHT     500 //max mqtt lenght in byte
00070 
00071 #elif COMM_PROTO==1  //HTTP protocol
00072   #define HTTP_HOST               "demo.thingsboard.io"
00073   #define HTTP_PORT               80
00074   #define HTTP_STR_1              "/api/v1/"
00075   #define HTTP_STR_2              "/telemetry"
00076 
00077 #elif COMM_PROTO==2  //COAP protocol
00078   #define COAP_HOST               "demo.thingsboard.io"
00079   #define COAP_PORT               5683
00080   #define COAP_STR_1              "/api/v1/"
00081   #define COAP_STR_2              "/telemetry"
00082   
00083   #define SHOW_COAP_RESPONSE      false
00084 
00085 #endif              //end protocol
00086 
00087 // strutture comuni
00088 
00089 #if COMM_PROTO == 0
00090 class MQTTNetwork
00091 {
00092 public:
00093     MQTTNetwork(NetworkInterface* aNetwork) : network(aNetwork) {
00094         socket = new TCPSocket();
00095     }
00096 
00097     ~MQTTNetwork() {
00098         delete socket;
00099     }
00100 
00101     int read(unsigned char* buffer, int len, int timeout) {
00102         return socket->recv(buffer, len);
00103     }
00104 
00105     int write(unsigned char* buffer, int len, int timeout) {
00106         return socket->send(buffer, len);
00107     }
00108 
00109     int connect(const char* hostname, int port) {
00110         socket->open(network);
00111         return socket->connect(hostname, port);
00112     }
00113 
00114     int disconnect() {
00115         return socket->close();
00116     }
00117 
00118 private:
00119     NetworkInterface* network;
00120     TCPSocket* socket;
00121 };
00122 
00123 #elif COMM_PROTO==2  //COAP protocol
00124 UDPSocket socket;           // Socket to talk CoAP over
00125 Thread recvfromThread;      // Thread to receive messages over CoAP
00126 struct coap_s* coapHandle;
00127 coap_version_e coapVersion = COAP_VERSION_1;
00128 
00129 // CoAP HAL
00130 void* coap_malloc(uint16_t size) {
00131     return malloc(size);
00132 }
00133 
00134 void coap_free(void* addr) {
00135     free(addr);
00136 }
00137 
00138 // tx_cb and rx_cb are not used in this program
00139 uint8_t coap_tx_cb(uint8_t *a, uint16_t b, sn_nsdl_addr_s *c, void *d) {
00140     printf("coap tx cb\n");
00141     return 0;
00142 }
00143 
00144 int8_t coap_rx_cb(sn_coap_hdr_s *a, sn_nsdl_addr_s *b, void *c) {
00145     printf("coap rx cb\n");
00146     return 0;
00147 }
00148 
00149 
00150 #endif
00151 
00152 #ifdef TARGET_DISCO_L475VG_IOT01A
00153 
00154 static DevI2C devI2c(PB_11,PB_10);
00155 static DigitalOut shutdown_pin(PC_6);
00156 static VL53L0X range(&devI2c, &shutdown_pin, PC_7);
00157 
00158 #endif
00159 
00160 DigitalOut led(LED1);
00161 Serial pc(USBTX, USBRX); //use these pins for serial coms.
00162 int main()
00163 {
00164     
00165     bool blnTilted = false; // variabile per l'assetto del cestino
00166     bool blnIsFull=false;   // variabile per lo stato (pieno/vuoto) del cestino
00167     int LaserCountObstacle=0; //contatore di ostacoli rilevati dal laser
00168   
00169     int count = 0;
00170     pc.baud(115200);
00171 
00172     
00173 //initing sensori   
00174     float sensor_pressure_value = 0;
00175     float sensor_temperature_value = 0;
00176     float sensor_humidity_value = 0;
00177  
00178     int16_t pDataXYZ[3] = {0};
00179     //float pGyroDataXYZ[3] = {0};
00180   
00181     range.init_sensor(VL53L0X_DEFAULT_ADDRESS);
00182      
00183     BSP_TSENSOR_Init();
00184     BSP_HSENSOR_Init();
00185     BSP_PSENSOR_Init();
00186 
00187     //BSP_MAGNETO_Init();
00188     //BSP_GYRO_Init();
00189     BSP_ACCELERO_Init(); 
00190 
00191 //initing sensori   
00192     
00193     
00194     printf(" --- START SESSION ---\n");
00195     ISM43362Interface wifi(MBED_CONF_APP_WIFI_SPI_MOSI,
00196             MBED_CONF_APP_WIFI_SPI_MISO,
00197             MBED_CONF_APP_WIFI_SPI_SCLK,
00198             MBED_CONF_APP_WIFI_SPI_NSS,
00199             MBED_CONF_APP_WIFI_RESET,
00200             MBED_CONF_APP_WIFI_DATAREADY,
00201             MBED_CONF_APP_WIFI_WAKEUP, false);
00202 
00203     // Scanning WiFi networks ------------------------------------------
00204 
00205     WiFiAccessPoint *ap;
00206 
00207     count = wifi.scan(NULL, 0);
00208     printf("%d networks available.\n", count);
00209 
00210     /* Limit number of network arbitrary to 15 */
00211     count = count < 15 ? count : 15;
00212 
00213     ap = new WiFiAccessPoint[count];
00214     count = wifi.scan(ap, count);
00215     for (int i = 0; i < count; i++) {
00216         printf("Network: %s RSSI: %hhd\n", ap[i].get_ssid(), ap[i].get_rssi());
00217     }
00218 
00219     delete[] ap;
00220 
00221     // Connecting to WiFi network --------------------------------------
00222 
00223     printf("\nConnecting to %s...\n", WIFI_NETWORK_NAME);
00224     int ret = wifi.connect(WIFI_NETWORK_NAME, WIFI_NETWORK_PASSWORD, WIFI_SECURITY);
00225     if (ret != 0) {
00226         printf("\nConnection error\n");
00227         return -1;
00228     }
00229 
00230     printf("Success\n\n");
00231     printf("MAC: %s\n", wifi.get_mac_address());
00232     printf("IP: %s\n", wifi.get_ip_address());
00233     printf("Netmask: %s\n", wifi.get_netmask());
00234     printf("Gateway: %s\n", wifi.get_gateway());
00235     printf("RSSI: %d\n\n", wifi.get_rssi());
00236 
00237 #if COMM_PROTO == 0  //MQTT
00238     printf("Collegamento MQTT server: " MQTT_HOST  "\n");
00239 
00240     MQTTNetwork network(&wifi);
00241     MQTT::Client<MQTTNetwork, Countdown,MQTT_MAX_MSG_LENGHT> client(network); // attenzione alla MAX DIM MSG MQTT
00242 
00243     char assess_token[] = DEVICE_ACCESS_TOKEN;
00244 
00245     MQTTPacket_connectData conn_data = MQTTPacket_connectData_initializer;
00246     conn_data.username.cstring = assess_token;
00247 
00248     if (network.connect(MQTT_HOST, MQTT_PORT) < 0) {
00249       printf("failed to connect to " MQTT_HOST  "\n");
00250       return -1;
00251     }
00252 
00253     if (client.connect(conn_data) < 0) {
00254       printf("failed to send MQTT connect message\n");
00255       return -1;
00256     }
00257 
00258     printf("successfully connect to MQTT server!\n");
00259 
00260 #elif COMM_PROTO == 1  //HTTP
00261 
00262     printf("Collegamento HTTP server: " HTTP_HOST  "\n");
00263     TCPSocket socket;
00264     nsapi_error_t response;
00265 
00266     // Open a socket on the network interface, and create a TCP connection 
00267     socket.open(&wifi);
00268     response = socket.connect(HTTP_HOST, HTTP_PORT);
00269     if(0 != response) {
00270         printf("Error connecting: %d\n", response);
00271         socket.close();
00272         return -1;
00273     }
00274     socket.close();
00275 #elif COMM_PROTO == 2 // COAP
00276     
00277     //inserire un test di invio dati al server coap
00278 
00279 
00280 #endif
00281 
00282 // Initialize sensors --------------------------------------------------
00283 /*
00284     DevI2C i2c_2(PB_11, PB_10);
00285     HTS221Sensor hum_temp(&i2c_2);
00286 
00287     hum_temp.init(NULL);
00288     hum_temp.enable();
00289     hum_temp.read_id(&id);
00290     printf("HTS221  humidity & temperature sensor = 0x%X\r\n", id);
00291 */
00292 // Variabili di appoggio  -----------------------------------------------
00293 #if COMM_PROTO == 1
00294     uint8_t http_request[1024];   
00295     char request_body[256];
00296     static   uint8_t http_resp[512];
00297     uint16_t reqLen;
00298     uint16_t respLen;
00299 
00300 #elif COMM_PROTO == 2 // COAP
00301     char coap_body[256];
00302     char coap_uri_path[256];
00303     uint16_t coap_message_id;
00304     coap_message_id=0;
00305     
00306 
00307 #endif
00308 
00309 
00310 
00311 
00312 // ciclo di lettura sensori e caricamento su cloud       
00313 for (;;) {
00314 /*   
00315    
00316     float temp, humid;
00317 
00318     hum_temp.get_temperature(&temp);
00319     hum_temp.get_humidity(&humid);
00320     
00321     printf("ID: %d HTS221:  [temp] %.2f C, [hum]   %.2f%%\r\n", DEVICE_ID,temp, humid);
00322 */
00323 
00324     sensor_temperature_value = BSP_TSENSOR_ReadTemp();
00325     printf("TEMPERATURE: %.2f degC\n", sensor_temperature_value);
00326 
00327     sensor_humidity_value = BSP_HSENSOR_ReadHumidity();
00328     printf("HUMIDITY   : %.2f %%\n", sensor_humidity_value);
00329 
00330     sensor_pressure_value = BSP_PSENSOR_ReadPressure();
00331     printf("PRESSURE   : %.2f mBar\n", sensor_pressure_value);
00332     
00333     BSP_ACCELERO_AccGetXYZ(pDataXYZ);
00334     printf("ACCELERO_X : %d\n", pDataXYZ[0]);
00335     //printf("ACCELERO_Y = %d\n", pDataXYZ[1]);
00336     //printf("ACCELERO_Z = %d\n", pDataXYZ[2]);
00337 
00338     uint32_t distance;
00339 
00340     int status = range.get_distance(&distance);
00341     if (status == VL53L0X_ERROR_NONE) {
00342         printf("VL53L0X [mm]: %6ld\n", distance);
00343     } else {
00344         printf("VL53L0X [mm]: --\n");
00345     }
00346     if (abs(pDataXYZ[0]) < TILT_THRESHOLD)  {
00347         blnTilted = true;
00348     }  else {
00349         blnTilted = false;
00350     } //controllo inclinazione
00351 
00352     if (status == VL53L0X_ERROR_NONE && distance<=MIN_DISTANCE_OBSTACLE && LaserCountObstacle < NUMBER_OF_OBSTACLE_FULL){
00353         LaserCountObstacle++;
00354     } else if (status == VL53L0X_ERROR_NONE && distance>MIN_DISTANCE_OBSTACLE && LaserCountObstacle>0){
00355         LaserCountObstacle--;
00356     } //controllo distanza ostacolo
00357     
00358     if (LaserCountObstacle>=NUMBER_OF_OBSTACLE_FULL){
00359         blnIsFull = true;
00360     } else if (LaserCountObstacle == 0) {
00361         blnIsFull = false;
00362     }
00363     printf("laser counter: %d\n",LaserCountObstacle);
00364 
00365    
00366 #if COMM_PROTO == 0
00367     char msg[256];  
00368 
00369 
00370     int n = snprintf(msg, sizeof(msg),
00371         "{\"ID\":%d,\"temperature\":%f, \"humidity\":%f, \"pressure\":%f, \"IsTilted\":%d, \"IsFull\":%d}",
00372         DEVICE_ID,sensor_temperature_value, sensor_humidity_value,sensor_pressure_value,blnTilted,blnIsFull);
00373     printf("messaggio: %s\n",msg);
00374 
00375     void *payload = reinterpret_cast<void*>(msg);
00376     size_t payload_len = n;
00377     printf("Message payload lenght: %d\r\n",payload_len);
00378     printf("publish to: %s %d %s\r\n", MQTT_HOST, MQTT_PORT, MQTT_TOPIC);
00379     if (client.publish(MQTT_TOPIC, payload, n) < 0) {
00380         printf("-- ERROR -- :failed to publish MQTT message\n");
00381     }
00382   
00383 #elif COMM_PROTO == 1
00384     // ciclo di scrittura su socket
00385     // - open
00386     // - connect
00387     // - send 
00388     // - close
00389    
00390     socket.open(&wifi);
00391     response = socket.connect(HTTP_HOST, HTTP_PORT);
00392     if(0 != response) {
00393         printf("Error connecting: %d\n", response);
00394         socket.close();
00395         return -1;
00396     }
00397         
00398         
00399     // body of the request
00400 
00401     sprintf(request_body, "{\"ID\":%d,\"temperature\":%f, \"humidity\":%f, \"pressure\":%f, \"IsTilted\":%d, \"IsFull\":%d}",
00402         DEVICE_ID,sensor_temperature_value, sensor_humidity_value,sensor_pressure_value,blnTilted,blnIsFull);
00403 
00404     printf("messaggio: %s\r\n",request_body);
00405 
00406 
00407     // build header of the request
00408     sprintf((char *)http_request, "POST %s%s%s HTTP/1.1\r\nHost: %s \r\n", HTTP_STR_1,DEVICE_ACCESS_TOKEN,HTTP_STR_2, HTTP_HOST);
00409     strcat((char *)http_request, "Accept: */*\r\n");
00410     strcat((char *)http_request, "User-agent: ST-475-IOT\r\n");
00411     strcat((char *)http_request, "Connection: Close\r\n"); 
00412     char buffer[64];
00413     strcat((char *)http_request, "Content-Type: application/json\r\n");
00414     sprintf(buffer, "Content-Length: %d \r\n", strlen(request_body));
00415     strcat((char *)http_request, buffer);
00416 
00417     // append body to the header of the request
00418     strcat((char *)http_request, request_body);
00419     reqLen = strlen((char *)http_request);
00420     printf((char *)http_request);
00421 
00422     // Send a simple http request
00423     
00424     nsapi_size_t size = strlen((char *)http_request);
00425     response = 0;
00426     
00427     while(size)
00428     {
00429         response = socket.send(((char *)http_request)+response, size);
00430         
00431         if (response < 0) {
00432             printf("Error sending data: %d\n", response);
00433             socket.close();
00434             return -1;
00435         } else {
00436             size -= response;
00437             // Check if entire message was sent or not
00438             printf("sent %d [%.*s]\n", response, strstr((char *)http_request, "\r\n")-(char *)http_request, (char *)http_request);
00439         }
00440     }
00441     // pulizia risorse della socket
00442     socket.close();        
00443         
00444 #elif COMM_PROTO == 2 //COAP              
00445    
00446 
00447     // Open a socket on the network interface
00448     socket.open(&wifi);
00449 
00450     // Initialize the CoAP protocol handle, pointing to local implementations on malloc/free/tx/rx functions
00451     coapHandle = sn_coap_protocol_init(&coap_malloc, &coap_free, &coap_tx_cb, &coap_rx_cb);
00452 
00453 
00454     // Path to the resource we want to retrieve
00455     sprintf(coap_uri_path, "%s%s%s", COAP_STR_1,DEVICE_ACCESS_TOKEN,COAP_STR_2);
00456     sprintf(coap_body, "{\"ID\":%d,\"temperature\":%f, \"humidity\":%f, \"pressure\":%f, \"IsTilted\":%d, \"IsFull\":%d}",
00457         DEVICE_ID,sensor_temperature_value, sensor_humidity_value,sensor_pressure_value,blnTilted,blnIsFull);
00458 
00459     printf ("URI PATH: %s\n",coap_uri_path);
00460     printf ("BODY: %s\n",coap_body);
00461     printf ("id: %d\n",coap_message_id);
00462 
00463     // See ns_coap_header.h
00464     sn_coap_hdr_s *coap_res_ptr = (sn_coap_hdr_s*)calloc(sizeof(sn_coap_hdr_s), 1);
00465     coap_res_ptr->uri_path_ptr = (uint8_t*)coap_uri_path;       // Path
00466     coap_res_ptr->uri_path_len = strlen(coap_uri_path);
00467     coap_res_ptr->msg_type = COAP_MSG_TYPE_NON_CONFIRMABLE;
00468     coap_res_ptr->msg_code = COAP_MSG_CODE_REQUEST_POST;         // CoAP method
00469     coap_res_ptr->content_format = COAP_CT_JSON;          // CoAP content type
00470     coap_res_ptr->payload_len = strlen(coap_body);                              // Body length
00471     coap_res_ptr->payload_ptr = (uint8_t*)coap_body;                              // Body pointer
00472     coap_res_ptr->options_list_ptr = 0;                         // Optional: options list
00473     coap_res_ptr->msg_id = coap_message_id;  //msg ID, don't forget to increase it
00474     coap_message_id++;
00475     
00476     // Calculate the CoAP message size, allocate the memory and build the message
00477     uint16_t message_len = sn_coap_builder_calc_needed_packet_data_size(coap_res_ptr);
00478     printf("Calculated message length: %d bytes\n", message_len);
00479 
00480     uint8_t* message_ptr = (uint8_t*)malloc(message_len);
00481     sn_coap_builder(message_ptr, coap_res_ptr);
00482 
00483     // Uncomment to see the raw buffer that will be sent...
00484      printf("Message is: ");
00485      for (size_t ix = 0; ix < message_len; ix++) {
00486          printf("%02x ", message_ptr[ix]);
00487      }
00488      printf("\n");
00489 
00490     int scount = socket.sendto(COAP_HOST, COAP_PORT, message_ptr, message_len);
00491     printf("Sent %d bytes to coap://%s:%d\n", scount,COAP_HOST, COAP_PORT);
00492 
00493 // routine di ricezione    
00494 #if SHOW_COAP_RESPONSE == true
00495     SocketAddress addr;
00496     uint8_t* recv_buffer = (uint8_t*)malloc(1280); // Suggested is to keep packet size under 1280 bytes
00497     
00498     if ((ret = socket.recvfrom(&addr, recv_buffer, 1280)) >= 0) {
00499         // to see where the message came from, inspect addr.get_addr() and addr.get_port()
00500   
00501         printf("Received packets from (%s,%d)\n", addr.get_ip_address(),addr.get_port());
00502 
00503         sn_coap_hdr_s* parsed = sn_coap_parser(coapHandle, ret, recv_buffer, &coapVersion);
00504 
00505         // We know the payload is going to be a string
00506         std::string payload((const char*)parsed->payload_ptr, parsed->payload_len);
00507 
00508         printf("\tmsg_id:           %d\n", parsed->msg_id);
00509         printf("\tmsg_code:         %d\n", parsed->msg_code);
00510         printf("\tcontent_format:   %d\n", parsed->content_format);
00511         printf("\tpayload_len:      %d\n", parsed->payload_len);
00512         printf("\tpayload:          %s\n", payload.c_str());
00513         printf("\toptions_list_ptr: %p\n", parsed->options_list_ptr);
00514     }
00515 
00516     free(recv_buffer);  
00517  
00518 
00519 #endif //end SHOW_COAP_RESPONSE   
00520     socket.close();
00521     sn_coap_protocol_destroy(coapHandle);
00522     free(coap_res_ptr);
00523     free(message_ptr);
00524 
00525      
00526 #endif //end protocol selection
00527 
00528 
00529     wait_ms(SENSOR_READING_PERIOD);
00530 }
00531 
00532 //le disconnect non vengono raggiunte perche' rimaniamo all'interno del ciclo
00533 //client.disconnect();
00534 //wifi.disconnect();
00535 
00536 //printf("\ndone\n");
00537 //return 0;
00538 
00539 }