Reduce global variables

This commit is contained in:
Rodrigo Arias Mallo 2025-10-13 21:09:06 +02:00
parent eaf4e9d814
commit 2546447652

View File

@ -15,8 +15,8 @@ enum logic {
#define LED_MIN_VALUE 0 #define LED_MIN_VALUE 0
enum state { enum machine_state {
SLEEPING, SLEEPING = 0,
DEBOUNCE, DEBOUNCE,
HEATING, HEATING,
HOT, HOT,
@ -24,16 +24,15 @@ enum state {
COOLING, COOLING,
}; };
long debounce_t0 = 0; //int state = SLEEPING;
int state = SLEEPING;
enum button { enum btn_index {
BUTTON_ON = 0, BTN_ON = 0,
BUTTON_HOT, BTN_HOT,
MAX_BUTTON, MAX_BTN,
}; };
enum button_state { enum btn_state {
RESTING = 0, RESTING = 0,
PRESSING, PRESSING,
PRESSED, PRESSED,
@ -44,23 +43,40 @@ enum button_state {
enum buzz_state { enum buzz_state {
BUZZ_OFF = 0, BUZZ_OFF = 0,
BUZZ_HEY, BUZZ_HEY,
BUZZ_STOP, BUZZ_ACTIVE,
}; };
int buzz_state;
int button_pin[MAX_BUTTON] = { int button_pin[MAX_BTN] = {
[BUTTON_ON] = PIN_POWER_ON, [BTN_ON] = PIN_POWER_ON,
[BUTTON_HOT] = PIN_HOT, [BTN_HOT] = PIN_HOT,
}; };
int button_state[MAX_BUTTON]; struct btn {
unsigned long button_press_t0[MAX_BUTTON]; enum btn_state state;
unsigned long button_release_t0[MAX_BUTTON]; unsigned long press_t0;
unsigned long release_t0;
};
float ntc_R; struct input {
float ntc_T; int ntc_V;
enum logic btn[MAX_BTN];
} g_in;
struct state {
enum machine_state mstate;
unsigned long brewing_t0;
unsigned long cooling_t0;
unsigned long heating_t0;
unsigned long hot_t0;
float ntc_R;
float ntc_T;
struct btn btn[MAX_BTN];
enum buzz_state buzz_state;
unsigned long buzz_t0;
} g_st;
int read_input(int pin) int read_input(int pin)
{ {
@ -85,44 +101,54 @@ void setled(int pin, enum logic st)
digitalWrite(pin, 0); digitalWrite(pin, 0);
} }
void update_buttons() void do_input(struct input *input)
{ {
for (int i = 0; i < MAX_BUTTON; i++) { /* Read buttons */
int st = button_state[i]; for (int i = 0; i < MAX_BTN; i++)
int pin = button_pin[i]; input->btn[i] = read_input(button_pin[i]);
if (st == RESTING) {
if (read_input(pin) == ON) { /* Read temperature sensor */
button_state[i] = PRESSING; input->ntc_V = analogRead(PIN_NTC);
button_press_t0[i] = millis();
}
} else if (st == PRESSING) {
if (read_input(pin) != ON) {
button_state[i] = RESTING;
} else if (millis() - button_press_t0[i] > DEBOUNCE_TIME) {
button_state[i] = PRESSED;
}
} else if (st == PRESSED) {
if (read_input(pin) != ON) {
button_state[i] = RELEASING;
button_release_t0[i] = millis();
}
} else if (st == RELEASING) {
if (read_input(pin) == ON) {
button_state[i] = PRESSED;
} else if (millis() - button_release_t0[i] > DEBOUNCE_TIME) {
button_state[i] = RELEASED;
}
} else if (st == RELEASED) {
button_state[i] = RESTING;
}
}
} }
void update_ntc() void proc_ntc(struct state *state, const struct input *input)
{ {
int Vo = analogRead(PIN_NTC); state->ntc_R = ntc_resistance(input->ntc_V);
ntc_R = ntc_resistance(Vo); state->ntc_T = ntc_temp(state->ntc_R);
ntc_T = ntc_temp(ntc_R); }
void proc_buttons(struct state *state, const struct input *input)
{
for (int i = 0; i < MAX_BTN; i++) {
struct btn *btn = &state->btn[i];
int v = input->btn[i];
if (btn->state == RESTING) {
if (v == ON) {
btn->state = PRESSING;
btn->press_t0 = millis();
}
} else if (btn->state == PRESSING) {
if (v != ON) {
btn->state = RESTING;
} else if (millis() - btn->press_t0 > DEBOUNCE_TIME) {
btn->state = PRESSED;
}
} else if (btn->state == PRESSED) {
if (v != ON) {
btn->state = RELEASING;
btn->release_t0 = millis();
}
} else if (btn->state == RELEASING) {
if (v == ON) {
btn->state = PRESSED;
} else if (millis() - btn->release_t0 > DEBOUNCE_TIME) {
btn->state = RELEASED;
}
} else if (btn->state == RELEASED) {
btn->state = RESTING;
}
}
} }
int red_min = 50; int red_min = 50;
@ -132,90 +158,112 @@ unsigned long cooling_time = 3000UL; /* 3 seconds */
unsigned long max_heating_time = 10000UL; /* 10 seconds */ unsigned long max_heating_time = 10000UL; /* 10 seconds */
unsigned long max_idle_time = 10000UL; /* 10 seconds */ unsigned long max_idle_time = 10000UL; /* 10 seconds */
void progress() void proc_machine(struct state *st)
{ {
int temp = analogRead(PIN_NTC); float temp = st->ntc_T;
int on = (button_state[BUTTON_ON] == RELEASED); int on = (st->btn[BTN_ON].state == RELEASED);
int hot = (button_state[BUTTON_HOT] == PRESSED); int hot = (st->btn[BTN_HOT].state == PRESSED);
static unsigned long brewing_t0 = 0;
static unsigned long cooling_t0 = 0;
static unsigned long heating_t0 = 0;
static unsigned long hot_t0 = 0;
Serial.print("state="); Serial.print("state=");
Serial.print(state); Serial.print(st->mstate);
Serial.print(" on="); Serial.print(" on=");
Serial.print(on); Serial.print(on);
Serial.print(" temp="); Serial.print(" temp=");
Serial.println(temp); Serial.print(temp);
Serial.println(" C");
/* Pressing ON cancels any operation */ /* Pressing ON cancels any operation */
if (state != SLEEPING && on) { if (st->mstate != SLEEPING && on) {
state = SLEEPING; st->mstate = SLEEPING;
st->buzz_state = BUZZ_OFF;
return; return;
} }
if (state == SLEEPING) { if (st->mstate == SLEEPING) {
if (on) { if (on) {
state = HEATING; st->mstate = HEATING;
heating_t0 = millis(); st->heating_t0 = millis();
Serial.println("heating"); Serial.println("heating");
} }
} else if (state == HEATING) { } else if (st->mstate == HEATING) {
if (temp > TEMP_MAX) { if (temp > TEMP_MAX) {
state = HOT; st->mstate = HOT;
hot_t0 = millis(); st->hot_t0 = millis();
buzz_state = BUZZ_HEY; st->buzz_state = BUZZ_HEY;
Serial.println("hot"); Serial.println("hot");
} else if (millis() - heating_t0 > max_heating_time) { } else if (millis() - st->heating_t0 > max_heating_time) {
/* TODO: Add alarm state */ /* TODO: Add alarm state */
state = SLEEPING; st->mstate = SLEEPING;
Serial.println("cannot heat, going to sleep"); Serial.println("cannot heat, going to sleep");
} }
} else if (state == HOT) { } else if (st->mstate == HOT) {
if (hot) { if (hot) {
state = BREWING; st->mstate = BREWING;
brewing_t0 = millis(); st->brewing_t0 = millis();
Serial.println("brewing"); Serial.println("brewing");
} else if (millis() - hot_t0 > max_idle_time) { } else if (millis() - st->hot_t0 > max_idle_time) {
state = SLEEPING; st->mstate = SLEEPING;
Serial.println("idle timeout, going to sleep"); Serial.println("idle timeout, going to sleep");
} }
} else if (state == BREWING) { } else if (st->mstate == BREWING) {
if (millis() - brewing_t0 > brewing_time) { if (millis() - st->brewing_t0 > brewing_time) {
state = COOLING; st->mstate = COOLING;
cooling_t0 = millis(); st->cooling_t0 = millis();
Serial.println("cooling"); Serial.println("cooling");
} }
} else if (state == COOLING) { } else if (st->mstate == COOLING) {
/* TODO: Wait a bit and go back to heating */ /* TODO: Wait a bit and go back to heating */
if (millis() - cooling_t0 > cooling_time) { if (millis() - st->cooling_t0 > cooling_time) {
state = HEATING; st->mstate = HEATING;
heating_t0 = millis(); st->heating_t0 = millis();
Serial.println("heating"); Serial.println("heating");
} }
} }
} }
void void
update_leds() proc_buzz(struct state *st)
{
if (st->buzz_state == BUZZ_HEY) {
tone(PIN_BUZZ, 1500);
st->buzz_state = BUZZ_ACTIVE;
st->buzz_t0 = millis();
} else if (st->buzz_state == BUZZ_ACTIVE) {
if (millis() - st->buzz_t0 > 20) {
st->buzz_state = BUZZ_OFF;
noTone(PIN_BUZZ);
}
} else {
noTone(PIN_BUZZ);
}
}
void do_proc(struct state *st, const struct input *input)
{
proc_ntc(st, input);
proc_buttons(st, input);
proc_machine(st);
proc_buzz(st);
}
void
output_leds(const struct state *st)
{ {
static int r = 0; static int r = 0;
static int g = 0; static int g = 0;
if (state == HEATING || state == COOLING) { if (st->mstate == HEATING || st->mstate == COOLING) {
analogWrite(PIN_LED_RED, r); analogWrite(PIN_LED_RED, r);
setled(PIN_LED_GREEN, 0); setled(PIN_LED_GREEN, 0);
if (r >= 255) if (r >= 255)
r = 0; r = 0;
else else
r += 3; r += 3;
} else if (state == HOT) { } else if (st->mstate == HOT) {
setled(PIN_LED_RED, 0); setled(PIN_LED_RED, 0);
setled(PIN_LED_GREEN, 1); setled(PIN_LED_GREEN, 1);
r = 0; r = 0;
} else if (state == BREWING) { } else if (st->mstate == BREWING) {
setled(PIN_LED_RED, 0); setled(PIN_LED_RED, 0);
analogWrite(PIN_LED_GREEN, g); analogWrite(PIN_LED_GREEN, g);
if (g >= 255) if (g >= 255)
@ -229,28 +277,13 @@ update_leds()
} }
} }
/* Return the temperature in celsisus */
float
measure_temp()
{
int Vo = analogRead(PIN_NTC);
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;
float R1 = 10e3; /* 10 kOhm resistor */
float R2 = R1 * (1023.0 / (float)Vo - 1.0);
float logR2 = log(R2);
float T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2));
float Tc = T - 273.15;
return Tc;
}
void void
update_heater() output_heater(const struct state *st)
{ {
if (state == HEATING || state == HOT || state == BREWING) { if (st->mstate == HEATING || st->mstate == HOT || st->mstate == BREWING) {
int temp = measure_temp(); if (st->ntc_T < TEMP_MIN)
if (temp < TEMP_MIN)
relay(PIN_HEAT, ON); relay(PIN_HEAT, ON);
else if (temp > TEMP_MAX) else if (st->ntc_T > TEMP_MAX)
relay(PIN_HEAT, OFF); relay(PIN_HEAT, OFF);
} else { } else {
relay(PIN_HEAT, OFF); relay(PIN_HEAT, OFF);
@ -258,47 +291,18 @@ update_heater()
} }
void void
update_pump() output_pump(const struct state *st)
{ {
if (state == BREWING) { if (st->mstate == BREWING)
relay(PIN_PUMP, ON); relay(PIN_PUMP, ON);
} else { else
relay(PIN_PUMP, OFF); relay(PIN_PUMP, OFF);
}
} }
void void do_output(const struct state *st)
update_buzz()
{ {
static unsigned long started = 0; output_leds(st);
output_heater(st);
if (buzz_state == BUZZ_HEY) {
tone(PIN_BUZZ, 1500);
if (started == 0)
started = millis();
else if (millis() - started > 20) {
buzz_state = BUZZ_OFF;
}
} else if (buzz_state == BUZZ_STOP) {
tone(PIN_BUZZ, 220);
} else if (buzz_state == BUZZ_OFF) {
noTone(PIN_BUZZ);
started = 0;
}
}
void inputs()
{
update_buttons();
update_ntc();
}
void outputs()
{
update_leds();
update_heater();
update_pump();
update_buzz();
} }
void setup() void setup()
@ -323,9 +327,9 @@ void setup()
void loop() void loop()
{ {
inputs(); do_input(&g_in);
progress(); do_proc(&g_st, &g_in);
outputs(); do_output(&g_st);
delay(5); delay(5);
} }