Dein Warenkorb ist gerade leer!
KW-Kaltwasser Regelung
… wie erstelle ich so eine Regelung auf einem STM32…
🔧 Systemüberblick
Hauptfunktionen:
- Ventilatorsteuerung: 0–10 V (DAC), Start mit 100 %, Absenkung nach X Sekunden auf konfigurierbaren Sollwert.
- CW-Ventilsteuerung: 0–10 V (DAC, 2-Punkt-Regelung) nach Raumtemperatur und -feuchte.
- Digitale Eingänge: Filteralarm, Ventilatoralarm.
- Alarmsystem: Min/Max-Grenzen, Sammelalarm, Reset über Befehl.
- UART-Interface: Für Konfiguration (Sollwerte, Schwellwerte, Start/Stop, Reset).
- FreeRTOS Task-Struktur: Regelung in separater Task.
📁 Modulstruktur
1. climate_controller.c/h
Funktion: Hauptlogik der Regelung (FreeRTOS Task)
- vClimateControllerTask(void *params)
- void ClimateController_Start()
- void ClimateController_Stop()
- void ClimateController_ResetAlarms()
- bool ClimateController_IsAlarmActive()
2. fan_control.c/h
Funktion: Steuerung des Ventilators
- Start bei 100 %
- Nachlaufzeit gesteuert
- MCP4728: DAC-Ausgabe (CH1)
3. valve_control.c/h
Funktion: 2-Punkt-Regelung des CW-Ventils
- Öffnen bei Überschreiten des Temperatur- oder Feuchtesollwerts
- Schließen bei Unterschreitung
- MCP4728: DAC-Ausgabe (CH2)
4. alarms.c/h
Funktion: Alarmverwaltung
- Einzelalarme (Filter, Lüfter, Min/Max Temp/Feuchte)
- Sammelalarm-Status
- Alarm-Reset
5. settings.c/h
Funktion: Speicherung und Verwaltung von Einstellungen
- Sollwerte: Temperatur, Feuchte, Lüfterleistung
- Grenzwerte: Min/Max Temp/Feuchte
- Nachlaufzeit
- Start-/Stopp-Status
6. uart_interface.c/h
Funktion: Terminal-Interface für Konfiguration
- set temp <value>
- set hum <value>
- set fan <value>
- set limits temp <min> <max>
- set limits hum <min> <max>
- set fan_fallback_time <s>
- start, stop, alarmreset, status
7. sensors.c/h
Funktion: Lesen der Temperatur- und Feuchtedaten
- Verwendung von I2C/SPI-Sensor (abhängig von HW)
- Update über Task oder Timer
------------------------------------------------------------------
🧠 FreeRTOS Task-Konzept:
| Task | Beschreibung | Zyklus |
| ----------------------- | ----------------------------- | -------- |
| `ClimateControllerTask` | Hauptregelung & Alarmhandling | 1 s |
| `UARTTask` | Eingabe verarbeiten | Ereignis |
| `SensorTask` | Temperatur- & Feuchtemessung | 500 ms |
------------------------------------------------------------------
📏 Beispielhafte Haupt-Logik:
void ClimateControllerTask(void *params) {
while (1) {
if (!settings.system_enabled) {
FanControl_Set(0);
ValveControl_SetClosed();
vTaskDelay(pdMS_TO_TICKS(1000));
continue;
}
float temp = Sensors_GetTemperature();
float hum = Sensors_GetHumidity();
// Alarm-Check
Alarms_Check(temp, hum, DI_Filter, DI_Fan);
// Lüftersteuerung
if (system_time_since_start < settings.fan_fallback_time) {
FanControl_Set(100);
} else {
FanControl_Set(settings.fan_setpoint);
}
// CW-Ventil
if (temp > settings.temp_setpoint || hum > settings.hum_setpoint) {
ValveControl_SetOpen();
} else {
ValveControl_SetClosed();
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
------------------------------------------------------------------
💬 UART-Befehle:
| Befehl | Beschreibung |
| -------------------------- | -------------------------------- |
| `set temp 23.5` | Temperatur-Sollwert setzen |
| `set hum 45` | Feuchte-Sollwert setzen |
| `set fan 60` | Lüfter-Sollwert (in %) setzen |
| `set limits temp 20 26` | Temp-Min/Max setzen |
| `set limits hum 30 60` | Feuchte-Min/Max setzen |
| `set fan_fallback_time 10` | Zeit (s) bis Lüfter absinkt |
| `start` / `stop` | Regelung aktivieren/deaktivieren |
| `alarmreset` | Alle Alarme zurücksetzen |
| `status` | Gibt aktuellen Status aus |
------------------------------------------------------------------
📌 Hardware-Voraussetzungen
- MCP4728: 0–10 V DAC (mit externer OPV-Verstärkung auf 0–10 V, da MCP4728 max. Vdd-Referenz hat)
- CH1: Lüfter
- CH2: CW-Ventil
- Digitale Eingänge: Ventilator- und Filteralarm
- Sensoren: z. B. SHT31, AHT10, DHT22 oder Sensirion SCD3x
- UART (z. B. USART3): Terminal (19200 Baud, 8N1)
------------------------------------------------------------------
Regelungsdateien starten hier:
------------------------------------------------------------------
// climate_controller.h
------------------------------------------------------------------
#ifndef CLIMATE_CONTROLLER_H
#define CLIMATE_CONTROLLER_H
#include <stdbool.h>
void ClimateController_Start();
void ClimateController_Stop();
void ClimateController_ResetAlarms();
bool ClimateController_IsAlarmActive();
void ClimateControllerTask(void *params);
#endif // CLIMATE_CONTROLLER_H
------------------------------------------------------------------
// climate_controller.c
------------------------------------------------------------------
#include "climate_controller.h"
#include "settings.h"
#include "fan_control.h"
#include "valve_control.h"
#include "alarms.h"
#include "sensors.h"
#include "main.h"
#include "cmsis_os.h"
static uint32_t start_time_ms = 0;
void ClimateController_Start() {
settings.system_enabled = true;
start_time_ms = HAL_GetTick();
}
void ClimateController_Stop() {
settings.system_enabled = false;
FanControl_Set(0);
ValveControl_SetClosed();
}
void ClimateController_ResetAlarms() {
Alarms_Reset();
}
bool ClimateController_IsAlarmActive() {
return Alarms_IsAnyActive();
}
void ClimateControllerTask(void *params) {
for (;;) {
if (!settings.system_enabled) {
FanControl_Set(0);
ValveControl_SetClosed();
osDelay(1000);
continue;
}
float temp = Sensors_GetTemperature();
float hum = Sensors_GetHumidity();
Alarms_Check(temp, hum);
uint32_t elapsed = HAL_GetTick() - start_time_ms;
if (elapsed < settings.fan_fallback_time_s * 1000) {
FanControl_Set(100);
} else {
FanControl_Set(settings.fan_setpoint);
}
if (temp > settings.temp_setpoint || hum > settings.hum_setpoint) {
ValveControl_SetOpen();
} else {
ValveControl_SetClosed();
}
osDelay(1000);
}
}
------------------------------------------------------------------
// fan_control.h
------------------------------------------------------------------
#ifndef FAN_CONTROL_H
#define FAN_CONTROL_H
void FanControl_Init();
void FanControl_Set(uint8_t percent);
#endif // FAN_CONTROL_H
------------------------------------------------------------------
// fan_control.c
------------------------------------------------------------------
#include "fan_control.h"
#include "mcp4728.h"
void FanControl_Init() {
// Init DAC channel if needed
}
void FanControl_Set(uint8_t percent) {
if (percent > 100) percent = 100;
uint16_t value = (uint16_t)((percent / 100.0f) * 4095);
MCP4728_SetChannelValue(0, value); // CH1
}
------------------------------------------------------------------
// valve_control.h
------------------------------------------------------------------
#ifndef VALVE_CONTROL_H
#define VALVE_CONTROL_H
void ValveControl_Init();
void ValveControl_SetOpen();
void ValveControl_SetClosed();
#endif // VALVE_CONTROL_H
------------------------------------------------------------------
// valve_control.c
------------------------------------------------------------------
#include "valve_control.h"
#include "mcp4728.h"
void ValveControl_Init() {
// Init DAC channel if needed
}
void ValveControl_SetOpen() {
MCP4728_SetChannelValue(1, 4095); // CH2 = 10V
}
void ValveControl_SetClosed() {
MCP4728_SetChannelValue(1, 0);
}
------------------------------------------------------------------
// alarms.h
------------------------------------------------------------------
#ifndef ALARMS_H
#define ALARMS_H
#include <stdbool.h>
void Alarms_Check(float temp, float hum);
void Alarms_Reset();
bool Alarms_IsAnyActive();
extern bool alarm_temp_min;
extern bool alarm_temp_max;
extern bool alarm_hum_min;
extern bool alarm_hum_max;
extern bool alarm_filter;
extern bool alarm_fan;
#endif // ALARMS_H
------------------------------------------------------------------
// alarms.c
------------------------------------------------------------------
#include "alarms.h"
#include "settings.h"
#include "main.h"
bool alarm_temp_min = false;
bool alarm_temp_max = false;
bool alarm_hum_min = false;
bool alarm_hum_max = false;
bool alarm_filter = false;
bool alarm_fan = false;
void Alarms_Check(float temp, float hum) {
alarm_temp_min = temp < settings.temp_min;
alarm_temp_max = temp > settings.temp_max;
alarm_hum_min = hum < settings.hum_min;
alarm_hum_max = hum > settings.hum_max;
alarm_filter = HAL_GPIO_ReadPin(FILTER_ALARM_GPIO_Port, FILTER_ALARM_Pin) == GPIO_PIN_RESET;
alarm_fan = HAL_GPIO_ReadPin(FAN_ALARM_GPIO_Port, FAN_ALARM_Pin) == GPIO_PIN_RESET;
}
void Alarms_Reset() {
alarm_temp_min = alarm_temp_max = alarm_hum_min = alarm_hum_max = false;
alarm_filter = alarm_fan = false;
}
bool Alarms_IsAnyActive() {
return alarm_temp_min || alarm_temp_max || alarm_hum_min || alarm_hum_max || alarm_filter || alarm_fan;
}
------------------------------------------------------------------
// settings.h
------------------------------------------------------------------
#ifndef SETTINGS_H
#define SETTINGS_H
#include <stdint.h>
#include <stdbool.h>
typedef struct {
float temp_setpoint;
float hum_setpoint;
uint8_t fan_setpoint;
float temp_min, temp_max;
float hum_min, hum_max;
uint16_t fan_fallback_time_s;
bool system_enabled;
} SystemSettings;
extern SystemSettings settings;
#endif // SETTINGS_H
------------------------------------------------------------------
// settings.c
------------------------------------------------------------------
#include "settings.h"
SystemSettings settings = {
.temp_setpoint = 24.0,
.hum_setpoint = 50.0,
.fan_setpoint = 60,
.temp_min = 20.0,
.temp_max = 26.0,
.hum_min = 30.0,
.hum_max = 60.0,
.fan_fallback_time_s = 10,
.system_enabled = false
};
------------------------------------------------------------------
// sensors.h
------------------------------------------------------------------
#ifndef SENSORS_H
#define SENSORS_H
float Sensors_GetTemperature();
float Sensors_GetHumidity();
#endif // SENSORS_H
------------------------------------------------------------------
// sensors.c
------------------------------------------------------------------
#include "sensors.h"
// Dummy functions
float Sensors_GetTemperature() {
return 23.5;
}
float Sensors_GetHumidity() {
return 48.0;
}
------------------------------------------------------------------
// uart_interface.h
------------------------------------------------------------------
#ifndef UART_INTERFACE_H
#define UART_INTERFACE_H
void UARTInterface_Task(void *params);
#endif // UART_INTERFACE_H
------------------------------------------------------------------
// uart_interface.c
------------------------------------------------------------------
#include "uart_interface.h"
#include "settings.h"
#include "climate_controller.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Dummy UART receive function
static void parse_command(const char *cmd) {
if (strncmp(cmd, "set temp ", 9) == 0) {
settings.temp_setpoint = atof(&cmd[9]);
} else if (strncmp(cmd, "set hum ", 8) == 0) {
settings.hum_setpoint = atof(&cmd[8]);
} else if (strncmp(cmd, "set fan ", 8) == 0) {
settings.fan_setpoint = atoi(&cmd[8]);
} else if (strncmp(cmd, "set fan_fallback_time ", 23) == 0) {
settings.fan_fallback_time_s = atoi(&cmd[23]);
} else if (strcmp(cmd, "start") == 0) {
ClimateController_Start();
} else if (strcmp(cmd, "stop") == 0) {
ClimateController_Stop();
} else if (strcmp(cmd, "alarmreset") == 0) {
ClimateController_ResetAlarms();
} else if (strcmp(cmd, "status") == 0) {
printf("Temp: %.1f, Hum: %.1f, Fan: %u%%\r\n",
Sensors_GetTemperature(),
Sensors_GetHumidity(),
settings.fan_setpoint);
}
}
void UARTInterface_Task(void *params) {
char rx_buffer[64];
while (1) {
// Implement UART receive to fill rx_buffer
// parse_command(rx_buffer);
osDelay(500);
}
}
------------------------------------------------------------------
Was ist bis jetzt alles Implementiert:
------------------------------------------------------------------
- climate_controller: Hauptregelungs-Task
- fan_control: DAC-Ausgabe für Ventilator
- valve_control: DAC-Ausgabe für CW-Ventil
- alarms: Überwachung der Grenzwerte und digitalen Alarme
- settings: Einstellungsverwaltung
- sensors: Platzhalter für Temperatur-/Feuchtesensoren
- uart_interface: Terminalsteuerung über UART
------------------------------------------------------------------
Tags:

Schreibe einen Kommentar