code splitting and cleaning

This commit is contained in:
xlemmingx 2025-05-23 10:48:05 +02:00
parent bbedb8d0fd
commit 607a089510
8 changed files with 285 additions and 183 deletions

12
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,12 @@
{
"files.associations": {
"devicetree.h": "c",
"lorawan.h": "c",
"kernel.h": "c",
"device.h": "c",
"log.h": "c",
"mlx90614.h": "c",
"sensor.h": "c",
"sht4x.h": "c"
}
}

123
src/lora/lorawan.c Normal file
View File

@ -0,0 +1,123 @@
#include <zephyr/kernel.h>
#include <zephyr/lorawan/lorawan.h>
#include <zephyr/logging/log.h>
#include <lora/lorawan.h>
/*
TODO:
- DEV NONCE in non volatile memory and increase
- format packets
- send: check if still in network
- downlink callback
// Build payload byte array
uint8_t uplinkPayload[6];
uplinkPayload[0] = uint8_t (int(temp_room_mlx));
uplinkPayload[1] = uint8_t (int((temp_room_mlx-int(temp_room_mlx)*100))); // See notes for high/lowByte functions
uplinkPayload[2] = uint8_t (int(temp_floor));
uplinkPayload[3] = uint8_t (int((temp_floor-int(temp_floor)*100))); // See notes for high/lowByte functions
uplinkPayload[4] = uint8_t (int(humidity));
uplinkPayload[5] = uint8_t (relaisstate); // See notes for high/lowByte functions
*/
const struct device *lora_dev;
struct lorawan_join_config join_cfg;
uint8_t dev_eui[] = LORAWAN_DEV_EUI;
uint8_t join_eui[] = LORAWAN_JOIN_EUI;
uint8_t app_key[] = LORAWAN_APP_KEY;
void init_lorawan() {
int ret;
struct lorawan_downlink_cb downlink_cb = {
.port = LW_RECV_PORT_ANY,
.cb = dl_callback};
lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0));
if (!device_is_ready(lora_dev))
{
LOG_ERR("%s: device not ready.", lora_dev->name);
return 0;
}
ret = lorawan_start();
if (ret < 0)
{
LOG_ERR("lorawan_start failed: %d", ret);
return 0;
}
else
{
LOG_INF("LoraWan started successfully");
}
lorawan_register_downlink_callback(&downlink_cb);
lorawan_register_dr_changed_callback(lorwan_datarate_changed);
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;
join_cfg.otaa.dev_nonce = 14u; // TODO
}
void join_network_otaa() {
int8_t status = -1;
while (lorawan_join(&join_cfg) < 0) {
LOG_ERR("lorawan_join_network failed: %d, retrying..", ret);
k_sleep(K_MSEC(5000));
}
LOG_INF("Joining network over OTAA");
}
void send_data_packet(char *data) {
LOG_INF("Sending data...");
while (1)
{
int8_t ret = lorawan_send(LORAWAN_PORT, data, sizeof(data), LORAWAN_MSG_CONFIRMED);
if (ret == -EAGAIN)
{
LOG_ERR("lorawan_send failed: %d. Continuing...", ret);
k_sleep(DELAY);
continue;
}
if (ret < 0)
{
LOG_ERR("lorawan_send failed: %d", ret);
k_sleep(DELAY);
continue;
}
else
{
LOG_INF("Data sent!");
}
k_sleep(DELAY);
}
}
static void dl_callback(uint8_t port, uint8_t flags, int16_t rssi, int8_t snr, uint8_t len,
const uint8_t *hex_data)
{
LOG_INF("Port %d, Pending %d, RSSI %ddB, SNR %ddBm, Time %d", port,
flags & LORAWAN_DATA_PENDING, rssi, snr, !!(flags & LORAWAN_TIME_UPDATED));
if (hex_data)
{
LOG_HEXDUMP_INF(hex_data, len, "Payload: ");
}
}
static void lorwan_datarate_changed(enum lorawan_datarate dr)
{
uint8_t unused, max_size;
lorawan_get_payload_sizes(&unused, &max_size);
LOG_INF("New Datarate: DR_%d, Max Payload %d", dr, max_size);
}

