diff --git a/RAKWireless-WisBlock/longfi-us915/README.md b/RAKWireless-WisBlock/longfi-us915/README.md new file mode 100644 index 0000000..c408d46 --- /dev/null +++ b/RAKWireless-WisBlock/longfi-us915/README.md @@ -0,0 +1,16 @@ + +# Helium Basic Example + +Here you will find a very basic example of a WisBlock/Helium embedded project that uses the Arduino IDE. +This version will join the Helium network and periodically send a "Hello" to the Helium network. + +### Hardware +The only hardware required is: +* the [WisBlock Starter Kit](https://store.rakwireless.com/products/wisblock-starter-kit) containing the base board with the core module installed. +* one USB 2.0 A-Male to Micro B interface cable. + +#### Antenna Type/location +The WisBlock starter kit comes with two antenna types, +* the one that resembles an "I" is the LoRa antenna, this one connects to the connector on the core moduke marked LoRa, which is below the large K in the RAK logo. +* the one that resembles a "T" is the BLE antenna, this one connects to the connector on the core module marked BLE + diff --git a/RAKWireless-WisBlock/longfi-us915/longfi-us915.ino b/RAKWireless-WisBlock/longfi-us915/longfi-us915.ino new file mode 100644 index 0000000..b01bec3 --- /dev/null +++ b/RAKWireless-WisBlock/longfi-us915/longfi-us915.ino @@ -0,0 +1,254 @@ +#include + +/** + * @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 +#include //http://librarymanager/All#SX126x +#include + +// 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}; + + + +// 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"); + +#if defined(REGION_AS923) + Serial.println("Region: AS923"); +#elif defined(REGION_AU915) + Serial.println("Region: AU915"); +#elif defined(REGION_CN470) + Serial.println("Region: CN470"); +#elif defined(REGION_CN779) + Serial.println("Region: CN779"); +#elif defined(REGION_EU433) + Serial.println("Region: EU433"); +#elif defined(REGION_IN865) + Serial.println("Region: IN865"); +#elif defined(REGION_EU868) + Serial.println("Region: EU868"); +#elif defined(REGION_KR920) + Serial.println("Region: KR920"); +#elif defined(REGION_US915) + Serial.println("Region: US915"); +#elif defined(REGION_US915_HYBRID) + Serial.println("Region: US915_HYBRID"); +#else + Serial.println("Please define a region in the compiler options."); +#endif + 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); + 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() +{ + // Handle Radio events + Radio.IrqProcess(); +} + +/**@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; +} diff --git a/README.md b/README.md index cc8d998..d7be5d6 100644 --- a/README.md +++ b/README.md @@ -25,4 +25,5 @@ Here you will find a collection of Arduino sketch examples of transmitting on th ### Heltec WiFi LoRa 32 V2 * [longfi-us915](Heltec-WiFi-LoRa-32-V2/longfi-us915) - +### RAKWireless WisBlock +* [longfi-us915](RAKWireless-WisBlock/longfi-us915/)