Skip to content
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
6 changes: 6 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ config SLEEP_TIME_MS
help
Duration for which the device will sleep before waking up. This value is in milliseconds.

config ENABLE_ANALOG
bool "Enable Analog Sensor"
default n
help
Enable support for Analog sensor.

source "Kconfig.zephyr"
endmenu

Expand Down
20 changes: 20 additions & 0 deletions app/boards/nucleo_wl55jc.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
aliases {
bme280-i2c = &i2c2;
};

zephyr,user {
io-channels = <&adc1 6>;
io-channels-names = "a0";
};
};

&i2c2 {
Expand All @@ -18,3 +23,18 @@
status = "okay";
};
};

&adc1 {
status = "okay";

#address-cells = <1>;
#size-cells = <0>;

soil_sensor: channel@6 {
reg = <6>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,resolution = <12>;
};
};
6 changes: 5 additions & 1 deletion app/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,8 @@ CONFIG_SETTINGS_RUNTIME=y
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y

CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_BOOTLOADER_MCUBOOT=y

# ADC config
CONFIG_ADC=y
CONFIG_CBPRINTF_FP_SUPPORT=y
2 changes: 1 addition & 1 deletion app/protobufs
11 changes: 10 additions & 1 deletion app/src/Application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,16 @@
#include "sensor.hpp"

// Number of supported sensor types used in the sensors array
#define NUMBER_OF_SENSORS 1
#define BASE_SENSOR_COUNT 1

#ifdef CONFIG_ENABLE_ANALOG
#define ANALOG_SENSOR_COUNT 1 // Analog sensor is enabled
#else
#define ANALOG_SENSOR_COUNT 0 // Analog sensor is disabled
#endif

// The final fixed size is calculated by the preprocessor
#define NUMBER_OF_SENSORS (BASE_SENSOR_COUNT + ANALOG_SENSOR_COUNT)

class LoRaWANHandler;
class SleepManager;
Expand Down
11 changes: 11 additions & 0 deletions app/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
#include <zephyr/logging/log.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/reboot.h>
#include <zephyr/drivers/adc.h>

#include "Application.hpp"
#include "peripherals/lorawan_handler/lorawan_handler.hpp"
#include "sensors/bme280/bme280.hpp"
#include "sensors/analog/analog.hpp"
#include "sensors/bq27441/bq27441.hpp"
#include "utils/banner.hpp"
#include "utils/sleep-manager.hpp"
Expand All @@ -19,14 +21,23 @@ LOG_MODULE_REGISTER(main_entry, LOG_LEVEL_DBG);
#define APP_SLEEP_DURATION_MS 10000
#endif

static const struct adc_dt_spec soil_sensor_adc_spec =
ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 0);


