mDot EVB to M2X demo.
Dependencies: DOGS102 ISL29011 MMA845x MPL3115A2 NCP5623B libmDot mbed-rtos mbed-src
Fork of MTDOT-EVBDemo by
Diff: main.cpp
- Revision:
- 5:72d4d95e1d42
- Parent:
- 4:71e411fbd9ff
- Child:
- 6:c212427700af
--- a/main.cpp Thu Jul 16 21:00:37 2015 +0000 +++ b/main.cpp Mon Jul 20 16:04:04 2015 +0000 @@ -22,13 +22,15 @@ * 1.01 TAB 7/6/15 Removed NULL pointer from evbAmbientLight creation call. * * 1.02 TAB 7/8/15 Send logo to LCD before attempting connection to LoRa network. Added - * information on setting up for public LoRa network. Moved SW setup to - * beginning of main. Removed printf call from ISR functions. Added - * additional checks for exit_program. + * information on setting up for public LoRa network. Moved SW setup to + * beginning of main. Removed printf call from ISR functions. Added + * additional checks for exit_program. * * 1.03 TAB 7/15/15 Added threads for push button switch debounce. * - * 1.04 JCM 7/16/15 Updated application to use with ATT m2x + * 1.04 JCM 7/16/15 Updated application for AT&T M2X Demo + * + * 1.05 JCM 7/20/15 Integrate Senet Public network demo * */ @@ -45,7 +47,12 @@ #include <string> #include <vector> - +/* + * General settings + */ +const bool public_net = false; +const bool senet_demo = false; +static uint8_t config_frequency_sub_band = 5; /* * Conduit AEP settings @@ -54,7 +61,14 @@ */ static std::string config_network_name = "testtest"; static std::string config_network_pass = "memememe"; -static uint8_t config_frequency_sub_band = 5; + +/* + * Public Network settings + */ +static uint8_t app_id[8] = {0x00,0x25,0x0C,0x00,0x00,0x01,0x00,0x01}; +std::vector<uint8_t> config_app_id(app_id, app_id + sizeof(app_id)/sizeof(uint8_t)); +static uint8_t app_key[16] = {0xB4,0xAD,0x1A,0x25,0x69,0x7F,0xF6,0x8E,0xD3,0x4B,0x83,0xC4,0xB6,0xC0,0xF2,0x3C}; +std::vector<uint8_t> config_app_key(app_key, app_key + sizeof(app_key)/sizeof(uint8_t)); /* * M2X settings @@ -63,18 +77,8 @@ * Once a device is added you will see DEVICE ID and PRIMARY API KEY fields * for the device. */ -const char *m2x_device = "b621939e08743f9befaa46840dcb0388"; -const char *m2x_key = "ee32d3c67ca64408e20bd471dcdbd4ff"; - -/* - * config_app_id and config_app_key are for public networks. - */ -/* -static uint8_t app_id[8] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D}; -std::vector<uint8_t> config_app_id; -static uint8_t app_key[16] = {0x00,0x01,0x02,0x03,0x0A,0x0B,0x0C,0x0D}; -std::vector<uint8_t> config_app_key; -*/ +const char *m2x_device = "f397d9c6c74cb1e2a1be5ef7731dc8af"; +const char *m2x_key = "5899c8b045531d3634efa65096ee3ede"; enum LED1_COLOR { @@ -86,50 +90,49 @@ * union for converting from 32-bit to 4 8-bit values */ union convert32 { - int32_t f_s; // convert from signed 32 bit int - uint32_t f_u; // convert from unsigned 32 bit int - uint8_t t_u[4]; // convert to 8 bit unsigned array + int32_t f_s; // convert from signed 32 bit int + uint32_t f_u; // convert from unsigned 32 bit int + uint8_t t_u[4]; // convert to 8 bit unsigned array }; /* * union for converting from 16- bit to 2 8-bit values */ union convert16 { - int16_t f_s; // convert from signed 16 bit int - uint16_t f_u; // convert from unsigned 16 bit int - uint8_t t_u[2]; // convert to 8 bit unsigned array + int16_t f_s; // convert from signed 16 bit int + uint16_t f_u; // convert from unsigned 16 bit int + uint8_t t_u[2]; // convert to 8 bit unsigned array }; -//DigitalIn mDot02(PA_2); // GPIO/UART_TX -//DigitalOut mDot03(PA_3); // GPIO/UART_RX -//DigitalIn mDot04(PA_6); // GPIO/SPI_MISO -//DigitalIn mDot06(PA_8); // GPIO/I2C_SCL -//DigitalIn mDot07(PC_9); // GPIO/I2C_SDA +//DigitalIn mDot02(PA_2); // GPIO/UART_TX +//DigitalOut mDot03(PA_3); // GPIO/UART_RX +//DigitalIn mDot04(PA_6); // GPIO/SPI_MISO +//DigitalIn mDot06(PA_8); // GPIO/I2C_SCL +//DigitalIn mDot07(PC_9); // GPIO/I2C_SDA -InterruptIn mDot08(PA_12); // GPIO/USB PB S1 on EVB -InterruptIn mDot09(PA_11); // GPIO/USB PB S2 on EVB +InterruptIn mDot08(PA_12); // GPIO/USB PB S1 on EVB +InterruptIn mDot09(PA_11); // GPIO/USB PB S2 on EVB -//DigitalIn mDot11(PA_7); // GPIO/SPI_MOSI +//DigitalIn mDot11(PA_7); // GPIO/SPI_MOSI -InterruptIn mDot12(PA_0); // GPIO/UART_CTS PRESSURE_INT2 on EVB -DigitalOut mDot13(PC_13,1); // GPIO LCD_C/D -InterruptIn mDot15(PC_1); // GPIO LIGHT_PROX_INT on EVB -InterruptIn mDot16(PA_1); // GPIO/UART_RTS ACCEL_INT2 on EVB -DigitalOut mDot17(PA_4,1); // GPIO/SPI_NCS LCD_CS on EVB +InterruptIn mDot12(PA_0); // GPIO/UART_CTS PRESSURE_INT2 on EVB +DigitalOut mDot13(PC_13,1); // GPIO LCD_C/D +InterruptIn mDot15(PC_1); // GPIO LIGHT_PROX_INT on EVB +InterruptIn mDot16(PA_1); // GPIO/UART_RTS ACCEL_INT2 on EVB +DigitalOut mDot17(PA_4,1); // GPIO/SPI_NCS LCD_CS on EVB -//DigitalIn mDot18(PA_5); // GPIO/SPI_SCK +//DigitalIn mDot18(PA_5); // GPIO/SPI_SCK //DigitalInOut mDot19(PB_0,PIN_INPUT,PullNone,0); // GPIO PushPull LED Low=Red High=Green set MODE=INPUT to turn off -AnalogIn mDot20(PB_1); // GPIO Current Sense Analog in on EVB +AnalogIn mDot20(PB_1); // GPIO Current Sense Analog in on EVB -Serial debugUART(PA_9, PA_10); // mDot debug UART +Serial debugUART(PA_9, PA_10); // mDot debug UART -//Serial mDotUART(PA_2, PA_3); // mDot external UART mDot02 and mDot03 +//Serial mDotUART(PA_2, PA_3); // mDot external UART mDot02 and mDot03 -I2C mDoti2c(PC_9,PA_8); // mDot External I2C mDot6 and mDot7 +I2C mDoti2c(PC_9,PA_8); // mDot External I2C mDot6 and mDot7 -SPI mDotspi(PA_7,PA_6,PA_5); // mDot external SPI mDot11, mDot4, and mDot18 - +SPI mDotspi(PA_7,PA_6,PA_5); // mDot external SPI mDot11, mDot4, and mDot18 uint8_t result, pckt_time=10; @@ -140,6 +143,8 @@ uint32_t pressure; int16_t num_frac; +uint8_t position_value; // 00 unknown, 01 is flat, 02 is vertical + bool exit_program = false; MMA845x_DATA accel_data; @@ -178,16 +183,16 @@ debugUART.baud(115200); // mDotUART.baud(9600); // mdot UART unused but available on external connector - Thread thread_1(pb1_debounce); // threads for de-bouncing pushbutton switches + Thread thread_1(pb1_debounce); // threads for de-bouncing pushbutton switches Thread thread_2(pb2_debounce); - thread_3 = new Thread(config_pkt_xmit); // start thread that sends LoRa packet when SW2 pressed + thread_3 = new Thread(config_pkt_xmit); // start thread that sends LoRa packet when SW2 pressed - evbAccel = new MMA845x(mDoti2c,MMA845x::SA0_VSS); // setup Accelerometer - evbBaro = new MPL3115A2(mDoti2c); // setup Barometric sensor - evbAmbLight = new ISL29011(mDoti2c); // Setup Ambient Light Sensor - evbBackLight = new NCP5623B(mDoti2c); // setup backlight and LED 2 driver chip - evbLCD = new DOGS102(mDotspi, mDot17, mDot13); // setup LCD + evbAccel = new MMA845x(mDoti2c,MMA845x::SA0_VSS); // setup Accelerometer + evbBaro = new MPL3115A2(mDoti2c); // setup Barometric sensor + evbAmbLight = new ISL29011(mDoti2c); // Setup Ambient Light Sensor + evbBackLight = new NCP5623B(mDoti2c); // setup backlight and LED 2 driver chip + evbLCD = new DOGS102(mDotspi, mDot17, mDot13); // setup LCD /* * Setup SW1 as program stop function @@ -263,52 +268,41 @@ } printf("\n\r"); - -// Setting up the mDot with network information. + printf("setting Network Mode to %s\r\n", public_net ? "public" : "private"); + if ((mdot_ret = mdot_radio->setPublicNetwork(public_net)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set Network Mode", mdot_ret); + } -/* - * This call sets up private or public mode on the MTDOT. Set the function to true if - * connecting to a public network - */ - printf("setting Private Network Mode\r\n"); - if ((mdot_ret = mdot_radio->setPublicNetwork(false)) != mDot::MDOT_OK) { - log_error(mdot_radio, "failed to set Public Network Mode", mdot_ret); - } - -/* - * Frequency sub-band is valid for NAM only and for Private networks should be set to a value - * between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only. - * This function can be commented out for EU networks - */ + /* + * Frequency sub-band is valid for NAM only and for Private networks should be set to a value + * between 1-8 that matches the the LoRa gateway setting. Public networks use sub-band 0 only. + * This function can be commented out for EU networks + */ printf("setting frequency sub band\r\n"); if ((mdot_ret = mdot_radio->setFrequencySubBand(config_frequency_sub_band)) != mDot::MDOT_OK) { log_error(mdot_radio, "failed to set frequency sub band", mdot_ret); } -/* - * setNetworkName is used for private networks. - * Use setNetworkID(AppID) for public networks - */ - -// config_app_id.assign(app_id,app_id+7); - printf("setting network name\r\n"); - if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) { -// if ((mdot_ret = mdot_radio->setNetworkID(config_app_id)) != mDot::MDOT_OK) { - log_error(mdot_radio, "failed to set network name", mdot_ret); + if (public_net) { + if ((mdot_ret = mdot_radio->setNetworkId(config_app_id)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set network name", mdot_ret); + } + } else { + if ((mdot_ret = mdot_radio->setNetworkName(config_network_name)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set network name", mdot_ret); + } } -/* - * setNetworkPassphrase is used for private networks - * Use setNetworkKey for public networks - */ - -// config_app_key.assign(app_key,app_key+15); - printf("setting network password\r\n"); - if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) { -// if ((mdot_ret = mdot_radio->setNetworkKey(config_app_key)) != mDot::MDOT_OK) { - log_error(mdot_radio, "failed to set network password", mdot_ret); + if (public_net) { + if ((mdot_ret = mdot_radio->setNetworkKey(config_app_key)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set network key", mdot_ret); + } + } else { + if ((mdot_ret = mdot_radio->setNetworkPassphrase(config_network_pass)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to set network pass phrase", mdot_ret); + } } // attempt to join the network @@ -316,12 +310,10 @@ while (((mdot_ret = mdot_radio->joinNetwork()) != mDot::MDOT_OK) && (!exit_program)) { log_error(mdot_radio,"failed to join network:", mdot_ret); if (mdot_radio->getFrequencyBand() == mDot::FB_868){ - mdot_ret = mdot_radio->getNextTxMs(); - } - else { - mdot_ret = 0; - } - + mdot_ret = mdot_radio->getNextTxMs(); + } else { + mdot_ret = 0; + } printf("delay = %lu\n\r",mdot_ret); osDelay(mdot_ret + 1); } @@ -350,11 +342,11 @@ printf("Start of Test\n\r"); - osDelay (500); // allows other threads to process + osDelay (500); // allows other threads to process printf("shutdown LED:\n\r"); evbBackLight->shutdown(); - osDelay (500); // allows other threads to process + osDelay (500); // allows other threads to process printf("Turn on LED2\n\r"); evbBackLight->setLEDCurrent(16); @@ -420,22 +412,24 @@ pckt_time = 10; i = 0; - lora_pl.clear(); - lora_pl.push_back(19); - lora_pl.push_back(strlen(m2x_device)); - lora_pl.insert(lora_pl.end(), m2x_device, m2x_device + strlen(m2x_device)); - while ((mdot_ret = mdot_radio->send(lora_pl)) != mDot::MDOT_OK) { - log_error(mdot_radio, "Failed to register m2x_device", mdot_ret); - osDelay(2000); - } + if (!senet_demo) { + lora_pl.clear(); + lora_pl.push_back(19); + lora_pl.push_back(strlen(m2x_device)); + lora_pl.insert(lora_pl.end(), m2x_device, m2x_device + strlen(m2x_device)); + while ((mdot_ret = mdot_radio->send(lora_pl)) != mDot::MDOT_OK) { + log_error(mdot_radio, "Failed to register m2x_device", mdot_ret); + osDelay(2000); + } - lora_pl.clear(); - lora_pl.push_back(20); - lora_pl.push_back(strlen(m2x_key)); - lora_pl.insert(lora_pl.end(), m2x_key, m2x_key + strlen(m2x_key)); - while ((mdot_ret = mdot_radio->send(lora_pl)) != mDot::MDOT_OK) { - log_error(mdot_radio, "Failed to register m2x_key", mdot_ret); - osDelay(2000); + lora_pl.clear(); + lora_pl.push_back(20); + lora_pl.push_back(strlen(m2x_key)); + lora_pl.insert(lora_pl.end(), m2x_key, m2x_key + strlen(m2x_key)); + while ((mdot_ret = mdot_radio->send(lora_pl)) != mDot::MDOT_OK) { + log_error(mdot_radio, "Failed to register m2x_key", mdot_ret); + osDelay(2000); + } } do { @@ -446,7 +440,7 @@ * Test Accelerometer XYZ data ready bit to see if acquisition complete */ do { - osDelay(100); // allows other threads to process + osDelay(100); // allows other threads to process result = evbAccel->getStatus(); } while ((result & MMA845x::XYZDR) == 0 ); @@ -464,6 +458,15 @@ sprintf(txtstr, "z = %d", accel_data._z ); evbLCD->writeText(20,3,font_6x8,txtstr,strlen(txtstr)); + // convert to simple position value for use in send/recv + if (accel_data._x > 500 && accel_data._z < 500) { + position_value = 0x02; + } else if (accel_data._x < 500 && accel_data._z > 500) { + position_value = 0x01; + } else { + position_value= 0x00; + } + /* * Trigger a Pressure reading */ @@ -475,7 +478,7 @@ * Test barometer device status to see if acquisition is complete */ do { - osDelay(100); // allows other threads to process + osDelay(100); // allows other threads to process result = evbBaro->getStatus(); } while ((result & MPL3115A2::PTDR) == 0 ); @@ -483,8 +486,8 @@ * Retrieve and print out barometric pressure */ pressure = evbBaro->getBaroData() >> 12; // convert 32 bit signed to 20 bit unsigned value - num_whole = pressure >> 2; // 18 bit integer significant - num_frac = (pressure & 0x3) * 25; // 2 bit fractional 0.25 per bit + num_whole = pressure >> 2; // 18 bit integer significant + num_frac = (pressure & 0x3) * 25; // 2 bit fractional 0.25 per bit sprintf(txtstr,"Press=%ld.%02d Pa", num_whole, num_frac); evbLCD->writeText(0,4,font_6x8,txtstr,strlen(txtstr)); @@ -499,7 +502,7 @@ * Test barometer device status to see if acquisition is complete */ do { - osDelay(100); // allows other threads to process + osDelay(100); // allows other threads to process result = evbBaro->getStatus(); } while ((result & MPL3115A2::PTDR) == 0 ); @@ -507,13 +510,13 @@ * Retrieve and print out altitude and temperature */ baro_data = evbBaro->getAllData(false); - baro_data._baro /= 4096; // convert 32 bit signed to 20 bit signed value - num_whole = baro_data._baro / 16; // 18 bit signed significant integer - num_frac = (baro_data._baro & 0xF) * 625 / 100; // 4 bit fractional .0625 per bit + baro_data._baro /= 4096; // convert 32 bit signed to 20 bit signed value + num_whole = baro_data._baro / 16; // 18 bit signed significant integer + num_frac = (baro_data._baro & 0xF) * 625 / 100; // 4 bit fractional .0625 per bit sprintf(txtstr,"Alti=%ld.%03d m", num_whole, num_frac); evbLCD->writeText(0,5,font_6x8,txtstr,strlen(txtstr)); - num_whole = baro_data._temp / 16; // 8 bit signed significant integer - num_frac = (baro_data._temp & 0x0F) * 625 / 10; // 4 bit fractional .0625 per bit + num_whole = baro_data._temp / 16; // 8 bit signed significant integer + num_frac = (baro_data._temp & 0x0F) * 625 / 10; // 4 bit fractional .0625 per bit sprintf(txtstr,"Temp=%ld.%03d C", num_whole, num_frac); evbLCD->writeText(0,6,font_6x8,txtstr,strlen(txtstr)); @@ -521,7 +524,7 @@ * retrieve and print out Ambient Light level */ lux_data = evbAmbLight->getData(); - num_whole = lux_data * 24 / 100; // 16000 lux full scale .24 lux per bit + num_whole = lux_data * 24 / 100; // 16000 lux full scale .24 lux per bit num_frac = lux_data * 24 % 100; sprintf(txtstr, "Light=%ld.%02d lux", num_whole, num_frac); evbLCD->writeText(0,7,font_6x8,txtstr,strlen(txtstr)); @@ -531,38 +534,67 @@ if (i % pckt_time == 0) { // check packet counter will send packet every 2-5-10 data collection loops lora_pl.clear(); - lora_pl.push_back(0x0E); // key for Current Acceleration 3-Axis Value - lora_pl.push_back(6); - converts.f_s = accel_data._x; - lora_pl.push_back(converts.t_u[1]); - lora_pl.push_back(converts.t_u[0]); - converts.f_s = accel_data._y; - lora_pl.push_back(converts.t_u[1]); - lora_pl.push_back(converts.t_u[0]); - converts.f_s = accel_data._z; - lora_pl.push_back(converts.t_u[1]); - lora_pl.push_back(converts.t_u[0]); - lora_pl.push_back(0x08); // key for Current Pressure Value - lora_pl.push_back(3); - convertl.f_u = pressure; // pressure data is 20 bits unsigned - lora_pl.push_back(convertl.t_u[2]); - lora_pl.push_back(convertl.t_u[1]); - lora_pl.push_back(convertl.t_u[0]); - lora_pl.push_back(0x05); // key for Current Ambient Light Value - lora_pl.push_back(2); - converts.f_u = lux_data; // data is 16 bits unsigned - lora_pl.push_back(converts.t_u[1]); - lora_pl.push_back(converts.t_u[0]); - lora_pl.push_back(0x0B); // key for Current Temperature Value - lora_pl.push_back(2); - converts.f_s = baro_data._temp; // temperature is signed 12 bit - lora_pl.push_back(converts.t_u[1]); - lora_pl.push_back(converts.t_u[0]); + + if (senet_demo) { + // Position Value + lora_pl.push_back(0); + lora_pl.push_back(position_value); + } else { + // Current Acceleration 3-Axis Value + lora_pl.push_back(14); + lora_pl.push_back(6); + converts.f_s = accel_data._x; + lora_pl.push_back(converts.t_u[1]); + lora_pl.push_back(converts.t_u[0]); + converts.f_s = accel_data._y; + lora_pl.push_back(converts.t_u[1]); + lora_pl.push_back(converts.t_u[0]); + converts.f_s = accel_data._z; + lora_pl.push_back(converts.t_u[1]); + lora_pl.push_back(converts.t_u[0]); + // Current Pressure Value + lora_pl.push_back(8); + lora_pl.push_back(3); + convertl.f_u = pressure; + lora_pl.push_back(convertl.t_u[2]); + lora_pl.push_back(convertl.t_u[1]); + lora_pl.push_back(convertl.t_u[0]); + // Current Ambient Light Value + lora_pl.push_back(5); + lora_pl.push_back(2); + converts.f_u = lux_data; + lora_pl.push_back(converts.t_u[1]); + lora_pl.push_back(converts.t_u[0]); + // Current Temperature Value + lora_pl.push_back(11); + lora_pl.push_back(2); + converts.f_s = baro_data._temp; + lora_pl.push_back(converts.t_u[1]); + lora_pl.push_back(converts.t_u[0]); + } if ((mdot_ret = mdot_radio->send(lora_pl)) != mDot::MDOT_OK) { log_error(mdot_radio, "failed to send", mdot_ret); } else { printf("successfully sent data to gateway\r\n"); + + if (senet_demo) { + lora_pl.clear(); + if ((mdot_ret = mdot_radio->recv(lora_pl)) != mDot::MDOT_OK) { + log_error(mdot_radio, "failed to recv:", mdot_ret); + } else { + printf("recv data: "); + for(int i = 0;i < lora_pl.size();i++) { + printf("%02X", lora_pl[i]); + } + printf("\r\n"); + if(lora_pl[0] == position_value) { + evbBackLight->setLEDCurrent(16); + } else { + evbBackLight->setLEDCurrent(0); + } + } + } } } } while(!exit_program && (i < 65000)); @@ -570,7 +602,7 @@ evbBaro->triggerOneShot(); do { - osDelay(200); // allows other threads to process + osDelay(200); // allows other threads to process result = evbBaro->getStatus(); } while ((result & MPL3115A2::PTDR) == 0 ); @@ -591,8 +623,8 @@ */ void pb1ISR(void) { - if (!pb1_low) - pb1_low = true; + if (!pb1_low) + pb1_low = true; } /* @@ -600,21 +632,19 @@ */ void pb1_debounce(void const *args) { - static uint8_t count = 0; while (true) { + if (pb1_low && (mDot08 == 0)) { + count++; + } else { + count = 0; + pb1_low = false; + } - if (pb1_low && (mDot08 == 0)) - count++; - else { - count = 0; - pb1_low = false; - } - - if (count == 5) - exit_program = true; - + if (count == 5) + exit_program = true; + Thread::wait(5); } } @@ -624,8 +654,8 @@ */ void pb2ISR(void) { - if (!pb2_low) - pb2_low = true; + if (!pb2_low) + pb2_low = true; } /* @@ -635,29 +665,26 @@ */ void pb2_debounce(void const *args) { - static uint8_t count = 0; while (true) { - - if (pb2_low && (mDot09 == 0)) - count++; - else { - count = 0; - pb2_low = false; + if (pb2_low && (mDot09 == 0)) { + count++; + } else { + count = 0; + pb2_low = false; } - - if (count == 5){ - if (pckt_time >= 5) - pckt_time /= 2; - else pckt_time = 20; + if (count == 5) { + if (pckt_time >= 5) + pckt_time /= 2; + else pckt_time = 20; - thread_3->signal_set(0x10); // signal config_pkt_xmit to send packet - } - + thread_3->signal_set(0x10); // signal config_pkt_xmit to send packet + } + Thread::wait(5); - } + } } /* @@ -676,9 +703,10 @@ std::vector<uint8_t> lora_pl; while (true) { - Thread::signal_wait(0x10); // wait for pb2ISR to signal send + Thread::signal_wait(0x10); // wait for pb2ISR to signal send + lora_pl.clear(); - lora_pl.push_back(0x0F); // key for Configuration data (packet transmission timer) + lora_pl.push_back(15); // key for Configuration data (packet transmission timer) lora_pl.push_back(1); lora_pl.push_back(pckt_time); @@ -688,4 +716,4 @@ printf("sent config data to gateway\r\n"); } } -} +} \ No newline at end of file