kopia lustrzana https://github.com/helium/longfi-arduino
237 wiersze
7.4 KiB
C++
237 wiersze
7.4 KiB
C++
#include <Arduino.h>
|
|
|
|
/**
|
|
* @file LoRaWAN_OTAA.ino
|
|
* @author rakwireless.com
|
|
* @brief LoRaWan node example with OTAA registration
|
|
* @version 0.1
|
|
* @date 2020-08-21
|
|
*
|
|
* @copyright Copyright (c) 2020
|
|
*
|
|
* @note RAK5005-O GPIO mapping to RAK4631 GPIO ports
|
|
RAK5005-O <-> nRF52840
|
|
IO1 <-> P0.17 (Arduino GPIO number 17)
|
|
IO2 <-> P1.02 (Arduino GPIO number 34)
|
|
IO3 <-> P0.21 (Arduino GPIO number 21)
|
|
IO4 <-> P0.04 (Arduino GPIO number 4)
|
|
IO5 <-> P0.09 (Arduino GPIO number 9)
|
|
IO6 <-> P0.10 (Arduino GPIO number 10)
|
|
SW1 <-> P0.01 (Arduino GPIO number 1)
|
|
A0 <-> P0.04/AIN2 (Arduino Analog A2
|
|
A1 <-> P0.31/AIN7 (Arduino Analog A7
|
|
SPI_CS <-> P0.26 (Arduino GPIO number 26)
|
|
*/
|
|
#include <Arduino.h>
|
|
#include <LoRaWan-RAK4630.h> //http://librarymanager/All#SX126x
|
|
#include <SPI.h>
|
|
|
|
// RAK4630 supply two LED
|
|
#ifndef LED_BUILTIN
|
|
#define LED_BUILTIN 35
|
|
#endif
|
|
|
|
#ifndef LED_BUILTIN2
|
|
#define LED_BUILTIN2 36
|
|
#endif
|
|
|
|
bool doOTAA = true;
|
|
#define SCHED_MAX_EVENT_DATA_SIZE APP_TIMER_SCHED_EVENT_DATA_SIZE /**< Maximum size of scheduler events. */
|
|
#define SCHED_QUEUE_SIZE 60 /**< Maximum number of events in the scheduler queue. */
|
|
#define LORAWAN_DATERATE DR_0 /*LoRaMac datarates definition, from DR_0 to DR_5*/
|
|
#define LORAWAN_TX_POWER TX_POWER_5 /*LoRaMac tx power definition, from TX_POWER_0 to TX_POWER_15*/
|
|
#define JOINREQ_NBTRIALS 3 /**< Number of trials for the join request. */
|
|
DeviceClass_t gCurrentClass = CLASS_A; /* class definition*/
|
|
lmh_confirm gCurrentConfirm = LMH_UNCONFIRMED_MSG; /* confirm/unconfirm packet definition*/
|
|
uint8_t gAppPort = LORAWAN_APP_PORT; /* data port*/
|
|
|
|
/**@brief Structure containing LoRaWan parameters, needed for lmh_init()
|
|
*/
|
|
static lmh_param_t lora_param_init = {LORAWAN_ADR_ON, LORAWAN_DATERATE, LORAWAN_PUBLIC_NETWORK, JOINREQ_NBTRIALS, LORAWAN_TX_POWER, LORAWAN_DUTYCYCLE_OFF};
|
|
|
|
// Foward declaration
|
|
static void lorawan_has_joined_handler(void);
|
|
static void lorawan_join_failed_handler(void);
|
|
static void lorawan_rx_handler(lmh_app_data_t *app_data);
|
|
static void lorawan_confirm_class_handler(DeviceClass_t Class);
|
|
static void send_lora_frame(void);
|
|
|
|
/**@brief Structure containing LoRaWan callback functions, needed for lmh_init()
|
|
*/
|
|
static lmh_callback_t lora_callbacks = {BoardGetBatteryLevel, BoardGetUniqueId, BoardGetRandomSeed,
|
|
lorawan_rx_handler, lorawan_has_joined_handler, lorawan_confirm_class_handler, lorawan_join_failed_handler};
|
|
|
|
//OTAA keys !!!! KEYS ARE MSB !!!!
|
|
NOTE: FILL IN THE THREE REQUIRED HELIUM NETWORK CREDENTIALS WITH YOUR VALUES AND DELETE THIS LINE
|
|
|
|
uint8_t nodeDeviceEUI[8] = {0x00, 0x00, 0xDA, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
uint8_t nodeAppEUI[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
uint8_t nodeAppKey[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|
|
|
// Define the LoRaWan Region of choice
|
|
// refer to the runtime support library file LoRaMac.h, region enumeration "eLoRaMacRegion_t"
|
|
// for a list of supported regions
|
|
#define LORA_REGION LORAMAC_REGION_US915
|
|
|
|
// Private defination
|
|
#define LORAWAN_APP_DATA_BUFF_SIZE 64 /**< buffer size of the data to be transmitted. */
|
|
#define LORAWAN_APP_INTERVAL 20000 /**< Defines for user timer, the application data transmission interval. 20s, value in [ms]. */
|
|
static uint8_t m_lora_app_data_buffer[LORAWAN_APP_DATA_BUFF_SIZE]; //< Lora user application data buffer.
|
|
static lmh_app_data_t m_lora_app_data = {m_lora_app_data_buffer, 0, 0, 0, 0}; //< Lora user application data structure.
|
|
|
|
TimerEvent_t appTimer;
|
|
static uint32_t timers_init(void);
|
|
static uint32_t count = 0;
|
|
static uint32_t count_fail = 0;
|
|
|
|
void setup()
|
|
{
|
|
pinMode(LED_BUILTIN, OUTPUT);
|
|
digitalWrite(LED_BUILTIN, LOW);
|
|
|
|
// Initialize LoRa chip.
|
|
lora_rak4630_init();
|
|
delay(5000);
|
|
// Initialize Serial for debug output
|
|
Serial.begin(115200);
|
|
while (!Serial)
|
|
{
|
|
delay(10);
|
|
}
|
|
Serial.println("=====================================");
|
|
Serial.println("Welcome to RAK4630 LoRaWan!!!");
|
|
Serial.println("Type: OTAA");
|
|
// NOTE: Update per your region setting
|
|
Serial.println("Region: US915");
|
|
|
|
Serial.println("=====================================");
|
|
|
|
//creat a user timer to send data to server period
|
|
uint32_t err_code;
|
|
err_code = timers_init();
|
|
if (err_code != 0)
|
|
{
|
|
Serial.printf("timers_init failed - %d\n", err_code);
|
|
}
|
|
|
|
// Setup the EUIs and Keys
|
|
lmh_setDevEui(nodeDeviceEUI);
|
|
lmh_setAppEui(nodeAppEUI);
|
|
lmh_setAppKey(nodeAppKey);
|
|
|
|
|
|
// Initialize LoRaWan
|
|
err_code = lmh_init(&lora_callbacks, lora_param_init, doOTAA, CLASS_A, LORA_REGION);
|
|
if (err_code != 0)
|
|
{
|
|
Serial.printf("lmh_init failed - %d\n", err_code);
|
|
}
|
|
|
|
// Start Join procedure
|
|
Serial.println("Starting Join");
|
|
lmh_join();
|
|
Serial.println("Return from join");
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
// user code
|
|
}
|
|
|
|
/**@brief LoRa function for handling HasJoined event.
|
|
*/
|
|
void lorawan_has_joined_handler(void)
|
|
{
|
|
Serial.println("OTAA Mode, Network Joined!");
|
|
|
|
lmh_error_status ret = lmh_class_request(gCurrentClass);
|
|
if (ret == LMH_SUCCESS)
|
|
{
|
|
delay(1000);
|
|
TimerSetValue(&appTimer, LORAWAN_APP_INTERVAL);
|
|
TimerStart(&appTimer);
|
|
}
|
|
}
|
|
|
|
|
|
/**@brief LoRa function for handling Join Failed event.
|
|
*/
|
|
void lorawan_join_failed_handler(void)
|
|
{
|
|
Serial.println("OTAA Mode, Network Join Failed!");
|
|
|
|
Serial.printf("Join Attempt failed after JOINREQ_NBTRIALS count of %d\r\n", JOINREQ_NBTRIALS);
|
|
Serial.println("No more network joins will be attempted");
|
|
}
|
|
|
|
/**@brief Function for handling LoRaWan received data from Gateway
|
|
*
|
|
* @param[in] app_data Pointer to rx data
|
|
*/
|
|
void lorawan_rx_handler(lmh_app_data_t *app_data)
|
|
{
|
|
Serial.printf("LoRa Packet received on port %d, size:%d, rssi:%d, snr:%d, data:%s\n",
|
|
app_data->port, app_data->buffsize, app_data->rssi, app_data->snr, app_data->buffer);
|
|
}
|
|
|
|
void lorawan_confirm_class_handler(DeviceClass_t Class)
|
|
{
|
|
Serial.printf("switch to class %c done\n", "ABC"[Class]);
|
|
// Informs the server that switch has occurred ASAP
|
|
m_lora_app_data.buffsize = 0;
|
|
m_lora_app_data.port = gAppPort;
|
|
lmh_send(&m_lora_app_data, gCurrentConfirm);
|
|
}
|
|
|
|
void send_lora_frame(void)
|
|
{
|
|
if (lmh_join_status_get() != LMH_SET)
|
|
{
|
|
//Not joined, try again later
|
|
return;
|
|
}
|
|
|
|
uint32_t i = 0;
|
|
memset(m_lora_app_data.buffer, 0, LORAWAN_APP_DATA_BUFF_SIZE);
|
|
m_lora_app_data.port = gAppPort;
|
|
m_lora_app_data.buffer[i++] = 'H';
|
|
m_lora_app_data.buffer[i++] = 'e';
|
|
m_lora_app_data.buffer[i++] = 'l';
|
|
m_lora_app_data.buffer[i++] = 'l';
|
|
m_lora_app_data.buffer[i++] = 'o';
|
|
m_lora_app_data.buffer[i++] = '!';
|
|
m_lora_app_data.buffsize = i;
|
|
|
|
lmh_error_status error = lmh_send(&m_lora_app_data, gCurrentConfirm);
|
|
if (error == LMH_SUCCESS)
|
|
{
|
|
count++;
|
|
Serial.printf("lmh_send ok count %d\n", count);
|
|
}
|
|
else
|
|
{
|
|
count_fail++;
|
|
Serial.printf("lmh_send fail count %d\n", count_fail);
|
|
}
|
|
}
|
|
|
|
/**@brief Function for handling user timerout event.
|
|
*/
|
|
void tx_lora_periodic_handler(void)
|
|
{
|
|
TimerSetValue(&appTimer, LORAWAN_APP_INTERVAL);
|
|
TimerStart(&appTimer);
|
|
Serial.println("Sending frame now...");
|
|
send_lora_frame();
|
|
}
|
|
|
|
/**@brief Function for the Timer initialization.
|
|
*
|
|
* @details Initializes the timer module. This creates and starts application timers.
|
|
*/
|
|
uint32_t timers_init(void)
|
|
{
|
|
TimerInit(&appTimer, tx_lora_periodic_handler);
|
|
return 0;
|
|
}
|