For now only the proportional (Kp) and derivative (Kd) components are used, the integral term is 0.
71 lines
1.3 KiB
C
71 lines
1.3 KiB
C
/* Copyright (c) 2025 Rodrigo Arias Mallo <rodarima@gmail.com>
|
|
* SPDX-License-Identifier: GPL-3.0-or-later */
|
|
|
|
#include "heater.h"
|
|
|
|
#define HEATER_MIN 500UL /* ms */
|
|
#define HEATER_MAX 2000UL /* ms */
|
|
#define HEATER_PERIOD 5000UL /* ms */
|
|
|
|
void
|
|
heater_on(struct heater *h, unsigned long t_ms, float duty)
|
|
{
|
|
unsigned long dt_on = duty * HEATER_MAX;
|
|
|
|
if (dt_on < HEATER_MIN)
|
|
dt_on = 0;
|
|
else if (dt_on > HEATER_MAX)
|
|
dt_on = HEATER_MAX;
|
|
|
|
h->next_on_dt = dt_on;
|
|
|
|
if (h->st == HEATER_OFF) {
|
|
h->st = HEATER_ON;
|
|
h->t0_on = t_ms;
|
|
h->t0_off = t_ms + h->next_on_dt;
|
|
h->cycle = CYCLE_ON;
|
|
}
|
|
}
|
|
|
|
void
|
|
heater_off(struct heater *h)
|
|
{
|
|
h->st = HEATER_OFF;
|
|
}
|
|
|
|
int
|
|
heater_state(struct heater *h, unsigned long t_ms)
|
|
{
|
|
if (h->st == HEATER_OFF)
|
|
return 0;
|
|
|
|
/* Switch state if current time exceeds time limit
|
|
* in the current state */
|
|
/* FIXME: Integer overflow can cause the heater to turn on forever */
|
|
while (1) {
|
|
int changed = 0;
|
|
if (h->cycle == CYCLE_ON) {
|
|
if (t_ms >= h->t0_off) {
|
|
h->cycle = CYCLE_OFF;
|
|
h->t0_on += HEATER_PERIOD;
|
|
changed = 1;
|
|
}
|
|
} else if (h->cycle == CYCLE_OFF) {
|
|
if (t_ms >= h->t0_on) {
|
|
/* Compute current cycle t0_off */
|
|
h->cycle = CYCLE_ON;
|
|
h->t0_off = h->t0_on + h->next_on_dt;
|
|
changed = 1;
|
|
}
|
|
}
|
|
|
|
if (!changed)
|
|
break;
|
|
}
|
|
|
|
if (h->cycle == CYCLE_ON)
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|