Skip to content

Commit

Permalink
Merge pull request #3 from BuzzVerse/feat/bme280
Browse files Browse the repository at this point in the history
feat: Refactor LoRaWAN and BME280 sensor integration
  • Loading branch information
wybran authored Jan 27, 2025
2 parents 6eda6a8 + 48fe028 commit 7d6812f
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 48 deletions.
13 changes: 10 additions & 3 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@
cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})

project(app LANGUAGES C)

FILE(GLOB app_sources src/*.cpp)
project(app LANGUAGES CXX)
file(GLOB_RECURSE app_sources src/*.cpp)
target_sources(app PRIVATE ${app_sources})

# Set C++17 using compiler flags instead of target_compile_features
set_target_properties(app PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
)

target_link_libraries(app PRIVATE etl::etl)
1 change: 1 addition & 0 deletions app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CONFIG_REBOOT=y
CONFIG_I2C=y
CONFIG_GPIO=y
CONFIG_SPI=y

CONFIG_SENSOR=y
CONFIG_SENSOR_ASYNC_API=y

Expand Down
42 changes: 42 additions & 0 deletions app/src/bme280.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "bme280.hpp"

#include <zephyr/drivers/sensor.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(bme280, LOG_LEVEL_DBG);

BME280::BME280(const device* dev) : bme280_dev(dev) {}

bool BME280::init() {
if (!device_is_ready(bme280_dev)) {
LOG_WRN("BME280 device not ready");
return false;
}

LOG_INF("BME280 device ready");
ready = true;
return true;
}

void BME280::read_data(etl::string<64>& msg, uint32_t counter) const {
struct sensor_value temp, press, humidity;

int rc = sensor_sample_fetch(bme280_dev);
if (rc != 0) {
LOG_ERR("sensor_sample_fetch failed: %d", rc);
return;
}

sensor_channel_get(bme280_dev, SENSOR_CHAN_AMBIENT_TEMP, &temp);
sensor_channel_get(bme280_dev, SENSOR_CHAN_PRESS, &press);
sensor_channel_get(bme280_dev, SENSOR_CHAN_HUMIDITY, &humidity);

double temp_val = temp.val1 + (temp.val2 / 1000000.0);
double hum_val = humidity.val1 + (humidity.val2 / 1000000.0);
double pressure_hpa = (press.val1 * 10) + (press.val2 * 10.0 / 1000000.0);

char buffer[64];
snprintf(buffer, sizeof(buffer), "%u. %.1f °C, %.1f %%, %.1f hPa", counter, temp_val, hum_val,
pressure_hpa);
msg = buffer;
}
18 changes: 18 additions & 0 deletions app/src/bme280.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include <etl/string.h>
#include <zephyr/device.h>

class BME280 {
public:
explicit BME280(const device* dev);
bool init();
void read_data(etl::string<64>& msg, uint32_t counter) const;
bool is_ready() const {
return ready;
}

private:
const device* bme280_dev;
bool ready{false};
};
4 changes: 0 additions & 4 deletions app/src/lorawan.h

This file was deleted.

58 changes: 58 additions & 0 deletions app/src/lorawan_handler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "lorawan_handler.hpp"

#include <etl/array.h>
#include <zephyr/device.h>
#include <zephyr/logging/log.h>
#include <zephyr/lorawan/lorawan.h>

LOG_MODULE_REGISTER(lorawan_handler, LOG_LEVEL_DBG);

bool LoRaWANHandler::init() {
const device* lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0));
if (!device_is_ready(lora_dev)) {
LOG_WRN("%s: device not ready.", lora_dev->name);
return false;
}

lorawan_enable_adr(false);
lorawan_set_class(LORAWAN_CLASS_A);

int ret = lorawan_start();
if (ret < 0) {
LOG_WRN("lorawan_start failed: %d", ret);
return false;
}

struct lorawan_join_config join_cfg;
join_cfg.mode = LORAWAN_ACT_OTAA;
join_cfg.dev_eui = dev_eui.data();
join_cfg.otaa.join_eui = join_eui.data();
join_cfg.otaa.app_key = app_key.data();
join_cfg.otaa.nwk_key = app_key.data();

LOG_INF("Joining LoRaWAN network...");
ret = lorawan_join(&join_cfg);
if (ret < 0) {
LOG_WRN("lorawan_join failed: %d", ret);
return false;
}

LOG_INF("Successfully joined LoRaWAN network");
connected = true;
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);

memcpy(buffer.data(), msg, msg_size);

int ret = lorawan_send(2, buffer.data(), msg_size, LORAWAN_MSG_UNCONFIRMED);
if (ret < 0) {
LOG_ERR("lorawan_send failed: %d", ret);
} else {
LOG_INF("Message sent successfully: %s", msg);
}
}
22 changes: 22 additions & 0 deletions app/src/lorawan_handler.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

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

class LoRaWANHandler {
public:
LoRaWANHandler() = default;
bool init();
void send_message(const char* msg) const;
bool is_connected() const {
return connected;
}

private:
static constexpr size_t MAX_MSG_SIZE = 64;
bool connected{false};
etl::array<uint8_t, 8> dev_eui = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
etl::array<uint8_t, 8> join_eui = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
etl::array<uint8_t, 16> app_key = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
};
64 changes: 25 additions & 39 deletions app/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,67 +1,53 @@
#include <stdio.h>
#include <etl/string.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/lorawan/lorawan.h>

#include "lorawan.h"
#include "bme280.hpp"
#include "lorawan_handler.hpp"

LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);

#define DELAY K_SECONDS(10)

int main(void) {
uint8_t dev_eui[] = LORAWAN_DEV_EUI;
uint8_t join_eui[] = LORAWAN_JOIN_EUI;
uint8_t app_key[] = LORAWAN_APP_KEY;
const device* const bme280_dev = DEVICE_DT_GET_ANY(bosch_bme280);

const struct device *lora_dev;
BME280 bme280(bme280_dev);
LoRaWANHandler lorawan;

lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0));
if (!device_is_ready(lora_dev)) {
LOG_ERR("%s: device not ready.", lora_dev->name);
return -ENODEV;
}

lorawan_enable_adr(false);
lorawan_set_class(LORAWAN_CLASS_A);

int ret = lorawan_start();
if (ret < 0) {
LOG_ERR("lorawan_start failed: %d", ret);
return ret;
}
bool bme280_ready = bme280.init();
bool lorawan_connected = lorawan.init();

struct lorawan_join_config join_cfg;
join_cfg.mode = LORAWAN_ACT_OTAA;
join_cfg.dev_eui = dev_eui;
join_cfg.otaa.join_eui = join_eui;
join_cfg.otaa.app_key = app_key;
join_cfg.otaa.nwk_key = app_key;

LOG_INF("Joining LoRaWAN network...");
ret = lorawan_join(&join_cfg);
if (ret < 0) {
LOG_ERR("lorawan_join failed: %d", ret);
return ret;
if (!lorawan_connected && !bme280_ready) {
LOG_ERR("No devices available, stopping application");
return -ENODEV;
}

uint32_t counter = 0;

while (1) {
char msg[32];
snprintf(msg, sizeof(msg), "Hello, World! %u", counter);
etl::string<64> msg;

if (bme280_ready) {
bme280.read_data(msg, counter);
} else {
char buffer[64];
snprintf(buffer, sizeof(buffer), "%u", counter);
msg = buffer;
}

ret = lorawan_send(2, (uint8_t *)msg, strlen(msg), LORAWAN_MSG_UNCONFIRMED);
if (ret < 0) {
LOG_ERR("lorawan_send failed: %d", ret);
if (lorawan_connected) {
lorawan.send_message(msg.c_str());
} else {
LOG_INF("Message sent successfully: %s", msg);
LOG_INF("BME280 (not sent): %s", msg.c_str());
}

counter++;
k_sleep(DELAY);
}

return 0;
}
}
3 changes: 1 addition & 2 deletions doc/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -918,8 +918,7 @@ WARN_LOGFILE =
# Note: If this tag is empty the current directory is searched.

INPUT = _doxygen/main.md \
_doxygen/groups.dox \
../include
_doxygen/groups.dox

# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
Expand Down

0 comments on commit 7d6812f

Please sign in to comment.