Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blues.io #72

Merged
merged 6 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading