A very easy to understand LoRaWAN-node code.
Dependencies: LoRaWAN-lib SX1272Lib X_NUCLEO_IKS01A1 mbed
Important parameters:
• In comissioning.h: DevEUI, AppEUI, AppKEY, DevADR, NwksKEY, AppsKEY, OTAA and public network. Frequency and channel block to use, confirmed or unconfirmed messages, app port, app data size and OTAA and Tx duty cycles.
• In LoRaMac.h: Maximum payload and MAC commands length, receive delays, max FCNT, adr ack limit, timeout and delay, max ack retries, rssi threshold and sync words.
• In LoRaMac.cpp: Maximum payload, MAC commands and FRMpayload length.
• In LoRaMac-board.h: Tx power, data rates and band settings.
NOTE: Please refer to LoRaWAN regional parameters (page 12 for US band) to know which parameters you can modify.
Code/main.cpp@0:60ff878b27b8, 2018-04-03 (annotated)
- Committer:
- dgabino
- Date:
- Tue Apr 03 17:09:34 2018 +0000
- Revision:
- 0:60ff878b27b8
A simpler way to customize your LoRaWAN payload
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dgabino | 0:60ff878b27b8 | 1 | /* |
dgabino | 0:60ff878b27b8 | 2 | / _____) _ | | |
dgabino | 0:60ff878b27b8 | 3 | ( (____ _____ ____ _| |_ _____ ____| |__ |
dgabino | 0:60ff878b27b8 | 4 | \____ \| ___ | (_ _) ___ |/ ___) _ \ |
dgabino | 0:60ff878b27b8 | 5 | _____) ) ____| | | || |_| ____( (___| | | | |
dgabino | 0:60ff878b27b8 | 6 | (______/|_____)_|_|_| \__)_____)\____)_| |_| |
dgabino | 0:60ff878b27b8 | 7 | (C)2015 Semtech |
dgabino | 0:60ff878b27b8 | 8 | |
dgabino | 0:60ff878b27b8 | 9 | Description: LoRaMac classA device implementation |
dgabino | 0:60ff878b27b8 | 10 | |
dgabino | 0:60ff878b27b8 | 11 | License: Revised BSD License, see LICENSE.TXT file include in the project |
dgabino | 0:60ff878b27b8 | 12 | |
dgabino | 0:60ff878b27b8 | 13 | Maintainer: Miguel Luis and Gregory Cristian |
dgabino | 0:60ff878b27b8 | 14 | */ |
dgabino | 0:60ff878b27b8 | 15 | #include "mbed.h" |
dgabino | 0:60ff878b27b8 | 16 | #include "board.h" |
dgabino | 0:60ff878b27b8 | 17 | #include "radio.h" |
dgabino | 0:60ff878b27b8 | 18 | |
dgabino | 0:60ff878b27b8 | 19 | #include "LoRaMac.h" |
dgabino | 0:60ff878b27b8 | 20 | #include "Comissioning.h" |
dgabino | 0:60ff878b27b8 | 21 | #include "SerialDisplay.h" |
dgabino | 0:60ff878b27b8 | 22 | #include "LoRaDeviceFunctions.h" |
dgabino | 0:60ff878b27b8 | 23 | #include "LoRaMacLayerService.h" |
dgabino | 0:60ff878b27b8 | 24 | |
dgabino | 0:60ff878b27b8 | 25 | |
dgabino | 0:60ff878b27b8 | 26 | #if( OVER_THE_AIR_ACTIVATION != 0 ) |
dgabino | 0:60ff878b27b8 | 27 | |
dgabino | 0:60ff878b27b8 | 28 | uint8_t DevEui[] = LORAWAN_DEVICE_EUI; |
dgabino | 0:60ff878b27b8 | 29 | uint8_t AppEui[] = LORAWAN_APPLICATION_EUI; |
dgabino | 0:60ff878b27b8 | 30 | uint8_t AppKey[] = LORAWAN_APPLICATION_KEY; |
dgabino | 0:60ff878b27b8 | 31 | |
dgabino | 0:60ff878b27b8 | 32 | #else |
dgabino | 0:60ff878b27b8 | 33 | |
dgabino | 0:60ff878b27b8 | 34 | uint8_t NwkSKey[] = LORAWAN_NWKSKEY; |
dgabino | 0:60ff878b27b8 | 35 | uint8_t AppSKey[] = LORAWAN_APPSKEY; |
dgabino | 0:60ff878b27b8 | 36 | uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS; |
dgabino | 0:60ff878b27b8 | 37 | |
dgabino | 0:60ff878b27b8 | 38 | #endif |
dgabino | 0:60ff878b27b8 | 39 | |
dgabino | 0:60ff878b27b8 | 40 | |
dgabino | 0:60ff878b27b8 | 41 | uint8_t AppPort = LORAWAN_APP_PORT; //application port |
dgabino | 0:60ff878b27b8 | 42 | |
dgabino | 0:60ff878b27b8 | 43 | uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE; //data size |
dgabino | 0:60ff878b27b8 | 44 | |
dgabino | 0:60ff878b27b8 | 45 | uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE]; //payload array |
dgabino | 0:60ff878b27b8 | 46 | |
dgabino | 0:60ff878b27b8 | 47 | uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON; //Indicates if the node is sending confirmed or unconfirmed messages |
dgabino | 0:60ff878b27b8 | 48 | |
dgabino | 0:60ff878b27b8 | 49 | TimerEvent_t TxNextPacketTimer; //Timer to handle the application data transmission duty cycle |
dgabino | 0:60ff878b27b8 | 50 | |
dgabino | 0:60ff878b27b8 | 51 | bool IsTxIntUpdate = false; //Indicates if a new transmit interrupt can be set |
dgabino | 0:60ff878b27b8 | 52 | |
dgabino | 0:60ff878b27b8 | 53 | bool NextTx = true; //Indicates if a new packet can be sent |
dgabino | 0:60ff878b27b8 | 54 | |
dgabino | 0:60ff878b27b8 | 55 | bool IsNetworkJoinedStatusUpdate = false; //Indicates if the MAC layer network join status has changed. |
dgabino | 0:60ff878b27b8 | 56 | |
dgabino | 0:60ff878b27b8 | 57 | bool IsTxUpdate = false; //Indicates if the message sent. |
dgabino | 0:60ff878b27b8 | 58 | |
dgabino | 0:60ff878b27b8 | 59 | bool IsRxUpdate = false; //Indicates if the message received in the RX window. |
dgabino | 0:60ff878b27b8 | 60 | |
dgabino | 0:60ff878b27b8 | 61 | float sensor_data; //Used to store the sensor data |
dgabino | 0:60ff878b27b8 | 62 | |
dgabino | 0:60ff878b27b8 | 63 | uint32_t TxDutyCycleTime = APP_TX_DUTYCYCLE; |
dgabino | 0:60ff878b27b8 | 64 | |
dgabino | 0:60ff878b27b8 | 65 | eDevicState DeviceState; |
dgabino | 0:60ff878b27b8 | 66 | |
dgabino | 0:60ff878b27b8 | 67 | sLoRaMacUplinkStatus LoRaMacUplinkStatus; |
dgabino | 0:60ff878b27b8 | 68 | |
dgabino | 0:60ff878b27b8 | 69 | sLoRaMacDownlinkStatus LoRaMacDownlinkStatus; |
dgabino | 0:60ff878b27b8 | 70 | |
dgabino | 0:60ff878b27b8 | 71 | LoRaMacPrimitives_t LoRaPrimitives; |
dgabino | 0:60ff878b27b8 | 72 | |
dgabino | 0:60ff878b27b8 | 73 | LoRaMacCallback_t LoRaCallbacks; |
dgabino | 0:60ff878b27b8 | 74 | |
dgabino | 0:60ff878b27b8 | 75 | MibRequestConfirm_t LoRaMibReq; |
dgabino | 0:60ff878b27b8 | 76 | |
dgabino | 0:60ff878b27b8 | 77 | MlmeReq_t mlmeReq; |
dgabino | 0:60ff878b27b8 | 78 | |
dgabino | 0:60ff878b27b8 | 79 | uint16_t ChannelMaskTemp[6] = {0}; |
dgabino | 0:60ff878b27b8 | 80 | |
dgabino | 0:60ff878b27b8 | 81 | uint8_t BoardGetBatteryLevel( void ) |
dgabino | 0:60ff878b27b8 | 82 | { |
dgabino | 0:60ff878b27b8 | 83 | return 0xFE; |
dgabino | 0:60ff878b27b8 | 84 | } |
dgabino | 0:60ff878b27b8 | 85 | DigitalIn I2cInterrupt( D5 ); |
dgabino | 0:60ff878b27b8 | 86 | I2C I2c(I2C_SDA, I2C_SCL); |
dgabino | 0:60ff878b27b8 | 87 | |
dgabino | 0:60ff878b27b8 | 88 | DigitalOut Pc7( D9 ); |
dgabino | 0:60ff878b27b8 | 89 | DigitalIn Pc1( A4 ); |
dgabino | 0:60ff878b27b8 | 90 | |
dgabino | 0:60ff878b27b8 | 91 | //DigitalIn UsrButton( PC_13 ); |
dgabino | 0:60ff878b27b8 | 92 | DigitalIn UsrButton( D10 ); |
dgabino | 0:60ff878b27b8 | 93 | |
dgabino | 0:60ff878b27b8 | 94 | DigitalOut Led( D6 ); |
dgabino | 0:60ff878b27b8 | 95 | |
dgabino | 0:60ff878b27b8 | 96 | #ifdef USE_IKS01A1_SENSOR |
dgabino | 0:60ff878b27b8 | 97 | X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(); |
dgabino | 0:60ff878b27b8 | 98 | MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer(); |
dgabino | 0:60ff878b27b8 | 99 | HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;; |
dgabino | 0:60ff878b27b8 | 100 | PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor; |
dgabino | 0:60ff878b27b8 | 101 | TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor; |
dgabino | 0:60ff878b27b8 | 102 | TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor; |
dgabino | 0:60ff878b27b8 | 103 | #endif |
dgabino | 0:60ff878b27b8 | 104 | |
dgabino | 0:60ff878b27b8 | 105 | SX1272MB2xAS Radio( NULL ); |
dgabino | 0:60ff878b27b8 | 106 | |
dgabino | 0:60ff878b27b8 | 107 | |
dgabino | 0:60ff878b27b8 | 108 | uint32_t BoardGetRandomSeed( void ) |
dgabino | 0:60ff878b27b8 | 109 | { |
dgabino | 0:60ff878b27b8 | 110 | return ( ( *( uint32_t* )ID1 ) ^ ( *( uint32_t* )ID2 ) ^ ( *( uint32_t* )ID3 ) ); |
dgabino | 0:60ff878b27b8 | 111 | } |
dgabino | 0:60ff878b27b8 | 112 | |
dgabino | 0:60ff878b27b8 | 113 | void BoardGetDevEUI( uint8_t *id ) |
dgabino | 0:60ff878b27b8 | 114 | { |
dgabino | 0:60ff878b27b8 | 115 | uint32_t *pDevEuiHWord = ( uint32_t* )&id[4]; |
dgabino | 0:60ff878b27b8 | 116 | |
dgabino | 0:60ff878b27b8 | 117 | if( *pDevEuiHWord == 0 ) |
dgabino | 0:60ff878b27b8 | 118 | { |
dgabino | 0:60ff878b27b8 | 119 | *pDevEuiHWord = BoardGetRandomSeed( ); |
dgabino | 0:60ff878b27b8 | 120 | } |
dgabino | 0:60ff878b27b8 | 121 | |
dgabino | 0:60ff878b27b8 | 122 | } |
dgabino | 0:60ff878b27b8 | 123 | |
dgabino | 0:60ff878b27b8 | 124 | static void OnTxNextPacketTimerEvent( void ) |
dgabino | 0:60ff878b27b8 | 125 | { |
dgabino | 0:60ff878b27b8 | 126 | MibRequestConfirm_t mibReq; |
dgabino | 0:60ff878b27b8 | 127 | LoRaMacStatus_t status; |
dgabino | 0:60ff878b27b8 | 128 | |
dgabino | 0:60ff878b27b8 | 129 | TimerStop( &TxNextPacketTimer ); |
dgabino | 0:60ff878b27b8 | 130 | |
dgabino | 0:60ff878b27b8 | 131 | mibReq.Type = MIB_NETWORK_JOINED; |
dgabino | 0:60ff878b27b8 | 132 | status = LoRaMacMibGetRequestConfirm( &mibReq ); |
dgabino | 0:60ff878b27b8 | 133 | |
dgabino | 0:60ff878b27b8 | 134 | if( status == LORAMAC_STATUS_OK ) |
dgabino | 0:60ff878b27b8 | 135 | { |
dgabino | 0:60ff878b27b8 | 136 | if( mibReq.Param.IsNetworkJoined == true ) |
dgabino | 0:60ff878b27b8 | 137 | { |
dgabino | 0:60ff878b27b8 | 138 | DeviceState = DEVICE_STATE_SEND; |
dgabino | 0:60ff878b27b8 | 139 | } |
dgabino | 0:60ff878b27b8 | 140 | else |
dgabino | 0:60ff878b27b8 | 141 | { |
dgabino | 0:60ff878b27b8 | 142 | DeviceState = DEVICE_STATE_JOIN; |
dgabino | 0:60ff878b27b8 | 143 | } |
dgabino | 0:60ff878b27b8 | 144 | NextTx = true; |
dgabino | 0:60ff878b27b8 | 145 | } |
dgabino | 0:60ff878b27b8 | 146 | } |
dgabino | 0:60ff878b27b8 | 147 | |
dgabino | 0:60ff878b27b8 | 148 | bool SendFrame( void ) |
dgabino | 0:60ff878b27b8 | 149 | { |
dgabino | 0:60ff878b27b8 | 150 | McpsReq_t mcpsReq; |
dgabino | 0:60ff878b27b8 | 151 | LoRaMacTxInfo_t txInfo; |
dgabino | 0:60ff878b27b8 | 152 | |
dgabino | 0:60ff878b27b8 | 153 | if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK ) |
dgabino | 0:60ff878b27b8 | 154 | { |
dgabino | 0:60ff878b27b8 | 155 | // Send empty frame in order to flush MAC commands |
dgabino | 0:60ff878b27b8 | 156 | mcpsReq.Type = MCPS_UNCONFIRMED; |
dgabino | 0:60ff878b27b8 | 157 | mcpsReq.Req.Unconfirmed.fBuffer = NULL; |
dgabino | 0:60ff878b27b8 | 158 | mcpsReq.Req.Unconfirmed.fBufferSize = 0; |
dgabino | 0:60ff878b27b8 | 159 | mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE; |
dgabino | 0:60ff878b27b8 | 160 | |
dgabino | 0:60ff878b27b8 | 161 | LoRaMacUplinkStatus.Acked = false; |
dgabino | 0:60ff878b27b8 | 162 | LoRaMacUplinkStatus.Port = 0; |
dgabino | 0:60ff878b27b8 | 163 | LoRaMacUplinkStatus.Buffer = NULL; |
dgabino | 0:60ff878b27b8 | 164 | LoRaMacUplinkStatus.BufferSize = 0; |
dgabino | 0:60ff878b27b8 | 165 | } |
dgabino | 0:60ff878b27b8 | 166 | else |
dgabino | 0:60ff878b27b8 | 167 | { |
dgabino | 0:60ff878b27b8 | 168 | LoRaMacUplinkStatus.Acked = false; |
dgabino | 0:60ff878b27b8 | 169 | LoRaMacUplinkStatus.Port = AppPort; |
dgabino | 0:60ff878b27b8 | 170 | LoRaMacUplinkStatus.Buffer = AppData; |
dgabino | 0:60ff878b27b8 | 171 | LoRaMacUplinkStatus.BufferSize = AppDataSize; |
dgabino | 0:60ff878b27b8 | 172 | |
dgabino | 0:60ff878b27b8 | 173 | if( ( IsTxConfirmed == false ) || ( LoRaMacUplinkStatus.UplinkCounter == 0 ) ) |
dgabino | 0:60ff878b27b8 | 174 | { |
dgabino | 0:60ff878b27b8 | 175 | mcpsReq.Type = MCPS_UNCONFIRMED; |
dgabino | 0:60ff878b27b8 | 176 | mcpsReq.Req.Unconfirmed.fPort = AppPort; |
dgabino | 0:60ff878b27b8 | 177 | mcpsReq.Req.Unconfirmed.fBuffer = AppData; |
dgabino | 0:60ff878b27b8 | 178 | mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize; |
dgabino | 0:60ff878b27b8 | 179 | mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE; |
dgabino | 0:60ff878b27b8 | 180 | } |
dgabino | 0:60ff878b27b8 | 181 | else |
dgabino | 0:60ff878b27b8 | 182 | { |
dgabino | 0:60ff878b27b8 | 183 | mcpsReq.Type = MCPS_CONFIRMED; |
dgabino | 0:60ff878b27b8 | 184 | mcpsReq.Req.Confirmed.fPort = AppPort; |
dgabino | 0:60ff878b27b8 | 185 | mcpsReq.Req.Confirmed.fBuffer = AppData; |
dgabino | 0:60ff878b27b8 | 186 | mcpsReq.Req.Confirmed.fBufferSize = AppDataSize; |
dgabino | 0:60ff878b27b8 | 187 | mcpsReq.Req.Confirmed.NbTrials = 8; |
dgabino | 0:60ff878b27b8 | 188 | mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE; |
dgabino | 0:60ff878b27b8 | 189 | } |
dgabino | 0:60ff878b27b8 | 190 | } |
dgabino | 0:60ff878b27b8 | 191 | |
dgabino | 0:60ff878b27b8 | 192 | LoRaMacUplinkStatus.Type = mcpsReq.Type; |
dgabino | 0:60ff878b27b8 | 193 | |
dgabino | 0:60ff878b27b8 | 194 | if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK ) |
dgabino | 0:60ff878b27b8 | 195 | { |
dgabino | 0:60ff878b27b8 | 196 | return false; |
dgabino | 0:60ff878b27b8 | 197 | } |
dgabino | 0:60ff878b27b8 | 198 | return true; |
dgabino | 0:60ff878b27b8 | 199 | } |
dgabino | 0:60ff878b27b8 | 200 | |
dgabino | 0:60ff878b27b8 | 201 | int main( void ) |
dgabino | 0:60ff878b27b8 | 202 | { |
dgabino | 0:60ff878b27b8 | 203 | |
dgabino | 0:60ff878b27b8 | 204 | TimerTimeCounterInit( ); //initialize timer |
dgabino | 0:60ff878b27b8 | 205 | |
dgabino | 0:60ff878b27b8 | 206 | DeviceState = DEVICE_STATE_INIT; // Indicate Device state |
dgabino | 0:60ff878b27b8 | 207 | |
dgabino | 0:60ff878b27b8 | 208 | while( 1 ) |
dgabino | 0:60ff878b27b8 | 209 | { |
dgabino | 0:60ff878b27b8 | 210 | if( IsNetworkJoinedStatusUpdate == true ) |
dgabino | 0:60ff878b27b8 | 211 | { |
dgabino | 0:60ff878b27b8 | 212 | //Checks if the device has joined the server and updates the joined status |
dgabino | 0:60ff878b27b8 | 213 | IsNetworkJoinedStatusUpdate = false; |
dgabino | 0:60ff878b27b8 | 214 | LoRaMibReq.Type = MIB_NETWORK_JOINED; |
dgabino | 0:60ff878b27b8 | 215 | LoRaMacMibGetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 216 | } |
dgabino | 0:60ff878b27b8 | 217 | |
dgabino | 0:60ff878b27b8 | 218 | if( IsTxIntUpdate == true ) |
dgabino | 0:60ff878b27b8 | 219 | { |
dgabino | 0:60ff878b27b8 | 220 | // Initialize next Tx Interrupt |
dgabino | 0:60ff878b27b8 | 221 | IsTxIntUpdate = false; |
dgabino | 0:60ff878b27b8 | 222 | TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime ); |
dgabino | 0:60ff878b27b8 | 223 | TimerStart( &TxNextPacketTimer ); |
dgabino | 0:60ff878b27b8 | 224 | |
dgabino | 0:60ff878b27b8 | 225 | } |
dgabino | 0:60ff878b27b8 | 226 | |
dgabino | 0:60ff878b27b8 | 227 | if( IsRxUpdate == true ) |
dgabino | 0:60ff878b27b8 | 228 | { |
dgabino | 0:60ff878b27b8 | 229 | // If downlink received then update Serial Terminal Rx parameters |
dgabino | 0:60ff878b27b8 | 230 | IsRxUpdate = false; |
dgabino | 0:60ff878b27b8 | 231 | SerialDisplayRxUpdate( ); |
dgabino | 0:60ff878b27b8 | 232 | } |
dgabino | 0:60ff878b27b8 | 233 | |
dgabino | 0:60ff878b27b8 | 234 | switch( DeviceState ) //realizes different tasks depending on device state |
dgabino | 0:60ff878b27b8 | 235 | { |
dgabino | 0:60ff878b27b8 | 236 | case DEVICE_STATE_INIT: |
dgabino | 0:60ff878b27b8 | 237 | { |
dgabino | 0:60ff878b27b8 | 238 | |
dgabino | 0:60ff878b27b8 | 239 | LoRaPrimitives.MacMcpsConfirm = McpsConfirm; //Update uplink and event info status |
dgabino | 0:60ff878b27b8 | 240 | LoRaPrimitives.MacMcpsIndication = McpsIndication; // |
dgabino | 0:60ff878b27b8 | 241 | LoRaPrimitives.MacMlmeConfirm = MlmeConfirm; |
dgabino | 0:60ff878b27b8 | 242 | LoRaCallbacks.GetBatteryLevel = BoardGetBatteryLevel; //0: external power source, 1-254: battery level, 255: couldnt measure battery level |
dgabino | 0:60ff878b27b8 | 243 | LoRaMacInitialization( &LoRaPrimitives, &LoRaCallbacks ); //Sets radio parameters (channels, frequency, timers, windows) |
dgabino | 0:60ff878b27b8 | 244 | |
dgabino | 0:60ff878b27b8 | 245 | TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent ); |
dgabino | 0:60ff878b27b8 | 246 | |
dgabino | 0:60ff878b27b8 | 247 | LoRaMibReq.Type = MIB_ADR; |
dgabino | 0:60ff878b27b8 | 248 | LoRaMibReq.Param.AdrEnable = LORAWAN_ADR_ON; |
dgabino | 0:60ff878b27b8 | 249 | LoRaMacMibSetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 250 | |
dgabino | 0:60ff878b27b8 | 251 | LoRaMibReq.Type = MIB_PUBLIC_NETWORK; |
dgabino | 0:60ff878b27b8 | 252 | LoRaMibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK; |
dgabino | 0:60ff878b27b8 | 253 | LoRaMacMibSetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 254 | |
dgabino | 0:60ff878b27b8 | 255 | LoRaMibReq.Type = MIB_CHANNELS_TX_POWER; |
dgabino | 0:60ff878b27b8 | 256 | LoRaMibReq.Param.ChannelsTxPower = LORAWAN_TX_POWER; |
dgabino | 0:60ff878b27b8 | 257 | LoRaMacMibSetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 258 | |
dgabino | 0:60ff878b27b8 | 259 | LoRaMibReq.Type = MIB_CHANNELS_MASK; |
dgabino | 0:60ff878b27b8 | 260 | LoRaMibReq.Param.ChannelsMask = ChannelMaskTemp; |
dgabino | 0:60ff878b27b8 | 261 | //channel mask for USE_BAND_915_HYBRID |
dgabino | 0:60ff878b27b8 | 262 | ChannelMaskTemp[0] = 0x00FF; |
dgabino | 0:60ff878b27b8 | 263 | ChannelMaskTemp[1] = 0x0000; |
dgabino | 0:60ff878b27b8 | 264 | ChannelMaskTemp[2] = 0x0000; |
dgabino | 0:60ff878b27b8 | 265 | ChannelMaskTemp[3] = 0x0000; |
dgabino | 0:60ff878b27b8 | 266 | ChannelMaskTemp[4] = 0x0001; |
dgabino | 0:60ff878b27b8 | 267 | LoRaMacMibSetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 268 | |
dgabino | 0:60ff878b27b8 | 269 | LoRaMacDownlinkStatus.DownlinkCounter = 0; |
dgabino | 0:60ff878b27b8 | 270 | |
dgabino | 0:60ff878b27b8 | 271 | DeviceState = DEVICE_STATE_JOIN; // Change Device state |
dgabino | 0:60ff878b27b8 | 272 | break; |
dgabino | 0:60ff878b27b8 | 273 | } |
dgabino | 0:60ff878b27b8 | 274 | case DEVICE_STATE_JOIN: |
dgabino | 0:60ff878b27b8 | 275 | { |
dgabino | 0:60ff878b27b8 | 276 | #if( OVER_THE_AIR_ACTIVATION != 0 ) // OTAA |
dgabino | 0:60ff878b27b8 | 277 | |
dgabino | 0:60ff878b27b8 | 278 | BoardGetDevEUI( DevEui ); // Generate DevEUI if not defined by User |
dgabino | 0:60ff878b27b8 | 279 | |
dgabino | 0:60ff878b27b8 | 280 | mlmeReq.Type = MLME_JOIN; //Changes Mlmereq content to send in join request |
dgabino | 0:60ff878b27b8 | 281 | mlmeReq.Req.Join.DevEui = DevEui; |
dgabino | 0:60ff878b27b8 | 282 | mlmeReq.Req.Join.AppEui = AppEui; |
dgabino | 0:60ff878b27b8 | 283 | mlmeReq.Req.Join.AppKey = AppKey; |
dgabino | 0:60ff878b27b8 | 284 | |
dgabino | 0:60ff878b27b8 | 285 | if( NextTx == true ) |
dgabino | 0:60ff878b27b8 | 286 | { |
dgabino | 0:60ff878b27b8 | 287 | LoRaMacMlmeRequest( &mlmeReq ); |
dgabino | 0:60ff878b27b8 | 288 | } |
dgabino | 0:60ff878b27b8 | 289 | |
dgabino | 0:60ff878b27b8 | 290 | SerialDisplayJoinUpdate( ); // Show on serial terminal |
dgabino | 0:60ff878b27b8 | 291 | |
dgabino | 0:60ff878b27b8 | 292 | DeviceState = DEVICE_STATE_SLEEP; |
dgabino | 0:60ff878b27b8 | 293 | |
dgabino | 0:60ff878b27b8 | 294 | #else // ABP |
dgabino | 0:60ff878b27b8 | 295 | |
dgabino | 0:60ff878b27b8 | 296 | // Choose a random device address if not already defined in Config.h |
dgabino | 0:60ff878b27b8 | 297 | if( DevAddr == 0 ) |
dgabino | 0:60ff878b27b8 | 298 | { |
dgabino | 0:60ff878b27b8 | 299 | // Random seed initialization |
dgabino | 0:60ff878b27b8 | 300 | srand1( BoardGetRandomSeed( ) ); |
dgabino | 0:60ff878b27b8 | 301 | DevAddr = randr( 0, 0x01FFFFFF ); |
dgabino | 0:60ff878b27b8 | 302 | } |
dgabino | 0:60ff878b27b8 | 303 | |
dgabino | 0:60ff878b27b8 | 304 | LoRaMibReq.Type = MIB_NET_ID; |
dgabino | 0:60ff878b27b8 | 305 | LoRaMibReq.Param.NetID = LORAWAN_NETWORK_ID; |
dgabino | 0:60ff878b27b8 | 306 | LoRaMacMibSetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 307 | |
dgabino | 0:60ff878b27b8 | 308 | LoRaMibReq.Type = MIB_DEV_ADDR; |
dgabino | 0:60ff878b27b8 | 309 | LoRaMibReq.Param.DevAddr = DevAddr; |
dgabino | 0:60ff878b27b8 | 310 | LoRaMacMibSetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 311 | |
dgabino | 0:60ff878b27b8 | 312 | LoRaMibReq.Type = MIB_NWK_SKEY; |
dgabino | 0:60ff878b27b8 | 313 | LoRaMibReq.Param.NwkSKey = NwkSKey; |
dgabino | 0:60ff878b27b8 | 314 | LoRaMacMibSetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 315 | |
dgabino | 0:60ff878b27b8 | 316 | LoRaMibReq.Type = MIB_APP_SKEY; |
dgabino | 0:60ff878b27b8 | 317 | LoRaMibReq.Param.AppSKey = AppSKey; |
dgabino | 0:60ff878b27b8 | 318 | LoRaMacMibSetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 319 | |
dgabino | 0:60ff878b27b8 | 320 | LoRaMibReq.Type = MIB_NETWORK_JOINED; |
dgabino | 0:60ff878b27b8 | 321 | LoRaMibReq.Param.IsNetworkJoined = true; |
dgabino | 0:60ff878b27b8 | 322 | LoRaMacMibSetRequestConfirm( &LoRaMibReq ); |
dgabino | 0:60ff878b27b8 | 323 | |
dgabino | 0:60ff878b27b8 | 324 | DeviceState = DEVICE_STATE_SEND; |
dgabino | 0:60ff878b27b8 | 325 | #endif |
dgabino | 0:60ff878b27b8 | 326 | IsNetworkJoinedStatusUpdate = true; |
dgabino | 0:60ff878b27b8 | 327 | break; |
dgabino | 0:60ff878b27b8 | 328 | } |
dgabino | 0:60ff878b27b8 | 329 | case DEVICE_STATE_SEND: |
dgabino | 0:60ff878b27b8 | 330 | { |
dgabino | 0:60ff878b27b8 | 331 | |
dgabino | 0:60ff878b27b8 | 332 | if( NextTx == true ) |
dgabino | 0:60ff878b27b8 | 333 | { |
dgabino | 0:60ff878b27b8 | 334 | //===============Functions to get X_NUCLEO_IKS01A1 sensor data=============== |
dgabino | 0:60ff878b27b8 | 335 | |
dgabino | 0:60ff878b27b8 | 336 | temp_sensor2->GetTemperature(&sensor_data); |
dgabino | 0:60ff878b27b8 | 337 | int16_t tmp_data = (int16_t) (sensor_data*10 + 0.5); |
dgabino | 0:60ff878b27b8 | 338 | AppData[2] = (int8_t) ( ( tmp_data >> 8 ) & 0xFF ); |
dgabino | 0:60ff878b27b8 | 339 | AppData[3] = (int8_t) tmp_data & 0xFF; |
dgabino | 0:60ff878b27b8 | 340 | |
dgabino | 0:60ff878b27b8 | 341 | pressure_sensor->GetPressure(&sensor_data); |
dgabino | 0:60ff878b27b8 | 342 | int16_t tmp = (int16_t) ( sensor_data * 10 ); |
dgabino | 0:60ff878b27b8 | 343 | AppData[6] = ( tmp >> 8 ) & 0xFF; |
dgabino | 0:60ff878b27b8 | 344 | AppData[7] = ( tmp ) & 0xFF; |
dgabino | 0:60ff878b27b8 | 345 | |
dgabino | 0:60ff878b27b8 | 346 | humidity_sensor->GetHumidity(&sensor_data); |
dgabino | 0:60ff878b27b8 | 347 | AppData[10] = (uint8_t) ( sensor_data * 2 ); |
dgabino | 0:60ff878b27b8 | 348 | |
dgabino | 0:60ff878b27b8 | 349 | //accelerometer->Get_X_Axes(Accl_Value); |
dgabino | 0:60ff878b27b8 | 350 | //AppData[BuffPtr++] = ( (int16_t) Accl_Value[0] >> 8 ) & 0xFF; |
dgabino | 0:60ff878b27b8 | 351 | //AppData[BuffPtr++] = ( (int16_t) Accl_Value[0] ) & 0xFF; |
dgabino | 0:60ff878b27b8 | 352 | //AppData[BuffPtr++] = ( (int16_t) Accl_Value[1] >> 8 ) & 0xFF; |
dgabino | 0:60ff878b27b8 | 353 | //AppData[BuffPtr++] = ( (int16_t) Accl_Value[1] ) & 0xFF; |
dgabino | 0:60ff878b27b8 | 354 | //AppData[BuffPtr++] = ( (int16_t) Accl_Value[2] >> 8 ) & 0xFF; |
dgabino | 0:60ff878b27b8 | 355 | //AppData[BuffPtr++] = ( (int16_t) Accl_Value[2] ) & 0xFF; |
dgabino | 0:60ff878b27b8 | 356 | //===========================Custom payload============================ |
dgabino | 0:60ff878b27b8 | 357 | |
dgabino | 0:60ff878b27b8 | 358 | //In this case the custom payload is the cayene LPP structure for the sensors data |
dgabino | 0:60ff878b27b8 | 359 | AppData[0]=0x01; |
dgabino | 0:60ff878b27b8 | 360 | AppData[1]=0x67; |
dgabino | 0:60ff878b27b8 | 361 | |
dgabino | 0:60ff878b27b8 | 362 | AppData[4]=0x02; |
dgabino | 0:60ff878b27b8 | 363 | AppData[5]=0x73; |
dgabino | 0:60ff878b27b8 | 364 | |
dgabino | 0:60ff878b27b8 | 365 | AppData[8]=0x03; |
dgabino | 0:60ff878b27b8 | 366 | AppData[9]=0x68; |
dgabino | 0:60ff878b27b8 | 367 | |
dgabino | 0:60ff878b27b8 | 368 | |
dgabino | 0:60ff878b27b8 | 369 | //=========================Cayenne LPP format======================= |
dgabino | 0:60ff878b27b8 | 370 | /* |
dgabino | 0:60ff878b27b8 | 371 | STRUCTURE: |
dgabino | 0:60ff878b27b8 | 372 | |
dgabino | 0:60ff878b27b8 | 373 | 1 Byte 1 Byte N Bytes 1 Byte 1 Byte M Bytes ... |
dgabino | 0:60ff878b27b8 | 374 | |
dgabino | 0:60ff878b27b8 | 375 | Data1 Ch. Data1 Type Data1 Data2 Ch. Data2 Type Data2 ... |
dgabino | 0:60ff878b27b8 | 376 | |
dgabino | 0:60ff878b27b8 | 377 | COMMON TYP IDENTIFIERS AND RESOLUTIONS: |
dgabino | 0:60ff878b27b8 | 378 | |
dgabino | 0:60ff878b27b8 | 379 | TYPE LPP HEX DATA SIZE RESOLUTION PER BIT |
dgabino | 0:60ff878b27b8 | 380 | |
dgabino | 0:60ff878b27b8 | 381 | Temperature 103 67 2 0.1 °C Signed MSB |
dgabino | 0:60ff878b27b8 | 382 | Humidity 104 68 1 0.5 % Unsigned |
dgabino | 0:60ff878b27b8 | 383 | Accelerometer 113 71 6 0.001 G Signed MSB per axis |
dgabino | 0:60ff878b27b8 | 384 | Barometer 115 73 2 0.1 hPa Unsigned MSB |
dgabino | 0:60ff878b27b8 | 385 | |
dgabino | 0:60ff878b27b8 | 386 | */ |
dgabino | 0:60ff878b27b8 | 387 | // Send payload over the air |
dgabino | 0:60ff878b27b8 | 388 | NextTx = SendFrame( ); |
dgabino | 0:60ff878b27b8 | 389 | } |
dgabino | 0:60ff878b27b8 | 390 | |
dgabino | 0:60ff878b27b8 | 391 | if( NextTx == false ) |
dgabino | 0:60ff878b27b8 | 392 | { |
dgabino | 0:60ff878b27b8 | 393 | |
dgabino | 0:60ff878b27b8 | 394 | SerialDisplayTxUpdate( ); |
dgabino | 0:60ff878b27b8 | 395 | } |
dgabino | 0:60ff878b27b8 | 396 | |
dgabino | 0:60ff878b27b8 | 397 | DeviceState = DEVICE_STATE_SLEEP; |
dgabino | 0:60ff878b27b8 | 398 | break; |
dgabino | 0:60ff878b27b8 | 399 | } |
dgabino | 0:60ff878b27b8 | 400 | case DEVICE_STATE_SLEEP: |
dgabino | 0:60ff878b27b8 | 401 | { |
dgabino | 0:60ff878b27b8 | 402 | break; |
dgabino | 0:60ff878b27b8 | 403 | } |
dgabino | 0:60ff878b27b8 | 404 | default: |
dgabino | 0:60ff878b27b8 | 405 | { |
dgabino | 0:60ff878b27b8 | 406 | DeviceState = DEVICE_STATE_INIT; |
dgabino | 0:60ff878b27b8 | 407 | break; |
dgabino | 0:60ff878b27b8 | 408 | } |
dgabino | 0:60ff878b27b8 | 409 | } |
dgabino | 0:60ff878b27b8 | 410 | } |
dgabino | 0:60ff878b27b8 | 411 | } |