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

feat(Sensors): Add support for BME280 sensor and refactor peripheral … #5

Merged
merged 6 commits into from
Feb 3, 2025
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
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @BuzzVerse/Reviewers
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ _deps

### VisualStudioCode ###
.vscode/*
!.vscode/tasks.json

### Eclipse ###
*.cproject
Expand Down
54 changes: 54 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "Zephyr: Build BuzzNode (ESP32)",
"command": "bash",
"args": [
"-c",
"source ~/zephyrproject/.venv/bin/activate && west build -b lora_node/esp32s3/procpu -p always app"
],
"group": "build",
"problemMatcher": [],
"detail": "Activate venv and build the BuzzNode ESP32 firmware."
},
{
"type": "shell",
"label": "Zephyr: Flash BuzzNode (ESP32)",
"command": "bash",
"args": [
"-c",
"source ~/zephyrproject/.venv/bin/activate && DEVICE=$(ls /dev/cu.usbmodem* | head -n 1) && west flash --esp-device $DEVICE"
],
"problemMatcher": [],
"detail": "Activate venv and flash the BuzzNode ESP32 firmware to the device."
},
{
"type": "shell",
"label": "Zephyr: Monitor BuzzNode Logs (ESP32)",
"command": "bash",
"args": [
"-c",
"source ~/zephyrproject/.venv/bin/activate && DEVICE=$(ls /dev/cu.usbmodem* | head -n 1) && west espressif monitor -p $DEVICE"
],
"problemMatcher": [],
"detail": "Activate venv and monitor logs for the BuzzNode ESP32 device."
},
{
"type": "shell",
"label": "Zephyr: Build-Flash-Monitor BuzzNode (ESP32)",
"command": "bash",
"args": [
"-c",
"source ~/zephyrproject/.venv/bin/activate && DEVICE=$(ls /dev/cu.usbmodem* | head -n 1) && west build -b lora_node/esp32s3/procpu -p always app && west flash --esp-device $DEVICE && west espressif monitor -p $DEVICE"
],
"problemMatcher": [],
"detail": "Activate venv and perform build, flash, and monitor steps for BuzzNode ESP32 firmware.",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
7 changes: 7 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ target_include_directories(proto PUBLIC
file(GLOB_RECURSE app_sources src/*.cpp)
target_sources(app PRIVATE ${app_sources})

# Add include directories for cleaner imports
target_include_directories(app PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/peripherals
${CMAKE_CURRENT_SOURCE_DIR}/src/sensors
)

# Set C++17 using compiler flags instead of target_compile_features
set_target_properties(app PROPERTIES
CXX_STANDARD 17
Expand Down
2 changes: 1 addition & 1 deletion app/protobufs
18 changes: 0 additions & 18 deletions app/src/bme280.hpp

This file was deleted.

21 changes: 0 additions & 21 deletions app/src/lorawan_handler.hpp

This file was deleted.

107 changes: 63 additions & 44 deletions app/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,74 +1,93 @@
#include <etl/string.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <etl/vector.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/lorawan/lorawan.h>

#include "bme280.hpp"
#include "lorawan_handler.hpp"
#include "buzzverse/bme280.pb.h"
#include "buzzverse/packet.pb.h"
#include "peripherals/lorawan_handler/lorawan_handler.hpp"
#include "sensors/bme280/bme280.hpp"
#include "utils/packet_handler.hpp"

LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);

#define DELAY K_SECONDS(10)

int main(void) {
// Example usage
// buzzverse_v1_Packet packet = buzzverse_v1_Packet_init_zero;
// packet.which_data = buzzverse_v1_Packet_bme280_tag;
// packet.data.bme280.temperature = 10;
// packet.data.bme280.pressure = 21;
// packet.data.bme280.humidity = 37;

// uint8_t buffer[buzzverse_v1_Packet_size];
// size_t size;

// if (PacketHandler::encode(packet, buffer, size)) {
// LOG_INF("Packet encoded successfully");
// } else {
// LOG_ERR("Failed to encode packet");
// }

// LOG_INF("Packet size: %zu", size);
// TODO: Remove this when ready
void test_encode_decode();

int main(void) {
const device* const bme280_dev = DEVICE_DT_GET_ANY(bosch_bme280);

BME280 bme280(bme280_dev);
LoRaWANHandler lorawan;

bool bme280_ready = bme280.init();
bool lorawan_connected = lorawan.init();
etl::vector<Peripheral*, 2> peripherals = {&bme280, &lorawan};

if (!lorawan_connected && !bme280_ready) {
LOG_ERR("No devices available, stopping application");
return -ENODEV;
for (auto* peripheral : peripherals) {
if (!peripheral->init()) {
LOG_ERR("%s initialization failed", peripheral->get_name().c_str());
}
}

uint32_t counter = 0;

while (1) {
etl::string<64> msg;

if (bme280_ready) {
bme280.read_data(msg, counter);
while (true) {
// Create and populate a BME280Data protobuf message
buzzverse_v1_BME280Data bme280_data = buzzverse_v1_BME280Data_init_zero;
if (bme280.is_ready()) {
bme280.read_data(&bme280_data);
} else {
char buffer[64];
snprintf(buffer, sizeof(buffer), "%u", counter);
msg = buffer;
LOG_ERR("BME280 not ready");
k_sleep(DELAY);
continue;
}

if (lorawan_connected) {
lorawan.send_message(msg.c_str());
} else {
LOG_INF("BME280 (not sent): %s", msg.c_str());
// Create and populate a Packet protobuf message
buzzverse_v1_Packet packet = buzzverse_v1_Packet_init_zero;
packet.which_data = buzzverse_v1_Packet_bme280_tag;
packet.data.bme280 = bme280_data;

// TODO: Remove this when ready
test_encode_decode();

// Send the packet using LoRaWANHandler
if (!lorawan.is_ready() || !lorawan.send_packet(packet)) {
LOG_ERR("Failed to send packet");
}

counter++;
k_sleep(DELAY);
}

return 0;
}

// TODO: Remove this when ready
void test_encode_decode() {
buzzverse_v1_Packet packet = buzzverse_v1_Packet_init_zero;
packet.which_data = buzzverse_v1_Packet_bme280_tag;
packet.data.bme280.temperature = 1;
packet.data.bme280.pressure = 1;
packet.data.bme280.humidity = 1;

uint8_t buffer[64];
size_t size = 0;

if (!PacketHandler::encode(packet, buffer, size)) {
LOG_ERR("Failed to encode packet");
return;
}

// print encoded packet bytes
LOG_INF("Encoded packet: ");
for (size_t i = 0; i < size; i++) {
LOG_INF("0x%02x", buffer[i]);
}

buzzverse_v1_Packet decoded_packet = buzzverse_v1_Packet_init_zero;
if (!PacketHandler::decode(buffer, size, decoded_packet)) {
LOG_ERR("Failed to decode packet");
return;
}

LOG_INF("Decoded packet: temperature=%d, pressure=%d, humidity=%d",
decoded_packet.data.bme280.temperature, decoded_packet.data.bme280.pressure,
decoded_packet.data.bme280.humidity);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <zephyr/lorawan/lorawan.h>

#include "utils/hex.hpp"
#include "utils/packet_handler.hpp"

LOG_MODULE_REGISTER(lorawan_handler, LOG_LEVEL_DBG);

Expand Down Expand Up @@ -64,17 +65,23 @@ bool LoRaWANHandler::init() {
return true;
}

void LoRaWANHandler::send_message(const char* msg) const {
etl::array<uint8_t, MAX_MSG_SIZE> buffer{};
size_t msg_len = strlen(msg);
size_t msg_size = etl::min(msg_len, MAX_MSG_SIZE);
bool LoRaWANHandler::send_packet(const buzzverse_v1_Packet& packet) const {
uint8_t buffer[MAX_MSG_SIZE];
size_t size = 0;

memcpy(buffer.data(), msg, msg_size);
// Encode the protobuf message
if (!PacketHandler::encode(packet, buffer, size)) {
LOG_ERR("Packet encoding failed");
return false;
}

int ret = lorawan_send(2, buffer.data(), msg_size, LORAWAN_MSG_UNCONFIRMED);
// Send the encoded message over LoRaWAN
int ret = lorawan_send(LORAWAN_PORT, buffer, size, LORAWAN_MSG_UNCONFIRMED);
if (ret < 0) {
LOG_ERR("lorawan_send failed: %d", ret);
} else {
LOG_INF("Message sent successfully: %s", msg);
LOG_ERR("LoRaWAN send failed: %d", ret);
return false;
}

LOG_INF("Packet sent successfully (size: %zu bytes)", size);
return true;
}
39 changes: 39 additions & 0 deletions app/src/peripherals/lorawan_handler/lorawan_handler.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef LORAWAN_HANDLER_HPP
#define LORAWAN_HANDLER_HPP

#include <etl/array.h>
#include <etl/string.h>

#include "buzzverse/packet.pb.h"
#include "peripheral.hpp"

class LoRaWANHandler : public Peripheral {
public:
LoRaWANHandler();

static constexpr uint8_t LORAWAN_PORT = 2;

static constexpr size_t MAX_MSG_SIZE = 64;
static constexpr size_t EUI_SIZE = 8;
static constexpr size_t KEY_SIZE = 16;

bool init() override;

bool is_ready() const override {
return connected;
}

etl::string<PERIPHERAL_NAME_SIZE> get_name() const override {
return "LoRaWAN";
}

bool send_packet(const buzzverse_v1_Packet& packet) const;

private:
bool connected{false};
etl::array<uint8_t, EUI_SIZE> dev_eui;
etl::array<uint8_t, EUI_SIZE> join_eui;
etl::array<uint8_t, KEY_SIZE> app_key;
};

#endif // LORAWAN_HANDLER_HPP
22 changes: 22 additions & 0 deletions app/src/peripherals/peripheral.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef PERIPHERAL_HPP
#define PERIPHERAL_HPP

#include <etl/string.h>

constexpr size_t PERIPHERAL_NAME_SIZE = 32;

class Peripheral {
public:
virtual ~Peripheral() = default;

// Initialize the peripheral
virtual bool init() = 0;

// Check if the peripheral is ready
virtual bool is_ready() const = 0;

// Get the name of the peripheral
virtual etl::string<PERIPHERAL_NAME_SIZE> get_name() const = 0;
};

#endif // PERIPHERAL_HPP
Loading
Loading