Add dual temperature threshold control with MLX sensor fallback
- Add separate thresholds for room temp (21°C) and floor temp (22°C) - Use t1/t2 downlink commands for setting thresholds - Automatically disable floor temp monitoring if MLX sensor fails - Relay turns off if either temperature threshold is exceeded - Robust operation with or without floor temperature sensor
This commit is contained in:
parent
de28645511
commit
64f9d49448
@ -14,6 +14,7 @@ LOG_MODULE_REGISTER(lorawan_class_a);
|
|||||||
extern bool relais_state;
|
extern bool relais_state;
|
||||||
extern bool relais_manual_override;
|
extern bool relais_manual_override;
|
||||||
extern uint8_t temperature_threshold;
|
extern uint8_t temperature_threshold;
|
||||||
|
extern uint8_t floor_temp_threshold;
|
||||||
const static struct device *lora_dev;
|
const static struct device *lora_dev;
|
||||||
static struct lorawan_join_config join_cfg;
|
static struct lorawan_join_config join_cfg;
|
||||||
static uint8_t dev_eui[8];
|
static uint8_t dev_eui[8];
|
||||||
@ -62,19 +63,34 @@ static void dl_callback(uint8_t port, uint8_t flags, int16_t rssi, int8_t snr, u
|
|||||||
LOG_WRN("Invalid relais command value: %d (valid: 0=OFF, 1=AUTO)", relais_value);
|
LOG_WRN("Invalid relais command value: %d (valid: 0=OFF, 1=AUTO)", relais_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Temperature threshold command: t[temp] (e.g., "t18" for 18°C) */
|
/* Room temperature threshold command: t1[temp] (e.g., "t1" + 18 for 18°C) */
|
||||||
else if (len > 2 && hex_data[0] == 't')
|
else if (len > 3 && hex_data[0] == 't' && hex_data[1] == '1')
|
||||||
{
|
{
|
||||||
uint8_t new_threshold = hex_data[1];
|
uint8_t new_threshold = hex_data[2];
|
||||||
if (new_threshold >= 10 && new_threshold <= 35) // Valid range 10-35°C
|
if (new_threshold >= 10 && new_threshold <= 35) // Valid range 10-35°C
|
||||||
{
|
{
|
||||||
temperature_threshold = new_threshold;
|
temperature_threshold = new_threshold;
|
||||||
relais_manual_override = false; // Re-enable automatic control
|
relais_manual_override = false; // Re-enable automatic control
|
||||||
LOG_INF("Temperature threshold updated to %d°C, automatic control enabled", temperature_threshold);
|
LOG_INF("Room temperature threshold updated to %d°C, automatic control enabled", temperature_threshold);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_WRN("Invalid temperature threshold %d°C (valid range: 10-35°C)", new_threshold);
|
LOG_WRN("Invalid room temperature threshold %d°C (valid range: 10-35°C)", new_threshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Floor temperature threshold command: t2[temp] (e.g., "t2" + 22 for 22°C) */
|
||||||
|
else if (len > 3 && hex_data[0] == 't' && hex_data[1] == '2')
|
||||||
|
{
|
||||||
|
uint8_t new_threshold = hex_data[2];
|
||||||
|
if (new_threshold >= 15 && new_threshold <= 40) // Valid range 15-40°C
|
||||||
|
{
|
||||||
|
floor_temp_threshold = new_threshold;
|
||||||
|
relais_manual_override = false; // Re-enable automatic control
|
||||||
|
LOG_INF("Floor temperature threshold updated to %d°C, automatic control enabled", floor_temp_threshold);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_WRN("Invalid floor temperature threshold %d°C (valid range: 15-40°C)", new_threshold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
0x0F, 0x0F}
|
0x0F, 0x0F}
|
||||||
|
|
||||||
#define RETRY_DELAY K_MSEC(1000)
|
#define RETRY_DELAY K_MSEC(1000)
|
||||||
#define SEND_INTERVALL K_MINUTES(5)
|
#define SEND_INTERVALL K_SECONDS(20)
|
||||||
|
|
||||||
void init_lorawan();
|
void init_lorawan();
|
||||||
|
|
||||||
|
|||||||
18
src/main.c
18
src/main.c
@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(g2h_heat_main);
|
|||||||
volatile bool relais_state = false;
|
volatile bool relais_state = false;
|
||||||
volatile bool relais_manual_override = false;
|
volatile bool relais_manual_override = false;
|
||||||
volatile uint8_t temperature_threshold = 21;
|
volatile uint8_t temperature_threshold = 21;
|
||||||
|
volatile uint8_t floor_temp_threshold = 22;
|
||||||
|
|
||||||
/* MAIN */
|
/* MAIN */
|
||||||
int main(void)
|
int main(void)
|
||||||
@ -48,14 +49,23 @@ int main(void)
|
|||||||
|
|
||||||
/* Set relais based on temperature if not manually overridden */
|
/* Set relais based on temperature if not manually overridden */
|
||||||
if (!relais_manual_override) {
|
if (!relais_manual_override) {
|
||||||
if (temp < temperature_threshold) {
|
bool temp_condition = temp < temperature_threshold;
|
||||||
relais_state = 1; // Heat on below threshold
|
bool floor_condition = true; // Default: ignore floor temp if sensor not available
|
||||||
|
|
||||||
|
// Only check floor temperature if MLX sensor is working
|
||||||
|
if (mlx90614_sensor_available) {
|
||||||
|
floor_condition = floor_temp < floor_temp_threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp_condition && floor_condition) {
|
||||||
|
relais_state = 1; // Heat on below thresholds
|
||||||
} else {
|
} else {
|
||||||
relais_state = 0; // Heat off at/above threshold
|
relais_state = 0; // Heat off if any threshold exceeded
|
||||||
}
|
}
|
||||||
set_relais_state(relais_state);
|
set_relais_state(relais_state);
|
||||||
}
|
}
|
||||||
printk("relais: %d (manual: %d, threshold: %d°C)\n", relais_state, relais_manual_override, temperature_threshold);
|
printk("relais: %d (manual: %d, temp_th: %d°C, floor_th: %d°C)\n",
|
||||||
|
relais_state, relais_manual_override, temperature_threshold, floor_temp_threshold);
|
||||||
|
|
||||||
/* Pack and send values */
|
/* Pack and send values */
|
||||||
char data[7];
|
char data[7];
|
||||||
|
|||||||
@ -8,28 +8,34 @@
|
|||||||
LOG_MODULE_REGISTER(mlx90614);
|
LOG_MODULE_REGISTER(mlx90614);
|
||||||
|
|
||||||
static const struct device *i2c_dev;
|
static const struct device *i2c_dev;
|
||||||
static const uint16_t i2c_addr = 0x5A;
|
|
||||||
static uint8_t read_data_buffer[3];
|
static uint8_t read_data_buffer[3];
|
||||||
|
bool mlx90614_sensor_available = false;
|
||||||
|
|
||||||
int init_mlx90614() {
|
int init_mlx90614()
|
||||||
|
{
|
||||||
i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c1));
|
i2c_dev = DEVICE_DT_GET(DT_NODELABEL(i2c1));
|
||||||
|
|
||||||
if (!i2c_dev) {
|
if (!i2c_dev)
|
||||||
|
{
|
||||||
LOG_ERR("I2C device not found!");
|
LOG_ERR("I2C device not found!");
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
LOG_INF("I2C device initialized.");
|
LOG_INF("I2C device initialized.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void request_sensor_data_mlx90614(uint8_t target_addr) {
|
void request_sensor_data_mlx90614(uint8_t target_addr)
|
||||||
|
{
|
||||||
uint8_t err;
|
uint8_t err;
|
||||||
for (int i = 0; i < MLX90614_RETRY_COUNT; i++)
|
for (int i = 0; i < MLX90614_RETRY_COUNT; i++)
|
||||||
{
|
{
|
||||||
err = i2c_write_read(i2c_dev, 0x5A, &target_addr, sizeof(target_addr), &read_data_buffer, sizeof(read_data_buffer));
|
err = i2c_write_read(i2c_dev, 0x5A, &target_addr, sizeof(target_addr), &read_data_buffer, sizeof(read_data_buffer));
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
{
|
{
|
||||||
LOG_INF("MLX90614 sensor values successfully read after %d tries", i+1);
|
LOG_INF("MLX90614 sensor values successfully read after %d tries", i + 1);
|
||||||
|
mlx90614_sensor_available = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -38,9 +44,11 @@ void request_sensor_data_mlx90614(uint8_t target_addr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOG_ERR("MLX90614 reading sensor values failed %d times with error %d!", MLX90614_RETRY_COUNT, err);
|
LOG_ERR("MLX90614 reading sensor values failed %d times with error %d!", MLX90614_RETRY_COUNT, err);
|
||||||
|
mlx90614_sensor_available = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_temp_from_raw_data_mlx90614() {
|
float get_temp_from_raw_data_mlx90614()
|
||||||
|
{
|
||||||
int16_t temperature = (read_data_buffer[1] << 8) | read_data_buffer[0]; // Temperaturwert aus den empfangenen Daten
|
int16_t temperature = (read_data_buffer[1] << 8) | read_data_buffer[0]; // Temperaturwert aus den empfangenen Daten
|
||||||
return temperature * 0.02 - 273.15; // Umrechnung in Celsius
|
return temperature * 0.02 - 273.15; // Umrechnung in Celsius
|
||||||
}
|
}
|
||||||
@ -1,9 +1,12 @@
|
|||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define MLX90614_INTERNAL_TEMP_ADDR 0x06
|
#define MLX90614_INTERNAL_TEMP_ADDR 0x06
|
||||||
#define MLX90614_IR_TEMP_ADDR 0x07
|
#define MLX90614_IR_TEMP_ADDR 0x07
|
||||||
#define MLX90614_RETRY_COUNT 5
|
#define MLX90614_RETRY_COUNT 5
|
||||||
|
|
||||||
|
extern bool mlx90614_sensor_available;
|
||||||
|
|
||||||
int init_mlx90614();
|
int init_mlx90614();
|
||||||
|
|
||||||
void request_sensor_data_mlx90614(uint8_t target_addr);
|
void request_sensor_data_mlx90614(uint8_t target_addr);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user