int main(void) {
printk("%s\n", APP_ASCII_BANNER);
LOG_INF("===== Buzzverse Node System Booting (Zephyr Log) =====");

BME280 bme280(DEVICE_DT_GET_ANY(bosch_bme280));
Analog analog(&soil_sensor_adc_spec);

// Array of available sensors
etl::array<etl::unique_ptr<Sensor>, NUMBER_OF_SENSORS> sensors {
etl::unique_ptr<BME280>(etl::move(&bme280)),
#ifdef CONFIG_ENABLE_ANALOG
etl::unique_ptr<Analog>(etl::move(&analog)),
#endif
};

BQ27441 bq27441(DEVICE_DT_GET_ANY(ti_bq274xx));
Expand Down
81 changes: 81 additions & 0 deletions app/src/sensors/analog/analog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include "analog.hpp"

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

#include "buzzverse/analog.pb.h"

LOG_MODULE_REGISTER(Analog, LOG_LEVEL_DBG);
Analog::Analog(const struct adc_dt_spec* adc_spec)
: m_adc_spec(adc_spec) {}

using Status = Sensor::Status;

Peripheral::Status Analog::init() {
if (!m_adc_spec || !device_is_ready(m_adc_spec->dev)) {
status = buzzverse_v1_Status_ComponentState_INITIALIZATION_FAILED;
LOG_WRN("Analog: Analog device not ready or spec is invalid");
return Peripheral::Status::NOT_READY;
}

int err = adc_channel_setup_dt(m_adc_spec);
if (err != 0) {
LOG_ERR("Analog: Failed to setup Analog channel %d (err %d)", m_adc_spec->channel_id, err);
status = buzzverse_v1_Status_ComponentState_INITIALIZATION_FAILED;
return Peripheral::Status::INIT_ERR;
}

LOG_INF("Analog: Analog device ready, channel %d configured via DT", m_adc_spec->channel_id);
status = buzzverse_v1_Status_ComponentState_NORMAL;

ready = true;
return Peripheral::Status::OK;
}

Status Analog::read_data(buzzverse_v1_Analog& data) const {
uint16_t sample_buffer = 0;
struct adc_sequence sequence = {0};
int ret = adc_sequence_init_dt(m_adc_spec, &sequence);
if (ret != 0) {
LOG_ERR("Analog: Failed to initialize Analog sequence: %d", ret);
return Status::READ_ERR;
}
sequence.buffer = &sample_buffer;
sequence.buffer_size = sizeof(sample_buffer);

ret = adc_read_dt(m_adc_spec, &sequence);
if (ret) {
LOG_ERR("Analog: Analog read failed: %d", ret);
return Status::READ_ERR;
}

int32_t millivolts = sample_buffer;
ret = adc_raw_to_millivolts_dt(m_adc_spec, &millivolts);
if (ret) {
LOG_ERR("Analog: Failed to convert raw Analog to millivolts: %d", ret);
return Status::READ_ERR;
}
data.millivolts = static_cast<uint16_t>(millivolts);

LOG_DBG("Analog: Raw Analog: %u, Voltage: %u mV", sample_buffer, data.millivolts);

return Status::OK;
}

Status Analog::get_packet(buzzverse_v1_Packet& packet) const {
buzzverse_v1_Analog analog_data = buzzverse_v1_Analog_init_zero;

if(read_data(analog_data) != Sensor::Status::OK) {
return Status::READ_ERR;
}

packet = buzzverse_v1_Packet_init_default;
packet.which_data = buzzverse_v1_Packet_analog_tag;
packet.data.analog = analog_data;
LOG_DBG("Packet constructed with analog data.");
return Status::OK;
}

void Analog::get_status(buzzverse_v1_Status& status_message) const {
status_message.analog_status = status;
}
50 changes: 50 additions & 0 deletions app/src/sensors/analog/analog.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#ifndef ADC_HPP
#define ADC_HPP

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

#include "buzzverse/analog.pb.h"

#include "../peripherals/peripheral.hpp"
#include "../sensor.hpp"
class Analog : public Sensor {
public:
/**
* @brief Constructor for the Analog sensor.
* @param adc_spec A pointer to the Analog device tree specification struct.
* This is obtained using ADC_DT_SPEC_GET() in your main application.
*/
explicit Analog(const struct adc_dt_spec* adc_spec);

// Initializes the sensor hardware (ADC channel setup).
Peripheral::Status init() override;

// Checks if the sensor is ready for reading.
bool is_ready() const override {
return ready;
};

// Returns the name of the sensor.
etl::string<PERIPHERAL_NAME_SIZE> get_name() const override {
return "Analog";
}

Status get_packet(buzzverse_v1_Packet& packet) const override;

void get_status(buzzverse_v1_Status& status_message) const override;

private:
buzzverse_v1_Status_ComponentState status{buzzverse_v1_Status_ComponentState_STATE_UNSPECIFIED};

// Reads data from the sensor and populates the SoilMoistureData struct.
Sensor::Status read_data(buzzverse_v1_Analog& data) const;

// A pointer to the ADC specification struct from the device tree.
const struct adc_dt_spec* m_adc_spec;

bool ready{false}; // Flag to indicate if the sensor is initialized and ready
};

#endif
2 changes: 1 addition & 1 deletion app/src/sensors/bme280/bme280.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ using Status = Sensor::Status;
Peripheral::Status BME280::init() {
if (!device_is_ready(bme280_dev)) {
LOG_WRN("BME280 device not ready");
status = buzzverse_v1_Status_ComponentState_INITIALIZATION_FAILED;
status = buzzverse_v1_Status_ComponentState_INITIALIZATION_FAILED;
return Peripheral::Status::NOT_READY;
}

Expand Down
30 changes: 30 additions & 0 deletions boards/buzzverse/lora_node/lora_node_procpu.dts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
bq27441-i2c = &i2c0;
lora0 = &lora0;
};

zephyr,user {
io-channels = <&adc1 6>;
io-channels-names = "a0";
};

leds {
compatible = "gpio-leds";
Expand Down Expand Up @@ -95,6 +100,31 @@
};
};

/* ADC pin configuration */
&pinctrl {
adc_in_pins: adc_in_pins {
pinmux = <&gpio0 8 GPIO_ACTIVE_LOW>;
};
};


&adc1 {
status = "okay";

#address-cells = <1>;
#size-cells = <0>;

/* Add the label 'soil_sensor' here so the C++ code can find it */
soil_sensor: channel@6 {
reg = <6>;
zephyr,gain = "ADC_GAIN_1";
zephyr,reference = "ADC_REF_INTERNAL";
zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
zephyr,resolution = <12>;
};
};


&spi3 {
#address-cells = <1>;
#size-cells = <0>;
Expand Down
1 change: 1 addition & 0 deletions boards/buzzverse/lora_node/lora_node_procpu.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ supported:
- pwm
- dma
- lora
- esp32s3-pinctrl
testing:
ignore_tags:
- net
Expand Down
Loading