
Lora Personalized device for Everynet
Dependencies: LMiCPersonalizedforEverynet SX1276Lib X_NUCLEO_IKS01A1 cantcoap lwip mbed-rtos mbed
Fork of LoRaWAN-test-10secs by
main.cpp
00001 /* 00002 / _____) _ | | 00003 ( (____ _____ ____ _| |_ _____ ____| |__ 00004 \____ \| ___ | (_ _) ___ |/ ___) _ \ 00005 _____) ) ____| | | || |_| ____( (___| | | | 00006 (______/|_____)_|_|_| \__)_____)\____)_| |_| 00007 (C)2015 Semtech 00008 00009 Description: MBED LoRaWAN example application 00010 00011 License: Revised BSD License, see LICENSE.TXT file include in the project 00012 00013 Maintainer: Miguel Luis and Gregory Cristian 00014 */ 00015 00016 #include <cstdio> 00017 #include <string> 00018 #include <cassert> 00019 00020 #include "mbed.h" 00021 //#include "Node.h" 00022 #include "cantcoap.h" 00023 #include "x_nucleo_iks01a1.h" 00024 #include "rtos.h" 00025 00026 #include "lmic.h" 00027 #include "debug.h" 00028 00029 /* Instantiate the expansion board */ 00030 static X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(D14, D15); 00031 00032 /* Retrieve the composing elements of the expansion board */ 00033 static GyroSensor *gyroscope = mems_expansion_board->GetGyroscope(); 00034 static MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer(); 00035 static MagneticSensor *magnetometer = mems_expansion_board->magnetometer; 00036 static HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor; 00037 static PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor; 00038 static TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor; 00039 static TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor; 00040 00041 uint8_t id; 00042 float value1, value2; 00043 char buffer1[32], buffer2[32], buffer3[32]; 00044 int32_t axes[3]; 00045 00046 static bool temp_sent = false; 00047 static bool hum_sent = false; 00048 static bool press_sent = false; 00049 static bool gyro_sent = false; 00050 static bool motion_sent = false; 00051 static bool magn_sent = false; 00052 00053 const std::string REGISTRATION_SEGMENT ="/rd"; 00054 const std::string ENDPOINT_SEGMENT = "?ep="; 00055 const std::string LIFETIME ="<="; 00056 const std::string BINDING ="&b="; 00057 00058 const std::string REGISTRATION_OPEN = "<"; 00059 const std::string REGISTRATION_CLOSE = ">"; 00060 const std::string REGISTRATION_SEPARATOR ="/"; 00061 00062 int _node_Id=0; 00063 00064 const std::string endPoint_Name = "loraDevice"; 00065 const int lifeTime = 300; 00066 const std::string binding = "U"; 00067 00068 unsigned char * _payload; 00069 long _payload_size; 00070 00071 /*! 00072 * When set to 1 the application uses the Over-the-Air activation procedure 00073 * When set to 0 the application uses the Personalization activation procedure 00074 */ 00075 #define OVER_THE_AIR_ACTIVATION 0 00076 00077 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00078 00079 /*! 00080 * Defines the network ID when using personalization activation procedure 00081 */ 00082 #define LORAWAN_NET_ID ( uint32_t )0x00000000 00083 00084 /*! 00085 * Defines the device address when using personalization activation procedure 00086 */ 00087 //To be changed when switching from one to another 00088 #define LORAWAN_DEV_ADDR ( uint32_t )0x12342222 00089 00090 #endif 00091 00092 /*! 00093 * Defines the application data transmission duty cycle 00094 */ 00095 //#define APP_TX_DUTYCYCLE 5000 // 5 [s] value in ms 00096 //PANY 00097 #define APP_TX_DUTYCYCLE 1000 // 1 [s] value in ms 00098 //PANY 00099 #define APP_TX_DUTYCYCLE_RND 1000 // 1 [s] value in ms 00100 00101 /*! 00102 * LoRaWAN Adaptative Data Rate 00103 */ 00104 #define LORAWAN_ADR_ON 1 00105 00106 /*! 00107 * LoRaWAN confirmed messages 00108 */ 00109 #define LORAWAN_CONFIRMED_MSG_ON 0 00110 00111 /*! 00112 * LoRaWAN application port 00113 */ 00114 #define LORAWAN_APP_PORT 15 00115 00116 /*! 00117 * User application data buffer size 00118 */ 00119 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00120 #define LORAWAN_APP_DATA_SIZE 6 00121 00122 #else 00123 #define LORAWAN_APP_DATA_SIZE 1 00124 00125 #endif 00126 00127 #define UINT16_MAX (65535U) 00128 #define UINT64_MAX (18446744073709551615ULL) 00129 00130 //Node lwm2mNode("LR-test0");; 00131 unsigned int LoRaWAN_data_size = 0; 00132 00133 /* Helper function for printing floats & doubles */ 00134 static char *printDouble(char* str, double v, int decimalDigits=2) 00135 { 00136 int i = 1; 00137 int intPart, fractPart; 00138 int len; 00139 char *ptr; 00140 00141 /* prepare decimal digits multiplicator */ 00142 for (;decimalDigits!=0; i*=10, decimalDigits--); 00143 00144 /* calculate integer & fractinal parts */ 00145 intPart = (int)v; 00146 fractPart = (int)((v-(double)(int)v)*i); 00147 00148 /* fill in integer part */ 00149 sprintf(str, "%i.", intPart); 00150 00151 /* prepare fill in of fractional part */ 00152 len = strlen(str); 00153 ptr = &str[len]; 00154 00155 /* fill in leading fractional zeros */ 00156 for (i/=10;i>1; i/=10, ptr++) { 00157 if(fractPart >= i) break; 00158 *ptr = '0'; 00159 } 00160 00161 /* fill in (rest of) fractional part */ 00162 sprintf(ptr, "%i", fractPart); 00163 00164 return str; 00165 } 00166 00167 /* Helper function for printing integers */ 00168 static char *printInt(char* str, int v) 00169 { 00170 /* fill in integer part */ 00171 sprintf(str, "%i", v); 00172 00173 return str; 00174 } 00175 00176 /* Thread for calling libNsdl exec function (cleanup, resendings etc..) */ 00177 /* Node updates accelerometer every 60 seconds. Notification sending is done here. */ 00178 static void exec_call_thread(void const *args) 00179 { 00180 uint8_t id; 00181 float value1, value2; 00182 char buffer1[32], buffer2[32]; 00183 int32_t axes[3]; 00184 00185 debug_str("--- Starting new run ---\r\n"); 00186 00187 humidity_sensor->ReadID(&id); 00188 debug_str("HTS221 humidity & temperature = "); 00189 debug_uint(id); 00190 debug_str("\r\n"); 00191 pressure_sensor->ReadID(&id); 00192 debug_str("LPS25H pressure & temperature = "); 00193 debug_uint(id); 00194 debug_str("\r\n"); 00195 magnetometer->ReadID(&id); 00196 debug_str("LIS3MDL magnetometer = "); 00197 debug_uint(id); 00198 debug_str("\r\n"); 00199 gyroscope->ReadID(&id); 00200 debug_str("LSM6DS0 accelerometer & gyroscope = "); 00201 debug_uint(id); 00202 debug_str("\r\n"); 00203 00204 wait(3); 00205 00206 while(1) { 00207 debug_str("\r\n"); 00208 00209 temp_sensor1->GetTemperature(&value1); 00210 humidity_sensor->GetHumidity(&value2); 00211 debug_str("HTS221: [temp] "); 00212 debug_str(printDouble(buffer1, value1)); 00213 debug_str("°C, [hum] "); 00214 debug_str(printDouble(buffer2, value2)); 00215 debug_str("%\r\n"); 00216 //pc.printf("HTS221: [temp] %7s°C, [hum] %s%%\r\n", printDouble(buffer1, value1), printDouble(buffer2, value2)); 00217 00218 temp_sensor2->GetFahrenheit(&value1); 00219 pressure_sensor->GetPressure(&value2); 00220 debug_str("LPS25H: [temp] "); 00221 debug_str(printDouble(buffer1, value1)); 00222 debug_str("°F, [press] "); 00223 debug_str(printDouble(buffer2, value2)); 00224 debug_str("mbar\r\n"); 00225 //pc.printf("LPS25H: [temp] %7s°F, [press] %smbar\r\n", printDouble(buffer1, value1), printDouble(buffer2, value2)); 00226 00227 debug_str("---\r\n"); 00228 00229 magnetometer->Get_M_Axes(axes); 00230 debug_str("LIS3MDL [mag/mgauss]: "); 00231 debug_uint(axes[0]); 00232 debug_str(", "); 00233 debug_uint(axes[1]); 00234 debug_str(", "); 00235 debug_uint(axes[2]); 00236 debug_str("\r\n"); 00237 //pc.printf("LIS3MDL [mag/mgauss]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00238 00239 accelerometer->Get_X_Axes(axes); 00240 debug_str("LSM6DS0 [acc/mg]: "); 00241 debug_uint(axes[0]); 00242 debug_str(", "); 00243 debug_uint(axes[1]); 00244 debug_str(", "); 00245 debug_uint(axes[2]); 00246 debug_str("\r\n"); 00247 //pc.printf("LSM6DS0 [acc/mg]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00248 00249 gyroscope->Get_G_Axes(axes); 00250 debug_str("LSM6DS0 [gyro/mdps]: "); 00251 debug_uint(axes[0]); 00252 debug_str(", "); 00253 debug_uint(axes[1]); 00254 debug_str(", "); 00255 debug_uint(axes[2]); 00256 debug_str("\r\n"); 00257 //pc.printf("LSM6DS0 [gyro/mdps]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00258 00259 wait(1.5); 00260 } 00261 } 00262 00263 std::string to_string( int x ) { 00264 int length = snprintf( NULL, 0, "%d", x ); 00265 //assert( length >= 0 ); 00266 char* buf = new char[length + 1]; 00267 snprintf( buf, length + 1, "%d", x ); 00268 std::string str( buf ); 00269 delete[] buf; 00270 return str; 00271 } 00272 00273 unsigned char * get_Registration_Payload(long *payload_size){ 00274 00275 string registration_Payload =""; 00276 00277 string s=""; 00278 00279 s.append(REGISTRATION_OPEN); 00280 s.append(REGISTRATION_SEPARATOR); 00281 s.append("3/0/0"); 00282 s.append(REGISTRATION_CLOSE); 00283 s.append(","); 00284 s.append(REGISTRATION_OPEN); 00285 s.append(REGISTRATION_SEPARATOR); 00286 s.append("3/0/1"); 00287 s.append(REGISTRATION_CLOSE); 00288 s.append(","); 00289 s.append(REGISTRATION_OPEN); 00290 s.append(REGISTRATION_SEPARATOR); 00291 s.append("3/0/2"); 00292 s.append(REGISTRATION_CLOSE); 00293 00294 registration_Payload.append(s); 00295 00296 unsigned char *c = new unsigned char[registration_Payload.size()+1]; 00297 copy(registration_Payload.begin(),registration_Payload.end(),c); 00298 c[registration_Payload.size()]='\0'; 00299 *payload_size=registration_Payload.size(); 00300 00301 return c; 00302 00303 } 00304 uint8_t * get_Token(int * size){ 00305 srand(time(0)+_node_Id); 00306 long test=0; 00307 bool exist=false; 00308 00309 do{ 00310 test=(rand() % UINT64_MAX); 00311 00312 }while (exist==true); 00313 uint8_t ones = 0xFF; 00314 *size=1; 00315 for (int i=0; i<8; ++i) { 00316 if ( (test>>8*i & ones) =='\0' || i==8) { 00317 *size=i; 00318 break; 00319 } 00320 } 00321 uint8_t * token =new uint8_t[*size]; 00322 for (int i=0; i<*size; ++i){ 00323 token[*size-1-i]=test>>8*i & ones; 00324 } 00325 return token; 00326 } 00327 00328 uint16_t get_Message_ID(){ 00329 srand(time(0)+_node_Id); 00330 int test=0; 00331 bool exist=false; 00332 do{ 00333 00334 exist=false; 00335 test=(rand() % UINT16_MAX); 00336 00337 }while (exist==true); 00338 00339 00340 return (uint16_t) test; 00341 00342 } 00343 00344 char * get_Registration_Query(){ 00345 00346 string buffer; 00347 buffer.append(REGISTRATION_SEGMENT); 00348 buffer.append(ENDPOINT_SEGMENT); 00349 buffer.append(endPoint_Name); 00350 buffer.append(LIFETIME); 00351 buffer.append(to_string(lifeTime)); 00352 buffer.append(BINDING); 00353 buffer.append(binding); 00354 00355 char *c = new char[buffer.size()+1]; 00356 copy(buffer.begin(),buffer.end(),c); 00357 c[buffer.size()]='\0'; 00358 return c; 00359 00360 00361 } 00362 00363 ////////////////////////////////////////////////// 00364 // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW) 00365 ////////////////////////////////////////////////// 00366 00367 // application router ID (LSBF) 00368 //To be changed when switching from one to another 00369 static const uint8_t AppEui[8] = 00370 { 00371 // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 00372 0x01, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 00373 }; 00374 00375 // unique device ID (LSBF) 00376 //To be changed when switching from one to another 00377 static const u1_t DevEui[8] = 00378 { 00379 0x33, 0x74, 0x73, 0x65, 0x74, 0x2D, 0x52, 0x4C // 4c522d7465737433 = "LR-test3" 00380 }; 00381 00382 // device-specific AES key (derived from device EUI) 00383 static const uint8_t DevKey[16] = 00384 { 00385 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 00386 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3E 00387 }; 00388 00389 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00390 // network session key 00391 //To be changed when switching from one to another 00392 static uint8_t NwkSKey[] = 00393 { 00394 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 00395 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3E 00396 }; 00397 00398 // application session key 00399 //To be changed when switching from one to another 00400 static uint8_t ArtSKey[] = 00401 { 00402 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 00403 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3E 00404 }; 00405 00406 #endif 00407 00408 // LEDs and Frame jobs 00409 osjob_t rxLedJob; 00410 osjob_t txLedJob; 00411 osjob_t sendFrameJob; 00412 00413 // LED state 00414 static bool AppLedStateOn = false; 00415 00416 ////////////////////////////////////////////////// 00417 // Utility functions 00418 ////////////////////////////////////////////////// 00419 /*! 00420 * \brief Computes a random number between min and max 00421 * 00422 * \param [IN] min range minimum value 00423 * \param [IN] max range maximum value 00424 * \retval random random value in range min..max 00425 */ 00426 int32_t randr( int32_t min, int32_t max ) 00427 { 00428 return ( int32_t )rand( ) % ( max - min + 1 ) + min; 00429 } 00430 00431 ////////////////////////////////////////////////// 00432 // APPLICATION CALLBACKS 00433 ////////////////////////////////////////////////// 00434 00435 // provide application router ID (8 bytes, LSBF) 00436 void os_getArtEui( uint8_t *buf ) 00437 { 00438 memcpy( buf, AppEui, 8 ); 00439 } 00440 00441 // provide device ID (8 bytes, LSBF) 00442 void os_getDevEui( uint8_t *buf ) 00443 { 00444 memcpy( buf, DevEui, 8 ); 00445 } 00446 00447 // provide device key (16 bytes) 00448 void os_getDevKey( uint8_t *buf ) 00449 { 00450 memcpy( buf, DevKey, 16 ); 00451 } 00452 00453 ////////////////////////////////////////////////// 00454 // MAIN - INITIALIZATION AND STARTUP 00455 ////////////////////////////////////////////////// 00456 00457 static void onRxLed( osjob_t* j ) 00458 { 00459 // debug_val("LED2 = ", 0 ); 00460 } 00461 00462 static void onTxLed( osjob_t* j ) 00463 { 00464 // debug_val("LED1 = ", 0 ); 00465 } 00466 00467 static void prepareTxCoapFrame( void ) 00468 { 00469 // Create Registration PDU : 00470 00471 CoapPDU *pdu = new CoapPDU(); 00472 00473 pdu->setCode(CoapPDU::COAP_POST); 00474 pdu->setType(CoapPDU::COAP_CONFIRMABLE); 00475 int size; 00476 uint8_t * token = get_Token(&size); 00477 pdu->setToken(token,size); 00478 pdu->setMessageID(get_Message_ID()); 00479 pdu->setURI(get_Registration_Query()); 00480 00481 _payload=get_Registration_Payload(&_payload_size); 00482 pdu->setPayload(_payload, (int) _payload_size); 00483 int PDUlength = pdu->getPDULength(); 00484 00485 // strncpy((char*) LMIC.frame, (const char*)pdu->getPDUPointer(), PDUlength); 00486 memcpy(LMIC.frame, pdu->getPDUPointer(), PDUlength * sizeof(uint8_t)); 00487 00488 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00489 LMIC.frame[PDUlength] = LMIC.seqnoDn >> 8; 00490 LMIC.frame[PDUlength+1] = LMIC.seqnoDn; 00491 LMIC.frame[PDUlength+2] = LMIC.rssi >> 8; 00492 LMIC.frame[PDUlength+3] = LMIC.rssi; 00493 LMIC.frame[PDUlength+4] = LMIC.snr; 00494 #endif 00495 debug_str("Frame to be sent: "); 00496 debug_buf(LMIC.frame, PDUlength + 5); 00497 00498 LoRaWAN_data_size = PDUlength + 5; 00499 } 00500 00501 static void prepareTxLoraFrame( void ) 00502 { 00503 const char *frame = "LoRa"; 00504 // const char *frame = "Test"; 00505 00506 strncpy((char*) LMIC.frame, frame, strlen(frame)); 00507 00508 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00509 LMIC.frame[strlen(frame)] = LMIC.seqnoDn >> 8; 00510 LMIC.frame[strlen(frame)+1] = LMIC.seqnoDn; 00511 LMIC.frame[strlen(frame)+2] = LMIC.rssi >> 8; 00512 LMIC.frame[strlen(frame)+3] = LMIC.rssi; 00513 LMIC.frame[strlen(frame)+4] = LMIC.snr; 00514 #endif 00515 debug_str("Frame to be sent: "); 00516 // debug_buf(LMIC.frame, strlen(frame) + 5); 00517 debug_buf(LMIC.frame, strlen(frame)); 00518 00519 // LoRaWAN_data_size = strlen(frame) + 5; 00520 LoRaWAN_data_size = strlen(frame); 00521 } 00522 00523 static void prepareTxSensorsFrame( void ) 00524 { 00525 std::string frame = ""; 00526 std::string tmp; 00527 // debug_str("\r\n"); 00528 00529 temp_sensor1->GetTemperature(&value1); 00530 humidity_sensor->GetHumidity(&value2); 00531 printDouble(buffer1, value1); 00532 // debug_str("HTS221: [temp] "); 00533 // debug_str(printDouble(buffer1, value1)); 00534 tmp = "0,"; 00535 tmp += buffer1; 00536 tmp += ","; 00537 00538 if ((!temp_sent) && (frame.length() + tmp.length() < 50)) 00539 { 00540 temp_sent = true; 00541 frame += tmp; 00542 } 00543 printDouble(buffer2, value2); 00544 // debug_str("Celsius, [hum] "); 00545 // debug_str(printDouble(buffer2, value2)); 00546 tmp = "1,"; 00547 tmp += buffer2; 00548 tmp += ","; 00549 00550 if ((!hum_sent) && (frame.length() + tmp.length() < 50)) 00551 { 00552 hum_sent = true; 00553 frame += tmp; 00554 } 00555 00556 // debug_str("%\r\n"); 00557 //pc.printf("HTS221: [temp] %7s°C, [hum] %s%%\r\n", printDouble(buffer1, value1), printDouble(buffer2, value2)); 00558 00559 temp_sensor2->GetFahrenheit(&value1); 00560 pressure_sensor->GetPressure(&value2); 00561 printDouble(buffer1, value1); 00562 printDouble(buffer2, value2); 00563 /* debug_str("LPS25H: [temp] "); 00564 debug_str(printDouble(buffer1, value1)); 00565 debug_str("Farenheit, [press] "); 00566 debug_str(printDouble(buffer2, value2));*/ 00567 tmp = "2,"; 00568 tmp += buffer2; 00569 tmp += ","; 00570 00571 if ((!press_sent) && (frame.length() + tmp.length() < 50)) 00572 { 00573 press_sent = true; 00574 frame += tmp; 00575 } 00576 00577 // debug_str("mbar\r\n"); 00578 //pc.printf("LPS25H: [temp] %7s°F, [press] %smbar\r\n", printDouble(buffer1, value1), printDouble(buffer2, value2)); 00579 00580 // debug_str("---\r\n"); 00581 00582 magnetometer->Get_M_Axes(axes); 00583 printInt(buffer1, axes[0]); 00584 printInt(buffer2, axes[1]); 00585 printInt(buffer3, axes[2]); 00586 /* debug_str("LIS3MDL [mag/mgauss]: "); 00587 debug_str(printInt(buffer1, axes[0])); 00588 debug_str(", "); 00589 debug_str(printInt(buffer2, axes[1])); 00590 debug_str(", "); 00591 debug_str(printInt(buffer3, axes[2])); 00592 debug_str("\r\n");*/ 00593 tmp = "3,"; 00594 tmp += buffer1; 00595 tmp += ";"; 00596 tmp += buffer2; 00597 tmp += ";"; 00598 tmp += buffer3; 00599 tmp += ","; 00600 00601 if ((!magn_sent) && (frame.length() + tmp.length() < 50)) 00602 { 00603 magn_sent = true; 00604 frame += tmp; 00605 } 00606 00607 //pc.printf("LIS3MDL [mag/mgauss]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00608 00609 accelerometer->Get_X_Axes(axes); 00610 printInt(buffer1, axes[0]); 00611 printInt(buffer2, axes[1]); 00612 printInt(buffer3, axes[2]); 00613 /* debug_str("LSM6DS0 [acc/mg]: "); 00614 00615 debug_str(printInt(buffer1, axes[0])); 00616 debug_str(", "); 00617 debug_str(printInt(buffer2, axes[1])); 00618 debug_str(", "); 00619 debug_str(printInt(buffer3, axes[2]));*/ 00620 tmp = "4,"; 00621 tmp += buffer1; 00622 tmp += ";"; 00623 tmp += buffer2; 00624 tmp += ";"; 00625 tmp += buffer3; 00626 tmp += ","; 00627 00628 if ((!motion_sent) && (frame.length() + tmp.length() < 50)) 00629 { 00630 motion_sent = true; 00631 frame += tmp; 00632 } 00633 00634 //debug_str("\r\n"); 00635 //pc.printf("LSM6DS0 [acc/mg]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00636 00637 gyroscope->Get_G_Axes(axes); 00638 printInt(buffer1, axes[0]); 00639 printInt(buffer2, axes[1]); 00640 printInt(buffer3, axes[2]); 00641 /* debug_str("LSM6DS0 [gyro/mdps]: "); 00642 debug_str(printInt(buffer1, axes[0])); 00643 debug_str(", "); 00644 debug_str(printInt(buffer2, axes[1])); 00645 debug_str(", "); 00646 debug_str(printInt(buffer3, axes[2]));*/ 00647 tmp = "5,"; 00648 tmp += buffer1; 00649 tmp += ";"; 00650 tmp += buffer2; 00651 tmp += ";"; 00652 tmp += buffer3; 00653 00654 if ((!gyro_sent) && (frame.length() + tmp.length() < 50)) 00655 { 00656 gyro_sent = false; 00657 temp_sent = false; 00658 press_sent = false; 00659 motion_sent = false; 00660 magn_sent = false; 00661 hum_sent = false; 00662 00663 frame += tmp; 00664 } 00665 00666 //debug_str("\r\n Frame: "); 00667 //debug_str(frame.c_str()); 00668 //debug_str("\r\n"); 00669 //pc.printf("LSM6DS0 [gyro/mdps]: %6ld, %6ld, %6ld\r\n", axes[0], axes[1], axes[2]); 00670 00671 strncpy((char*) LMIC.frame, frame.c_str(), strlen(frame.c_str())); 00672 00673 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00674 LMIC.frame[strlen(frame.c_str())] = LMIC.seqnoDn >> 8; 00675 LMIC.frame[strlen(frame.c_str())+1] = LMIC.seqnoDn; 00676 LMIC.frame[strlen(frame.c_str())+2] = LMIC.rssi >> 8; 00677 LMIC.frame[strlen(frame.c_str())+3] = LMIC.rssi; 00678 LMIC.frame[strlen(frame.c_str())+4] = LMIC.snr; 00679 #endif 00680 //debug_str("Frame to be sent: "); 00681 // debug_buf(LMIC.frame, strlen(frame) + 5); 00682 //debug_buf(LMIC.frame, strlen(frame.c_str())); 00683 00684 // LoRaWAN_data_size = strlen(frame) + 5; 00685 LoRaWAN_data_size = strlen(frame.c_str()); 00686 } 00687 00688 static void prepareTxFrame( void ) 00689 { 00690 LMIC.frame[0] = AppLedStateOn; 00691 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 ) 00692 LMIC.frame[1] = LMIC.seqnoDn >> 8; 00693 LMIC.frame[2] = LMIC.seqnoDn; 00694 LMIC.frame[3] = LMIC.rssi >> 8; 00695 LMIC.frame[4] = LMIC.rssi; 00696 LMIC.frame[5] = LMIC.snr; 00697 #endif 00698 //debug_str("Frame to be sent: "); 00699 //debug_buf(LMIC.frame, LORAWAN_APP_DATA_SIZE); 00700 00701 LoRaWAN_data_size = LORAWAN_APP_DATA_SIZE; 00702 } 00703 00704 void processRxFrame( void ) 00705 { 00706 00707 char* frameToDisplay = (char*) (LMIC.frame + LMIC.dataBeg); 00708 frameToDisplay[LMIC.dataLen] = '\0'; 00709 00710 switch( LMIC.frame[LMIC.dataBeg - 1] ) // Check Rx port number 00711 { 00712 case 0: 00713 // debug_str("Port 0!!!\r\n"); 00714 // debug_val("Data Len: ", LMIC.dataLen); 00715 00716 case 1: // The application LED can be controlled on port 1 or 2 00717 debug_str("Data received on port 1: "); 00718 debug_str("Data in hexa: "); 00719 debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen ); 00720 debug_str("Data in string: "); 00721 00722 debug_str( frameToDisplay ); 00723 debug_str("\r\n"); 00724 00725 break; 00726 case 2: 00727 debug_str("Data received on port 2: "); 00728 debug_str("Data in hexa: "); 00729 debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen ); 00730 debug_str("Data in string: "); 00731 00732 debug_str( frameToDisplay ); 00733 debug_str("\r\n"); 00734 00735 if( LMIC.dataLen == 1 ) 00736 { 00737 debug_str("Data received on port 2: "); 00738 debug_hex(LMIC.frame[LMIC.dataBeg]); 00739 debug_str("\r\n"); 00740 AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01; 00741 //debug_val( "LED3 = ", AppLedStateOn ); 00742 } 00743 break; 00744 default: 00745 break; 00746 } 00747 } 00748 00749 static void onSendFrame( osjob_t* j ) 00750 { 00751 //prepareTxFrame( ); 00752 //prepareTxCoapFrame(); 00753 prepareTxSensorsFrame(); 00754 //prepareTxLoraFrame(); 00755 00756 #if( OVER_THE_AIR_ACTIVATION == 1 ) 00757 LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LoRaWAN_data_size, LORAWAN_CONFIRMED_MSG_ON, 1 ); 00758 #endif 00759 #if( OVER_THE_AIR_ACTIVATION == 0 ) 00760 LMIC_setTxData2( LORAWAN_APP_PORT, LMIC.frame, LoRaWAN_data_size, LORAWAN_CONFIRMED_MSG_ON, 0 ); 00761 #endif 00762 00763 // Blink Tx LED 00764 //debug_val( "LED1 = ", 1 ); 00765 os_setTimedCallback( &txLedJob, os_getTime( ) + ms2osticks( 25 ), onTxLed ); 00766 /* os_setTimedCallback( &sendFrameJob, 00767 os_getTime( ) + ms2osticks( APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ) ), 00768 onSendFrame );*/ 00769 } 00770 00771 // Initialization job 00772 static void onInit( osjob_t* j ) 00773 { 00774 debug_str("--- Starting new run ---\r\n"); 00775 00776 humidity_sensor->ReadID(&id); 00777 debug_str("HTS221 humidity & temperature = "); 00778 debug_uint(id); 00779 debug_str("\r\n"); 00780 pressure_sensor->ReadID(&id); 00781 debug_str("LPS25H pressure & temperature = "); 00782 debug_uint(id); 00783 debug_str("\r\n"); 00784 magnetometer->ReadID(&id); 00785 debug_str("LIS3MDL magnetometer = "); 00786 debug_uint(id); 00787 debug_str("\r\n"); 00788 gyroscope->ReadID(&id); 00789 debug_str("LSM6DS0 accelerometer & gyroscope = "); 00790 debug_uint(id); 00791 debug_str("\r\n"); 00792 00793 // reset MAC state 00794 LMIC_reset( ); 00795 LMIC_setAdrMode( LORAWAN_ADR_ON ); 00796 LMIC_setDrTxpow( DR_SF12, 14 ); 00797 00798 // start joining 00799 #if( OVER_THE_AIR_ACTIVATION != 0 ) 00800 LMIC_startJoining( ); 00801 #else 00802 LMIC_setSession( LORAWAN_NET_ID, LORAWAN_DEV_ADDR, NwkSKey, ArtSKey ); 00803 onSendFrame( NULL ); 00804 #endif 00805 // init done - onEvent( ) callback will be invoked... 00806 } 00807 00808 int main( void ) 00809 { 00810 debug_init(); 00811 osjob_t initjob; 00812 00813 // initialize runtime env 00814 os_init( ); 00815 // setup initial job 00816 os_setCallback( &initjob, onInit ); 00817 // execute scheduled jobs and events 00818 00819 //static Thread exec_thread(exec_call_thread); 00820 00821 os_runloop( ); 00822 // (not reached) 00823 } 00824 00825 ////////////////////////////////////////////////// 00826 // LMIC EVENT CALLBACK 00827 ////////////////////////////////////////////////// 00828 void onEvent( ev_t ev ) 00829 { 00830 bool txOn = false; 00831 debug_event( ev ); 00832 00833 switch( ev ) 00834 { 00835 // network joined, session established 00836 case EV_JOINED: 00837 debug_val( "Net ID = ", LMIC.netid ); 00838 txOn = true; 00839 break; 00840 // scheduled data sent (optionally data received) 00841 case EV_TXCOMPLETE: 00842 debug_val( "Datarate = ", LMIC.datarate ); 00843 // Check if we have a downlink on either Rx1 or Rx2 windows 00844 if( ( LMIC.txrxFlags & ( TXRX_DNW1 | TXRX_DNW2 ) ) != 0 ) 00845 { 00846 // debug_val( "LED2 = ", 1 ); 00847 os_setTimedCallback( &rxLedJob, os_getTime( ) + ms2osticks( 25 ), onRxLed ); 00848 00849 if( LMIC.dataLen != 0 ) 00850 { // data received in rx slot after tx 00851 //debug_buf( LMIC.frame + LMIC.dataBeg, LMIC.dataLen ); 00852 processRxFrame( ); 00853 } 00854 } 00855 txOn = true; 00856 break; 00857 default: 00858 break; 00859 } 00860 if( txOn == true ) 00861 { 00862 //Sends frame every APP_TX_DUTYCYCLE +/- APP_TX_DUTYCYCLE_RND random time (if not duty cycle limited) 00863 os_setTimedCallback( &sendFrameJob, 00864 os_getTime( ) + ms2osticks( APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND ) ), 00865 onSendFrame ); 00866 //os_setCallback( &sendFrameJob, onSendFrame ); 00867 ////Sends frame as soon as possible (duty cylce limitations) 00868 //onSendFrame( NULL ); 00869 } 00870 } 00871 00872
Generated on Wed Jul 13 2022 06:25:04 by
