-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #72 from RAKWireless/Blues.IO
Blues.io
- Loading branch information
Showing
97 changed files
with
8,215 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Empty file.
Empty file.
Empty file.
322 changes: 322 additions & 0 deletions
322
...Blues-Hummingbird-Gateway/Arduino/Blues-Hummingbird-Gateway/Blues-Hummingbird-Gateway.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,322 @@ | ||
/** | ||
* @file main.cpp | ||
* @author Bernd Giesecke ([email protected]) | ||
* @brief App event handlers | ||
* @version 0.1 | ||
* @date 2023-04-25 | ||
* | ||
* @copyright Copyright (c) 2023 | ||
* | ||
*/ | ||
|
||
#include "main.h" | ||
|
||
/** LoRaWAN packet */ | ||
WisCayenne g_solution_data(255); | ||
|
||
/** Received package for parsing */ | ||
uint8_t rcvd_data[256]; | ||
/** Length of received package */ | ||
uint16_t rcvd_data_len = 0; | ||
|
||
/** Send Fail counter **/ | ||
uint8_t send_fail = 0; | ||
|
||
/** Set the device name, max length is 10 characters */ | ||
char g_ble_dev_name[10] = "RAK"; | ||
|
||
/** Flag for RAK1906 sensor */ | ||
bool has_rak1906 = false; | ||
|
||
/** Flag is Blues Notecard was found */ | ||
bool has_blues = false; | ||
|
||
/** | ||
* @brief Initial setup of the application (before LoRaWAN and BLE setup) | ||
* | ||
*/ | ||
void setup_app(void) | ||
{ | ||
Serial.begin(115200); | ||
time_t serial_timeout = millis(); | ||
// On nRF52840 the USB serial is not available immediately | ||
while (!Serial) | ||
{ | ||
if ((millis() - serial_timeout) < 5000) | ||
{ | ||
delay(100); | ||
digitalWrite(LED_GREEN, !digitalRead(LED_GREEN)); | ||
} | ||
else | ||
{ | ||
break; | ||
} | ||
} | ||
digitalWrite(LED_GREEN, LOW); | ||
|
||
// Set firmware version | ||
api_set_version(SW_VERSION_1, SW_VERSION_2, SW_VERSION_3); | ||
} | ||
|
||
/** | ||
* @brief Final setup of application (after LoRaWAN and BLE setup) | ||
* | ||
* @return true | ||
* @return false | ||
*/ | ||
bool init_app(void) | ||
{ | ||
Serial.printf("init_app\n"); | ||
|
||
Serial.printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); | ||
Serial.printf("WisBlock Hummingbird Blues Sensor\n"); | ||
Serial.printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); | ||
|
||
// Initialize User AT commands | ||
init_user_at(); | ||
|
||
// Check if RAK1906 is available | ||
has_rak1906 = init_rak1906(); | ||
if (has_rak1906) | ||
{ | ||
Serial.printf("+EVT:RAK1906\n"); | ||
} | ||
|
||
// Initialize Blues Notecard | ||
has_blues = init_blues(); | ||
if (!has_blues) | ||
{ | ||
Serial.printf("+EVT:CELLULAR_ERROR\n"); | ||
} | ||
else | ||
{ | ||
Serial.printf("+EVT:RAK13102\n"); | ||
Serial.printf("Start P2P RX\n"); | ||
// Set to permanent listen | ||
g_lora_p2p_rx_mode = RX_MODE_RX; | ||
Radio.Rx(0); | ||
} | ||
|
||
pinMode(WB_IO2, OUTPUT); | ||
digitalWrite(WB_IO2, LOW); | ||
return true; | ||
} | ||
|
||
/** | ||
* @brief Handle events | ||
* Events can be | ||
* - timer (setup with AT+SENDINT=xxx) | ||
* - interrupt events | ||
* - wake-up signals from other tasks | ||
*/ | ||
void app_event_handler(void) | ||
{ | ||
// Timer triggered event | ||
if ((g_task_event_type & STATUS) == STATUS) | ||
{ | ||
g_task_event_type &= N_STATUS; | ||
Serial.printf("Timer wakeup\n"); | ||
if (g_lpwan_has_joined) | ||
{ | ||
// Reset the packet | ||
g_solution_data.reset(); | ||
|
||
// Get battery level | ||
float batt_level_f = read_batt(); | ||
g_solution_data.addVoltage(LPP_CHANNEL_BATT, batt_level_f / 1000.0); | ||
|
||
// Read sensors and battery | ||
if (has_rak1906) | ||
{ | ||
read_rak1906(); | ||
} | ||
|
||
if (!has_blues) | ||
{ | ||
if (g_lorawan_settings.lorawan_enable) | ||
{ | ||
lmh_error_status result = send_lora_packet(g_solution_data.getBuffer(), g_solution_data.getSize()); | ||
switch (result) | ||
{ | ||
case LMH_SUCCESS: | ||
Serial.printf("Packet enqueued\n"); | ||
break; | ||
case LMH_BUSY: | ||
Serial.printf("LoRa transceiver is busy\n"); | ||
Serial.printf("+EVT:BUSY\n\n"); | ||
break; | ||
case LMH_ERROR: | ||
Serial.printf("+EVT:SIZE_ERROR\n\n"); | ||
Serial.printf("Packet error, too big to send with current DR\n"); | ||
break; | ||
} | ||
} | ||
else | ||
{ | ||
// Add unique identifier in front of the P2P packet, here we use the DevEUI | ||
g_solution_data.addDevID(LPP_CHANNEL_DEVID, &g_lorawan_settings.node_device_eui[4]); | ||
// uint8_t packet_buffer[g_solution_data.getSize() + 8]; | ||
// memcpy(packet_buffer, g_lorawan_settings.node_device_eui, 8); | ||
// memcpy(&packet_buffer[8], g_solution_data.getBuffer(), g_solution_data.getSize()); | ||
|
||
// Send packet over LoRa | ||
// if (send_p2p_packet(packet_buffer, g_solution_data.getSize() + 8)) | ||
if (send_p2p_packet(g_solution_data.getBuffer(), g_solution_data.getSize())) | ||
{ | ||
Serial.printf("Packet enqueued\n"); | ||
} | ||
else | ||
{ | ||
Serial.printf("+EVT:SIZE_ERROR\n"); | ||
Serial.printf("Packet too big\n"); | ||
} | ||
} | ||
} | ||
else | ||
{ | ||
Serial.printf("Get hub sync status:\n"); | ||
blues_hub_status(); | ||
|
||
g_solution_data.addDevID(0, &g_lorawan_settings.node_device_eui[4]); | ||
blues_parse_send(g_solution_data.getBuffer(), g_solution_data.getSize()); | ||
} | ||
// Reset the packet | ||
g_solution_data.reset(); | ||
} | ||
else | ||
{ | ||
Serial.printf("Network not joined, skip sending\n"); | ||
} | ||
} | ||
|
||
// Parse request event | ||
if ((g_task_event_type & PARSE) == PARSE) | ||
{ | ||
g_task_event_type &= N_PARSE; | ||
|
||
if (has_blues) | ||
{ | ||
if (!blues_parse_send(rcvd_data, rcvd_data_len)) | ||
{ | ||
Serial.printf("Parsing or sending failed\n"); | ||
|
||
Serial.printf("**********************************************\n"); | ||
Serial.printf("Get hub sync status:\n"); | ||
// {“req”:”hub.sync.status”} | ||
blues_start_req("hub.sync.status\n"); | ||
blues_send_req(); | ||
|
||
Serial.printf("**********************************************\n"); | ||
delay(2000); | ||
|
||
Serial.printf("Get note card status:\n"); | ||
// {“req”:”card.wireless”} | ||
blues_start_req("card.wireless\n"); | ||
blues_send_req(); | ||
|
||
Serial.printf("**********************************************\n"); | ||
delay(2000); | ||
} | ||
} | ||
else | ||
{ | ||
Serial.printf("Got PARSE request, but no Blues Notecard detected\n"); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @brief Handle BLE events | ||
* | ||
*/ | ||
void ble_data_handler(void) | ||
{ | ||
if (g_enable_ble) | ||
{ | ||
if ((g_task_event_type & BLE_DATA) == BLE_DATA) | ||
{ | ||
Serial.printf("RECEIVED BLE\n"); | ||
// BLE UART data arrived | ||
g_task_event_type &= N_BLE_DATA; | ||
|
||
while (g_ble_uart.available() > 0) | ||
{ | ||
at_serial_input(uint8_t(g_ble_uart.read())); | ||
delay(5); | ||
} | ||
at_serial_input(uint8_t('\n')); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @brief Handle LoRa events | ||
* | ||
*/ | ||
void lora_data_handler(void) | ||
{ | ||
// LoRa Join finished handling | ||
if ((g_task_event_type & LORA_JOIN_FIN) == LORA_JOIN_FIN) | ||
{ | ||
g_task_event_type &= N_LORA_JOIN_FIN; | ||
if (g_join_result) | ||
{ | ||
Serial.printf("Successfully joined network\n"); | ||
} | ||
else | ||
{ | ||
Serial.printf("Join network failed\n"); | ||
/// \todo here join could be restarted. | ||
// lmh_join(); | ||
} | ||
} | ||
|
||
// LoRa data handling | ||
if ((g_task_event_type & LORA_DATA) == LORA_DATA) | ||
{ | ||
g_task_event_type &= N_LORA_DATA; | ||
Serial.printf("Received package over LoRa\n"); | ||
char log_buff[g_rx_data_len * 3] = {0}; | ||
uint8_t log_idx = 0; | ||
for (int idx = 0; idx < g_rx_data_len; idx++) | ||
{ | ||
sprintf(&log_buff[log_idx], "%02X ", g_rx_lora_data[idx]); | ||
log_idx += 3; | ||
} | ||
Serial.printf("%s", log_buff); | ||
|
||
#if MY_DEBUG > 0 | ||
CayenneLPP lpp(g_rx_data_len - 8); | ||
memcpy(lpp.getBuffer(), &g_rx_lora_data[8], g_rx_data_len - 8); | ||
DynamicJsonDocument jsonBuffer(4096); | ||
JsonObject root = jsonBuffer.to<JsonObject>(); | ||
lpp.decodeTTN(lpp.getBuffer(), g_rx_data_len - 8, root); | ||
serializeJsonPretty(root, Serial); | ||
Serial.println(); | ||
#endif | ||
memcpy(rcvd_data, g_rx_lora_data, g_rx_data_len); | ||
rcvd_data_len = g_rx_data_len; | ||
api_wake_loop(PARSE); | ||
} | ||
|
||
// LoRa TX finished handling | ||
if ((g_task_event_type & LORA_TX_FIN) == LORA_TX_FIN) | ||
{ | ||
g_task_event_type &= N_LORA_TX_FIN; | ||
|
||
Serial.printf("LPWAN TX cycle %s", g_rx_fin_result ? "finished ACK" : "failed NAK\n"); | ||
|
||
if (!g_rx_fin_result) | ||
{ | ||
// Increase fail send counter | ||
send_fail++; | ||
|
||
if (send_fail == 10) | ||
{ | ||
// Too many failed sendings, reset node and try to rejoin | ||
delay(100); | ||
api_reset(); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.