23
src/lora/lorawan.h Normal file
View File

@ -0,0 +1,23 @@
#include <zephyr/kernel.h>
#include <zephyr/lorawan/lorawan.h>
#define LORAWAN_PORT 2
/* Customize based on network configuration */
#define LORAWAN_DEV_EUI { 0x2D, 0xBF, 0xF6, 0xC2, 0xA1, 0x20,\
0x01, 0x4A }
#define LORAWAN_JOIN_EUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00 }
/* #define LORAWAN_APP_KEY { 0x71, 0x5A, 0x39, 0xB2, 0x86, 0xC3,\
0x37, 0xA3, 0xC4, 0xF0, 0x78, 0xF9,\
0x0F, 0x33, 0x07, 0x7D } */
#define LORAWAN_APP_KEY { 0x71, 0x5A, 0x39, 0xB2, 0x86, 0xC3,\
0x37, 0xA3, 0xC4, 0xF0, 0x78, 0xF9,\
0x0F, 0x33, 0x07, 0x7D }
static void dl_callback(uint8_t port, uint8_t flags, int16_t rssi, int8_t snr, uint8_t len,
const uint8_t *hex_data);
static void lorwan_datarate_changed(enum lorawan_datarate dr);

View File

@ -1,203 +1,29 @@
/*
* Class A LoRaWAN sample application
*
* Copyright (c) 2020 Manivannan Sadhasivam <mani@kernel.org>
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/lorawan/lorawan.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/sensor/sht4x.h>
/* Customize based on network configuration */
#define LORAWAN_DEV_EUI { 0x2D, 0xBF, 0xF6, 0xC2, 0xA1, 0x20,\
0x01, 0x4A }
#define LORAWAN_JOIN_EUI { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
0x00, 0x00 }
/* #define LORAWAN_APP_KEY { 0x71, 0x5A, 0x39, 0xB2, 0x86, 0xC3,\
0x37, 0xA3, 0xC4, 0xF0, 0x78, 0xF9,\
0x0F, 0x33, 0x07, 0x7D } */
#define LORAWAN_APP_KEY { 0x71, 0x5A, 0x39, 0xB2, 0x86, 0xC3,\
0x37, 0xA3, 0xC4, 0xF0, 0x78, 0xF9,\
0x0F, 0x33, 0x07, 0x7D }
#include <lora/lorawan.h>
#include <sensors/mlx90614.h>
#include <sensors/sht4x.h>
#define DELAY K_MSEC(10000)
#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(lorawan_class_a);
char data[] = {'h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'};
static void dl_callback(uint8_t port, uint8_t flags, int16_t rssi, int8_t snr, uint8_t len,
const uint8_t *hex_data)
{
LOG_INF("Port %d, Pending %d, RSSI %ddB, SNR %ddBm, Time %d", port,
flags & LORAWAN_DATA_PENDING, rssi, snr, !!(flags & LORAWAN_TIME_UPDATED));
if (hex_data) {
LOG_HEXDUMP_INF(hex_data, len, "Payload: ");
}
}
static void lorwan_datarate_changed(enum lorawan_datarate dr)
{
uint8_t unused, max_size;
lorawan_get_payload_sizes(&unused, &max_size);
LOG_INF("New Datarate: DR_%d, Max Payload %d", dr, max_size);
}
/* MAIN */
int main(void)
{
// MLX90614 Example Fetch
const struct device *i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c1));
uint8_t reg_addr;
uint8_t read_data[3];
if (!i2c_dev) {
printk("I2C device not found\n");
return;
}
reg_addr = 0x06;
if (i2c_write_read(i2c_dev, 0x5A, &reg_addr, sizeof(reg_addr), &read_data, sizeof(read_data)) < 0)
{
printk("Failed to write to I2C device\n");
}
int16_t temperature = (read_data[1] << 8) | read_data[0]; // Temperaturwert aus den empfangenen Daten
float temp_celsius = temperature * 0.02 - 273.15; // Umrechnung in Celsius
printf("Temperatur Sensor: %.2f °C\n", temp_celsius);
reg_addr = 0x07;
if (i2c_write_read(i2c_dev, 0x5A, &reg_addr, sizeof(reg_addr), &read_data, sizeof(read_data)) < 0)
{
printk("Failed to write to I2C device\n");
}
// Temperaturdaten verarbeiten
temperature = (read_data[1] << 8) | read_data[0]; // Temperaturwert aus den empfangenen Daten
temp_celsius = temperature * 0.02 - 273.15; // Umrechnung in Celsius
printf("Temperatur IR: %.2f °C\n", temp_celsius);
return 0;
/*
// SHT4X Example Fetch
if(!DT_HAS_COMPAT_STATUS_OKAY(sensirion_sht4x)) {
printf("No sensirion,sht4x compatible node found in the device tree");
}
const struct device *const sht = DEVICE_DT_GET_ANY(sensirion_sht4x);
struct sensor_value temp, hum;
if (!device_is_ready(sht)) {
printf("SHT4X-Device %s is not ready.\n", sht->name);
return 0;
}
while (true) {
if (sensor_sample_fetch(sht)) {
printf("Failed to fetch sample from SHT4X device\n");
return 0;
}
sensor_channel_get(sht, SENSOR_CHAN_AMBIENT_TEMP, &temp);
sensor_channel_get(sht, SENSOR_CHAN_HUMIDITY, &hum);
printf("SHT4X: %.2f Temp. [C] ; %0.2f RH [%%]\n",
sensor_value_to_double(&temp),
sensor_value_to_double(&hum));
k_sleep(K_MSEC(5000));
}
*/
const struct device *lora_dev;
struct lorawan_join_config join_cfg;
uint8_t dev_eui[] = LORAWAN_DEV_EUI;
uint8_t join_eui[] = LORAWAN_JOIN_EUI;
uint8_t app_key[] = LORAWAN_APP_KEY;
int ret;
struct lorawan_downlink_cb downlink_cb = {
.port = LW_RECV_PORT_ANY,
.cb = dl_callback
};
lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0));
if (!device_is_ready(lora_dev)) {
LOG_ERR("%s: device not ready.", lora_dev->name);
return 0;
}
ret = lorawan_start();
if (ret < 0) {
LOG_ERR("lorawan_start failed: %d", ret);
return 0;
} else {
LOG_INF("LoraWan started successfully");
}
lorawan_register_downlink_callback(&downlink_cb);
lorawan_register_dr_changed_callback(lorwan_datarate_changed);
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;
join_cfg.otaa.dev_nonce = 14u;
// TODO: Repeat until success
LOG_INF("Joining network over OTAA");
ret = lorawan_join(&join_cfg);
if (ret < 0) {
LOG_ERR("lorawan_join_network failed: %d", ret);
return 0;
}
LOG_INF("Sending data...");
while (1) {
ret = lorawan_send(2, data, sizeof(data),
LORAWAN_MSG_CONFIRMED);
/*
* Note: The stack may return -EAGAIN if the provided data
* length exceeds the maximum possible one for the region and
* datarate. But since we are just sending the same data here,
* we'll just continue.
*/
if (ret == -EAGAIN) {
LOG_ERR("lorawan_send failed: %d. Continuing...", ret);
k_sleep(DELAY);
continue;
}
if (ret < 0) {
LOG_ERR("lorawan_send failed: %d", ret);
k_sleep(DELAY);
continue;
} else {
LOG_INF("Data sent!");
}
k_sleep(DELAY);
}
}

