LMIC transmit example for NAmote-72 with GPS
Dependencies: lib_gps lib_mpl3115a2 lmic_MOTE_L152RC mbed
Deprecated and replaced with
Import programLoRaWAN-NAMote72-Application-Demo
Demonstration of Class-A LoRaWAN device using NAMote-72
LoRaWAN Network Configuration (in Config.h)
For Over the Air (OTA) activation of an End-Device, it must be configured with the following parameters:
DEVEUI
(8 Bytes) : Fist 3 Bytes is the Organizationally Unique Identifier (OUI) followed by 5 bytes of unique ID.APPEUI
(8 Bytes)APPKey
(or DEVKEY) (16 Bytes) The parameters can be entered as shown in the figure below
LoRaWAN Transmission Configuration (in Config.h)
- Inter-Frame Delay :
One can change the delay between each frame transmission using
MS_DELAY_NEXT_TX
It is advisable thatMS_DELAY_NEXT_TX
is greater than or equal to 3sec.
- Payload Length :
The lenght of the payload (in bytes) to be transmitted can be configured using
PAYLOAD_LENGTH
- Data Rate :
The data rate can be configured as per LoRaWAN specification using the paramter
FIXED_DR
- Channel Configuration :
In the case where the End-Device is transmitting over frequencies corresponding to a block of 8 channels, the block can be specified using
CHNL_HYBRID
. The value 0 corresponds to Block A, 1 corresponds to Block B and so on. When the End-Device transmits over more than 50 channels,CHNL_HYBRID
needs to be commented out
- Transmit Power :
The power of the data to be transmitted can be configured using the parameter
FIXED_TX_POWER
. The maximum transmit power allowed is as per FCC regulation, depending upon the mode of transmission.
Serial Terminal Display
By using a serial port connection using applications such as teraterm or putty, one can view the status of the End-Device. Once the End-Device Joins the network, transmission parameters such as payload data, transmit power, battery level etc. are displayed on the terminal.
Default Application Payload
This application defaults to sending uplink data to logical port 5. The application payload consists of:
Sample Application Payload Calculation for Longitude/Latitude
Payload => 00 19 F6 352BBA A94C20 FFFF
Temperature Calculation
19H => 2510
Temp = 25/2 = 12.5 oC
Battery Level
FFH => 100 %
F6H => 96.5 %
Longitude Calculation
longitude = A94C20H => 1109507210
longitudinal coordinate = -360 + (longitude10 x 180/(223))
longitudinal coordinate = -121.93
Latitude Calculation
latitude = 352BBAH = 348460210
latitude coordinate = (latitude10 x 90/(223-1))
latitude coordinate = 37.39
Revision 8:26682f47bff1, committed 2016-03-02
- Comitter:
- ubhat
- Date:
- Wed Mar 02 08:11:33 2016 +0000
- Parent:
- 7:7de55330772d
- Commit message:
- Restructure Main.cpp & config.h
Changed in this revision
diff -r 7de55330772d -r 26682f47bff1 config.h --- a/config.h Fri Jan 15 18:24:10 2016 +0000 +++ b/config.h Wed Mar 02 08:11:33 2016 +0000 @@ -1,5 +1,31 @@ +// Organizationally Unique Identifier +#define OUI 0x00, 0x00, 0x00 + +/* DEVEUI = {[OUI] [5 bytes of Unique ID]} +if last 4 bytes of DEVEUI equals 0, then the firmware will assign a unique ID +*/ +#define DEVEUI OUI, 0x00, 0x00, 0x00, 0x00, 0x00 + +#define APPEUI 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +#define DEVKEY 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + +// Time between transmissions in msec +#define MS_DELAY_NEXT_TX 3000 + +// Length of payload (Must be within the Maximum Length as defined in 7.2.6 of LoRaWAN 1.0 Specification +#define PAYLOAD_LENGTH 11 + +/* DR_SF10 = 0, DR_SF9 = 1, DR_SF8 = 2, DR_SF7 = 3, DR_SF8C = 4 [as defined in Table 18 of Section 7 of LoRaWAN 1.0 Specification */ +#define FIXED_DR DR_SF10 + +/* US 915MHz ISM Band */ #define CFG_us915 +/* SX1272 chip */ #define CFG_sx1272_radio -//#define CHNL_HYBRID 0 /* 0-7 to select block of 8 channels used */ \ No newline at end of file +// 0-7 to select block of 8 channels (Block A = 0, Block B = 1 ... Block H = 7). Comment this line to enable all 64 channels +#define CHNL_HYBRID 0 + +// Set Tx Power in dBm (Max = 30dBm for frequency hopping over 50channels; 26dBm with Digital Modulation; 21dBm in Hybrid mode) +#define FIXED_TX_POWER 20
diff -r 7de55330772d -r 26682f47bff1 lib_mpl3115a2.lib --- a/lib_mpl3115a2.lib Fri Jan 15 18:24:10 2016 +0000 +++ b/lib_mpl3115a2.lib Wed Mar 02 08:11:33 2016 +0000 @@ -1,1 +1,1 @@ -https://developer.mbed.org/users/dudmuck/code/lib_mpl3115a2/#3cd1f21925e8 +https://developer.mbed.org/users/dudmuck/code/lib_mpl3115a2/#0eb8b0ad292b
diff -r 7de55330772d -r 26682f47bff1 lmic_MOTE_L152RC.lib --- a/lmic_MOTE_L152RC.lib Fri Jan 15 18:24:10 2016 +0000 +++ b/lmic_MOTE_L152RC.lib Wed Mar 02 08:11:33 2016 +0000 @@ -1,1 +1,1 @@ -https://developer.mbed.org/teams/Semtech/code/lmic_MOTE_L152RC/#0faa1bb768b5 +https://developer.mbed.org/teams/Semtech/code/lmic_MOTE_L152RC/#6c0830baf10f
diff -r 7de55330772d -r 26682f47bff1 main.cpp --- a/main.cpp Fri Jan 15 18:24:10 2016 +0000 +++ b/main.cpp Wed Mar 02 08:11:33 2016 +0000 @@ -1,26 +1,25 @@ -/* - / _____) _ | | -( (____ _____ ____ _| |_ _____ ____| |__ - \____ \| ___ | (_ _) ___ |/ ___) _ \ - _____) ) ____| | | || |_| ____( (___| | | | -(______/|_____)_|_|_| \__)_____)\____)_| |_| - (C)2013 Semtech - -Description: MBED example application - -License: Revised BSD License, see LICENSE.TXT file include in the project +/******************************************************************************* + * Copyright (c) 2014-2015 IBM Corporation. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Zurich Research Lab - initial API, implementation and documentation + *******************************************************************************/ -Maintainer: Miguel Luis and Gregory Cristian -*/ -#include "mbed.h" #include "lmic.h" -#include "mpl3115a2.h" +#include "debug.h" +#include <mbed.h> #include "gps.h" -#include "debug.h" +#include "mpl3115a2.h" -#define SENET_F -//#define SMTC +#define FHS_MAX_POW 30 /* Frequency Hopping Max Power */ +#define DMTS_MAX_POW 26 /* Digital Modulation Max Power */ +#define HS_MAX_POW 20 /* Hybrid System Max Power */ +bool joined; typedef enum { MOTE_NONE = 0, MOTE_V2, @@ -28,89 +27,38 @@ } mote_version_e; mote_version_e mote_version = MOTE_NONE; +DigitalOut gps_en(PB_11); // dis/enables voltage divider on PA_1 DigitalOut pc_7(PC_7); DigitalIn pc_1(PC_1); +AnalogIn *bat; +#define LOW_BAT_THRESHOLD 3.45 +#define AIN_VREF 3.3 // stm32 internal refernce +#define AIN_VBAT_DIV 2 // resistor divider + +#define LED_ON 0 +#define LED_OFF 1 +static DigitalOut led_red(PB_1); +static DigitalOut led_yellow(PB_10); +//static DigitalOut led_green(PC_3); +static DigitalOut led_usr(PA_5); -/* ****************************************** */ -/* ***** Basic App and Network Parameters *** */ -/* ****************************************** */ -// Hybrid Mode must be defined in lmic.h // -// DevEUI and Keys defined by Activation type // -#define APP_DATA_SIZE 11 -#define APP_ACK 0 -#define MS_DELAY_NEXT_TX 400 -#ifdef SMTC -#define OVER_THE_AIR_ACTIVATION 1 //0 -#else -#define OVER_THE_AIR_ACTIVATION 1 -#endif /* SMTC */ - -/* ***************************************** */ - -#define LED_RED PB_1 -#define LED_YEL PB_10 - -static DigitalOut led1(LED_RED); -static DigitalOut led2(LED_YEL); - -/* gps(tx, rx, en); */ GPS gps(PB_6, PB_7, PB_11); - I2C i2c(I2C_SDA, I2C_SCL); DigitalIn i2c_int_pin(PB_4); MPL3115A2 mpl3115a2(i2c, i2c_int_pin); -AnalogIn *bat; -#define LOW_BAT_THRESHOLD 3.45 +volatile bool AppLedStateOn = false; + ////////////////////////////////////////////////// // CONFIGURATION (FOR APPLICATION CALLBACKS BELOW) ////////////////////////////////////////////////// -#ifdef SENET_F -// application router ID (LSBF) -//static const u1_t APPEUI[8] = { 0x01, 0x00, 0x01, 0x00, 0x00, 0x0c, 0x25, 0x00 }; -static const u1_t reverse_APPEUI[8] = { 0x00, 0x25, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x01 }; - -// unique device ID (LSBF) -//static const u1_t DEVEUI[8] = { 0x0f, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x25, 0x00 }; -static const u1_t reverse_DEVEUI[8] = { 0x00, 0x25, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x0F }; - -// device-specific AES key (derived from device EUI) -static const u1_t DEVKEY[16] = { 0xe4, 0x72, 0x71, 0xc5, 0xf5, 0x30, 0xa9, 0x9f, 0xcf, 0xc4, 0x0e, 0xab, 0xea, 0xd7, 0x19, 0x42, }; - // E4 -72 -71 -C5 -F5 -30 -A9 -9F -CF -C4 -0E -AB -EA -D7 -19 -42 -#endif /* SENET_F */ - -#ifdef SMTC -// Semtech Activation (v1.x server) -// application router ID (LSBF) -static const u1_t reverse_APPEUI[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - //AA-AA-AA-AA-FF-FF-FF-FF -//static const u1_t APPEUI[8] = { 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa, 0xaa, 0xaa }; -//static const u1_t reverse_APPEUI[8] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xff, 0xff, 0xff, 0xff }; -// unique device ID (LSBF) -//static const u1_t DEVEUI[8] = { 0x21, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x25, 0x00 }; -static const u1_t reverse_DEVEUI[8] = { 0x00, 0x25, 0x0C, 0x01, 0x00, 0x00, 0x00, 0x20 }; -//static const u1_t DEVEUI[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; -//static const u1_t reverse_DEVEUI[8] = { 0xEF, 0xCD, 0xAB, 0x89, 0x67, 0x45, 0x23, 0x01 }; - -// device-specific AES key (derived from device EUI) -static const u1_t DEVKEY[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; -//static const u1_t DEVKEY[16] = { 0xab, 0x89, 0xef, 0xcd, 0x23, 0x01, 0x67, 0x45, 0x54, 0x76, 0x10, 0x32, 0xdc, 0xfe, 0x98, 0xba }; +static const u1_t app_eui[ 8] = { APPEUI }; +//static u1_t dev_eui[ 8] = { OUI, 0x00, 0xff, 0xff, 0xff, 0xff }; +static u1_t dev_eui[ 8] = { DEVEUI }; +static const u1_t dev_key[16] = { DEVKEY }; -/*static uint8_t NwkSKey[] = -{ - 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C -}; - -static uint8_t ArtSKey[] = -{ - 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, - 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C -};*/ - -#endif /* SMTC */ ////////////////////////////////////////////////// // APPLICATION CALLBACKS @@ -118,21 +66,20 @@ // provide application router ID (8 bytes, LSBF) void os_getArtEui (u1_t* buf) { - //memcpy(buf, APPEUI, 8); - LMIC_reverse_memcpy(buf, reverse_APPEUI, 8); + LMIC_reverse_memcpy(buf, app_eui, sizeof(app_eui)); } // provide device ID (8 bytes, LSBF) void os_getDevEui (u1_t* buf) { - //memcpy(buf, DEVEUI, 8); - LMIC_reverse_memcpy(buf, reverse_DEVEUI, 8); + LMIC_reverse_memcpy(buf, dev_eui, sizeof(dev_eui)); } // provide device key (16 bytes) void os_getDevKey (u1_t* buf) { - memcpy(buf, DEVKEY, 16); + memcpy(buf, dev_key, sizeof(dev_key)); } + ////////////////////////////////////////////////// // MAIN - INITIALIZATION AND STARTUP ////////////////////////////////////////////////// @@ -144,74 +91,130 @@ first = pc_1; pc_7 = 0; if (first && !pc_1) { + gps.en_invert = 1; mote_version = MOTE_V2; - printf("v2\r\n"); - bat = new AnalogIn(PA_0); + bat = new AnalogIn(PA_0); } else { mote_version = MOTE_V3; - printf("v3\r\n"); bat = new AnalogIn(PA_1); + //gps.en_invert = 0; + gps_en = 0; } } +////////////////////////////////////////////////// +// Display network parameters (DevEUI, AppEUI etc) +////////////////////////////////////////////////// +void DisplayNetworkParam() +{ + int i; + + if(mote_version == MOTE_V2) + printf("\r\nNA Mote Ver. 2\r\n"); + else + if(mote_version == MOTE_V3) + printf("\r\nNA Mote Ver. 3\r\n"); + else + printf("\r\nNA Mote Ver. NOT DEFINED\r\n"); + + printf("DEVEUI:"); + for (i = 0; i < sizeof(dev_eui); i++) { + printf("%02x", dev_eui[i]); + if (i < sizeof(dev_eui)-1) + printf("-"); + } + printf("\r\n"); + + printf("APPEUI:"); + for (i = 0; i < sizeof(app_eui); i++) { + printf("%02x", app_eui[i]); + if (i < sizeof(app_eui)-1) + printf("-"); + } + printf("\r\n"); + + printf("DEVKEY:"); + for (i = 0; i < sizeof(dev_key); i++) { + printf("%02x ", dev_key[i]); + } + printf("\r\n"); +} + +void DisplayData(uint8_t *pData, int len) +{ + int i; + + for(i = 0; i < len; i++) + printf("%x ", pData[i]); + printf("\r\n"); +} + +osjob_t nJoinedJob; + +static void on_not_joined(osjob_t* j) +{ + if (joined) + return; + + DisplayNetworkParam(); + + os_setTimedCallback( &nJoinedJob, os_getTime() + ms2osticks(7000), on_not_joined ); +} + + // initial job -static void initfunc (osjob_t* j) { - debug_str("B: INITFUNC\n"); +static void initfunc (osjob_t* j) +{ + u4_t* id; + u4_t* u4_ptr; + + u4_ptr = (u4_t*)&dev_eui[4]; // [4] to [7] + + if(*u4_ptr == 0) + { + id = (u4_t*)0x1ff800d0; // STM32L1xx Cat3 + *u4_ptr = *id; + id = (u4_t*)0x1ff800d4; + *u4_ptr ^= *id; + id = (u4_t*)0x1ff800e4; + *u4_ptr ^= *id; + } + + get_mote_version(); + gps.init(); + + gps.enable(1); + mpl3115a2.init(); + // reset MAC state LMIC_reset(); + + os_setTimedCallback( &nJoinedJob, os_getTime() + ms2osticks(3000), on_not_joined ); + joined = false; // start joining -#if( OVER_THE_AIR_ACTIVATION != 0 ) LMIC_startJoining(); -#else - devaddr_t *serial_id = (devaddr_t *) 0x1FF800d0; // cat3 device stm32l152rc - LMIC_setSession( 0, *serial_id, NwkSKey, ArtSKey ); - debug_val("SN = ", *serial_id); -#endif + + led_red = LED_ON; // indicate joining + led_yellow = LED_OFF; + //led_green = LED_OFF; // init done - onEvent() callback will be invoked... - - //DEBUG_STR("E: INITFUNC"); - get_mote_version(); - if (mote_version == MOTE_V3) - gps.en_invert = false; - else - gps.en_invert = true; - - gps.init(); - gps.enable(1); - //gps.verbose = 1; - - mpl3115a2.init(); } -int main(void) -{ + +// application entry point +int main () { osjob_t initjob; // initialize runtime env os_init(); + // initialize debug library debug_init(); // setup initial job os_setCallback(&initjob, initfunc); // execute scheduled jobs and events os_runloop(); // (not reached) -} - -////////////////////////////////////////////////// -// LMIC EVENT CALLBACK -////////////////////////////////////////////////// -osjob_t rxLedJob; -osjob_t txLedJob; -osjob_t sendFrameJob; - -static void onRxLed (osjob_t* j) { - debug_val("LED2 = ", 1 ); - led2 = 1; -} - -static void onTxLed (osjob_t* j) { - debug_val("LED1 = ", 1 ); - led1 = 1; + return 0; } static void @@ -229,100 +232,140 @@ } } -static bool AppLedStateOn = false; - -#define AIN_VREF 3.3 // stm32 internal refernce -#define AIN_VBAT_DIV 2 // resistor divider -static void PrepareDataFrame( void ) -{ - uint16_t altitudeGps; - - restore_hsi(); - - gps.service(); - //printf("lat:%f long:%f\r\n", gps.Latitude, gps.Longitude); - mpl3115a2.ReadTemperature(); +osjob_t sendFrameJob; +osjob_t indicateJob; - // immediately prepare next transmission - //LMIC.frame[0] = LMIC.rxq.snr; - LMIC.frame[0] = AppLedStateOn; // (bit 0 == 1) => LED on - LMIC.frame[1] = (int)mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So, +/-63 C - LMIC.frame[2] = (bat->read_u16() >> 8) + (bat->read_u16() >> 9) ; // per LoRaMAC spec; 0=Charging; 1...254 = level, 255 = N/A - - LMIC.frame[3] = ( gps.LatitudeBinary >> 16 ) & 0xFF; - LMIC.frame[4] = ( gps.LatitudeBinary >> 8 ) & 0xFF; - LMIC.frame[5] = gps.LatitudeBinary & 0xFF; - LMIC.frame[6] = ( gps.LongitudeBinary >> 16 ) & 0xFF; - LMIC.frame[7] = ( gps.LongitudeBinary >> 8 ) & 0xFF; - LMIC.frame[8] = gps.LongitudeBinary & 0xFF; - - altitudeGps = atoi(gps.NmeaGpsData.NmeaAltitude); - //printf("alt:%d\r\n", altitudeGps); - LMIC.frame[9] = ( altitudeGps >> 8 ) & 0xFF; - LMIC.frame[10] = altitudeGps & 0xFF; - - - //printf("bat:%.2f\r\n", volts); -#ifndef CHNL_HYBRID - float volts = bat->read()*AIN_VREF*AIN_VBAT_DIV; - if (volts < LOW_BAT_THRESHOLD) - LMIC.txpow_limit = 20; - else - LMIC.txpow_limit = 30; -#endif /* !CHNL_HYBRID */ +static void tx_ind_cb(osjob_t* j) +{ + led_red = LED_OFF; } static void onSendFrame (osjob_t* j) { - if (LMIC.opmode & OP_TXRXPEND) + uint16_t altitudeGps; + + if (LMIC.opmode & OP_TXRXPEND) { return; + } + +#ifdef FIXED_DR + LMIC.datarate = FIXED_DR; +#endif + +#ifdef FIXED_TX_POWER + LMIC.txpow = FIXED_TX_POWER; +#endif + + restore_hsi(); + + if(LMIC.datarate == DR_SF8C) + LMIC.txpow_limit = DMTS_MAX_POW; + else +#ifdef CHNL_HYBRID + LMIC.txpow_limit = HS_MAX_POW; +#else + LMIC.txpow_limit = FHS_MAX_POW; +#endif + + if( LMIC.txpow > LMIC.txpow_limit) + LMIC.txpow = LMIC.txpow_limit; + + float volts = bat->read()*AIN_VREF*AIN_VBAT_DIV; + if (volts < LOW_BAT_THRESHOLD) { + if (LMIC.txpow_limit > 20) + LMIC.txpow_limit = 20; + if (LMIC.txpow > 20) + LMIC.txpow = 20; + } + + /////////////////////////////////////////////////////////////////// + gps.service(); + mpl3115a2.ReadTemperature(); + + uint8_t tmpData[PAYLOAD_LENGTH] = {0}; + + tmpData[0] = 15-(LMIC.txpow>>1); + tmpData[0] <<= 4; +#ifdef CHNL_HYBRID + tmpData[0] |= 0x04; // 8ch: set bit2 +#else + tmpData[0] |= 0x08; // 64ch: set bit3 +#endif + + tmpData[0] |= AppLedStateOn & 1; // (bit 0 == 1) => LED on + tmpData[1] = (int)mpl3115a2.Temperature; // Signed degrees Celcius in half degree units. So, +/-63 C + tmpData[2] = (bat->read_u16() >> 8) + (bat->read_u16() >> 9) ; // per LoRaMAC spec; 0=Charging; 1...254 = level, 255 = N/A + + tmpData[3] = ( gps.LatitudeBinary >> 16 ) & 0xFF; + tmpData[4] = ( gps.LatitudeBinary >> 8 ) & 0xFF; + tmpData[5] = gps.LatitudeBinary & 0xFF; + tmpData[6] = ( gps.LongitudeBinary >> 16 ) & 0xFF; + tmpData[7] = ( gps.LongitudeBinary >> 8 ) & 0xFF; + tmpData[8] = gps.LongitudeBinary & 0xFF; + + altitudeGps = atoi(gps.NmeaGpsData.NmeaAltitude); + tmpData[9] = ( altitudeGps >> 8 ) & 0xFF; + tmpData[10] = altitudeGps & 0xFF; + if (PAYLOAD_LENGTH > 11) { + for (int i = 11; i < PAYLOAD_LENGTH; i++) + tmpData[i] = i - 10; + } + + for(int i = 0; i < PAYLOAD_LENGTH; i++) + LMIC.frame[i] = tmpData[i]; - PrepareDataFrame( ); - // schedule transmission (port 1, data[], datalen 1, ACK requested) - // (will be sent as soon as duty cycle permits) - - LMIC_setTxData2(5, LMIC.frame, APP_DATA_SIZE, APP_ACK); + // port, buffer, buffer length, need_ack + LMIC_setTxData2(5, LMIC.frame, PAYLOAD_LENGTH, 0); + + led_red = LED_ON; + + // Display Info + + DisplayNetworkParam(); + + printf("Seq# %d\r\n",LMIC.seqnoUp-1); + + printf("TX Data: "); + DisplayData(tmpData, PAYLOAD_LENGTH); + + printf("TX Power: %d dBm\r\n",LMIC.txpow); + + printf("Battery: %f Volts\r\n",volts); + + os_setTimedCallback( &indicateJob, os_getTime() + ms2osticks(30), tx_ind_cb ); + } -void onEvent (ev_t ev) { - debug_event(ev); - - gps.service(); +////////////////////////////////////////////////// +// LMIC EVENT CALLBACK +////////////////////////////////////////////////// - switch(ev) - { - // network joined, session established - case EV_JOINED: - debug_val("Net ID = ", LMIC.netid); - goto tx; - // scheduled data sent (optionally data received) - case EV_TXCOMPLETE: - if(LMIC.dataLen) - { // data received in rx slot after tx - debug_buf(LMIC.frame+LMIC.dataBeg, LMIC.dataLen); - if(LMIC.dataLen == 1) { // set LED state if exactly one byte is received - AppLedStateOn = LMIC.frame[LMIC.dataBeg] & 0x01; - debug_val("LED3 = ", AppLedStateOn ? 0 : 1 ); +void onEvent (ev_t ev) +{ + debug_event(ev); + + switch(ev) { + case EV_JOINED: + // network joined, session established + debug_val("netid = ", LMIC.netid); + joined = true; + led_red = LED_OFF; // indicate joined + goto tx; + case EV_TXCOMPLETE: + // scheduled data sent (optionally data received) + if(LMIC.dataLen) { // data received in rx slot after tx + led_yellow = led_yellow ? 0 : 1; + if (LMIC.dataLen == 1) { // set LED state if exactly one byte is received + led_usr = LMIC.frame[LMIC.dataBeg] & 0x01; + } + debug_buf(LMIC.frame+LMIC.dataBeg, LMIC.dataLen); } - } - if((LMIC.txrxFlags & (TXRX_DNW1|TXRX_DNW2) )!= 0 ) - { - debug_val("LED2 = ", 0 ); - led2 = 0; - os_setTimedCallback( &rxLedJob, os_getTime() + ms2osticks(15), onRxLed ); - } tx: - os_setTimedCallback( &sendFrameJob, os_getTime() + ms2osticks(MS_DELAY_NEXT_TX), onSendFrame ); // Change the Tx periodicity - //onSendFrame(NULL); - - // Blink Tx LED - debug_val("LED1 = ", 0 ); - led1 = 0; - - os_setTimedCallback( &txLedJob, os_getTime() + ms2osticks(25), onTxLed ); - break; - default: - break; - } -} + os_setTimedCallback( &sendFrameJob, os_getTime() + ms2osticks(MS_DELAY_NEXT_TX), onSendFrame ); + break; + default: + led_red = LED_ON; // indicate not joined + break; + } // ..switch(ev) +} \ No newline at end of file