Skip to content

Commit

Permalink
Merge pull request #72 from RAKWireless/Blues.IO
Browse files Browse the repository at this point in the history
Blues.io
  • Loading branch information
beegee-tokyo authored Oct 25, 2023
2 parents 96cb76a + bc60166 commit 8f5ea5e
Show file tree
Hide file tree
Showing 97 changed files with 8,215 additions and 0 deletions.
Empty file.
Empty file.
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();
}
}
}
}
Loading

0 comments on commit 8f5ea5e

Please sign in to comment.