43
src/sensors/mlx90614.c Normal file
View File

@ -0,0 +1,43 @@
#include <sensors/mlx90614.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/devicetree.h>
static struct device *i2c_dev;
static uint16_t i2c_addr = 0x00;
void init_mlx90614() {
i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c1));
i2c_addr = DT_PROP(DT_NODELABEL(mlx90614), reg);
if (!i2c_dev) {
LOG_ERR("I2C device not found!");
return;
} else {
LOG_INF("I2C device initialized.");
}
if (i2c_addr == 0x00) {
LOG_ERR("MLX90614 I2C address fetch from device tree failed!");
} else {
LOG_INF("MLX90614 I2C address found.");
}
}
void request_sensor_data_mlx90614(uint16_t target_addr, const uint8_t *read_data) {
for (int i = 0; i < MLX90614_RETRY_COUNT; i++) {
if (i2c_write_read(i2c_dev, i2c_addr, &target_addr, sizeof(target_addr), &read_data, sizeof(read_data) == 0)) {
LOG_INF("MLX90614 sensor values successfully read after %d tries", i+1);
return;
} else {
k_sleep(K_MSEC(100));
}
}
LOG_ERR("MLX90614 reading sensor values failed %d times!", MLX90614_RETRY_COUNT);
}
float get_temp_from_raw_data_mlx90614(const uint8_t *read_data) {
int16_t temperature = (read_data[1] << 8) | read_data[0]; // Temperaturwert aus den empfangenen Daten
return temperature * 0.02 - 273.15; // Umrechnung in Celsius
}

