diff --git a/barista/barista.ino b/barista/barista.ino index d014ea8..553c34e 100644 --- a/barista/barista.ino +++ b/barista/barista.ino @@ -15,8 +15,8 @@ enum logic { #define LED_MIN_VALUE 0 -enum state { - SLEEPING, +enum machine_state { + SLEEPING = 0, DEBOUNCE, HEATING, HOT, @@ -24,16 +24,15 @@ enum state { COOLING, }; -long debounce_t0 = 0; -int state = SLEEPING; +//int state = SLEEPING; -enum button { - BUTTON_ON = 0, - BUTTON_HOT, - MAX_BUTTON, +enum btn_index { + BTN_ON = 0, + BTN_HOT, + MAX_BTN, }; -enum button_state { +enum btn_state { RESTING = 0, PRESSING, PRESSED, @@ -44,23 +43,40 @@ enum button_state { enum buzz_state { BUZZ_OFF = 0, BUZZ_HEY, - BUZZ_STOP, + BUZZ_ACTIVE, }; -int buzz_state; -int button_pin[MAX_BUTTON] = { - [BUTTON_ON] = PIN_POWER_ON, - [BUTTON_HOT] = PIN_HOT, +int button_pin[MAX_BTN] = { + [BTN_ON] = PIN_POWER_ON, + [BTN_HOT] = PIN_HOT, }; -int button_state[MAX_BUTTON]; -unsigned long button_press_t0[MAX_BUTTON]; -unsigned long button_release_t0[MAX_BUTTON]; +struct btn { + enum btn_state state; + unsigned long press_t0; + unsigned long release_t0; +}; -float ntc_R; -float ntc_T; +struct input { + 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) { @@ -85,44 +101,54 @@ void setled(int pin, enum logic st) digitalWrite(pin, 0); } -void update_buttons() +void do_input(struct input *input) { - for (int i = 0; i < MAX_BUTTON; i++) { - int st = button_state[i]; - int pin = button_pin[i]; - if (st == RESTING) { - if (read_input(pin) == ON) { - button_state[i] = PRESSING; - 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; - } - } + /* Read buttons */ + for (int i = 0; i < MAX_BTN; i++) + input->btn[i] = read_input(button_pin[i]); + + /* Read temperature sensor */ + input->ntc_V = analogRead(PIN_NTC); } -void update_ntc() +void proc_ntc(struct state *state, const struct input *input) { - int Vo = analogRead(PIN_NTC); - ntc_R = ntc_resistance(Vo); - ntc_T = ntc_temp(ntc_R); + state->ntc_R = ntc_resistance(input->ntc_V); + state->ntc_T = ntc_temp(state->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; @@ -132,90 +158,112 @@ unsigned long cooling_time = 3000UL; /* 3 seconds */ unsigned long max_heating_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); - int on = (button_state[BUTTON_ON] == RELEASED); - int hot = (button_state[BUTTON_HOT] == 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; + float temp = st->ntc_T; + int on = (st->btn[BTN_ON].state == RELEASED); + int hot = (st->btn[BTN_HOT].state == PRESSED); Serial.print("state="); - Serial.print(state); + Serial.print(st->mstate); Serial.print(" on="); Serial.print(on); Serial.print(" temp="); - Serial.println(temp); + Serial.print(temp); + Serial.println(" C"); /* Pressing ON cancels any operation */ - if (state != SLEEPING && on) { - state = SLEEPING; + if (st->mstate != SLEEPING && on) { + st->mstate = SLEEPING; + st->buzz_state = BUZZ_OFF; return; } - if (state == SLEEPING) { + if (st->mstate == SLEEPING) { if (on) { - state = HEATING; - heating_t0 = millis(); + st->mstate = HEATING; + st->heating_t0 = millis(); Serial.println("heating"); } - } else if (state == HEATING) { + } else if (st->mstate == HEATING) { if (temp > TEMP_MAX) { - state = HOT; - hot_t0 = millis(); - buzz_state = BUZZ_HEY; + st->mstate = HOT; + st->hot_t0 = millis(); + st->buzz_state = BUZZ_HEY; Serial.println("hot"); - } else if (millis() - heating_t0 > max_heating_time) { + } else if (millis() - st->heating_t0 > max_heating_time) { /* TODO: Add alarm state */ - state = SLEEPING; + st->mstate = SLEEPING; Serial.println("cannot heat, going to sleep"); } - } else if (state == HOT) { + } else if (st->mstate == HOT) { if (hot) { - state = BREWING; - brewing_t0 = millis(); + st->mstate = BREWING; + st->brewing_t0 = millis(); Serial.println("brewing"); - } else if (millis() - hot_t0 > max_idle_time) { - state = SLEEPING; + } else if (millis() - st->hot_t0 > max_idle_time) { + st->mstate = SLEEPING; Serial.println("idle timeout, going to sleep"); } - } else if (state == BREWING) { - if (millis() - brewing_t0 > brewing_time) { - state = COOLING; - cooling_t0 = millis(); + } else if (st->mstate == BREWING) { + if (millis() - st->brewing_t0 > brewing_time) { + st->mstate = COOLING; + st->cooling_t0 = millis(); Serial.println("cooling"); } - } else if (state == COOLING) { + } else if (st->mstate == COOLING) { /* TODO: Wait a bit and go back to heating */ - if (millis() - cooling_t0 > cooling_time) { - state = HEATING; - heating_t0 = millis(); + if (millis() - st->cooling_t0 > cooling_time) { + st->mstate = HEATING; + st->heating_t0 = millis(); Serial.println("heating"); } } } 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 g = 0; - if (state == HEATING || state == COOLING) { + if (st->mstate == HEATING || st->mstate == COOLING) { analogWrite(PIN_LED_RED, r); setled(PIN_LED_GREEN, 0); if (r >= 255) r = 0; else r += 3; - } else if (state == HOT) { + } else if (st->mstate == HOT) { setled(PIN_LED_RED, 0); setled(PIN_LED_GREEN, 1); r = 0; - } else if (state == BREWING) { + } else if (st->mstate == BREWING) { setled(PIN_LED_RED, 0); analogWrite(PIN_LED_GREEN, g); 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 -update_heater() +output_heater(const struct state *st) { - if (state == HEATING || state == HOT || state == BREWING) { - int temp = measure_temp(); - if (temp < TEMP_MIN) + if (st->mstate == HEATING || st->mstate == HOT || st->mstate == BREWING) { + if (st->ntc_T < TEMP_MIN) relay(PIN_HEAT, ON); - else if (temp > TEMP_MAX) + else if (st->ntc_T > TEMP_MAX) relay(PIN_HEAT, OFF); } else { relay(PIN_HEAT, OFF); @@ -258,47 +291,18 @@ update_heater() } void -update_pump() +output_pump(const struct state *st) { - if (state == BREWING) { + if (st->mstate == BREWING) relay(PIN_PUMP, ON); - } else { + else relay(PIN_PUMP, OFF); - } } -void -update_buzz() +void do_output(const struct state *st) { - static unsigned long started = 0; - - 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(); + output_leds(st); + output_heater(st); } void setup() @@ -323,9 +327,9 @@ void setup() void loop() { - inputs(); - progress(); - outputs(); + do_input(&g_in); + do_proc(&g_st, &g_in); + do_output(&g_st); delay(5); }