11
src/sensors/mlx90614.h Normal file
View File

@ -0,0 +1,11 @@
#include <zephyr/kernel.h>
#define MLX90614_INTERNAL_TEMP_ADDR 0x06
#define MLX90614_IR_TEMP_ADDR 0x07
#define MLX90614_RETRY_COUNT 5
int init_mlx90614();
int request_sensor_data_mlx90614(uint16_t target_addr, const uint8_t *read_data);
float get_temp_from_raw_data_mlx90614(const uint8_t *read_data);

55
src/sensors/sht4x.c Normal file
View File

@ -0,0 +1,55 @@
#include <sensors/sht4x.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/sensor/sht4x.h>
static struct device *sht;
void init_sht4x()
{
if (!DT_HAS_COMPAT_STATUS_OKAY(sensirion_sht4x)) {
LOG_ERR("No sensirion,sht4x compatible node found in the device tree");
return;
}
sht = DEVICE_DT_GET_ANY(sensirion_sht4x);
if (!device_is_ready(sht))
{
LOG_ERR("SHT4X-Device %s is not ready.\n", sht->name);
return;
}
}
void request_sensor_data_sht4x()
{
for (int i = 0; i < SHT4X_RETRY_COUNT; i++)
{
if (sensor_sample_fetch(sht) == 0)
{
LOG_INF("SHT4X sensor values successfully read after %d tries", i + 1);
return;
}
else
{
k_sleep(K_MSEC(100));
}
}
LOG_ERR("SHT4X reading sensor values failed %d times!", SHT4X_RETRY_COUNT);
}
float get_value_from_current_sample_sht4x(enum sensor_channel sensor)
{
struct sensor_value value;
float result;
if (sensor_channel_get(sht, sensor, &value) == 0) {
result = sensor_value_to_double(&value);
LOG_INF("Value '%s' successfully read [%f]", sensor, result);
} else {
LOG_ERR("Can't read sensor value '%s' from sample!", sensor);
return 0.0;
}
return value;
}

9
src/sensors/sht4x.h Normal file
View File

@ -0,0 +1,9 @@
#include <zephyr/drivers/sensor.h>
#define SHT4X_RETRY_COUNT 5
void init_sht4x();
void request_sensor_data_sht4x();
float get_value_from_raw_data_sht4x(enum sensor_channel sensor);