In questa guida vedremo come creare una macchina da caffè automatizzata con Arduino e C++.
Il circuito è composto da 3 motori che vanno a simulare il frullino, la pompa dell'acqua e la schiuma. Abbiamo 2 led, uno rosso e uno verde che rappresentano lo stato del sistema che riscalda l'acqua, un potenziometro per gestire il livello dell'acqua, un sensore di temperatura per capire quando avviare la preparazione vera e propria del caffè, 6 pulsanti per la scelta della bevanda e un display LCD.
Quando accendiamo la macchinetta il display LCD restituisce un messaggio di benvenuto "Coffee EHF ON".
Utilizzando i pulsanti fisici sulla macchina del caffè si può selezionare che bevanda si desideri preparare. Ogni pulsante è associato a un tipo specifico di caffè (espresso, americano, latte, ecc...).
Il sistema "monitora" il livello dell'acqua attraverso un potenziometro (in realtà dobbiamo impostarlo noi) e se il livello dell'acqua è superiore al 25% è pronta per preparare il caffè.
Quando l'utente preme uno dei pulsanti la macchina inizia la preparazione che è specifica per quel tipo di caffè.
Inizialmente attiva i componenti come il macinino, il riscaldatore, la pompa dell'acqua o il frullino a seconda del tipo di caffè selezionato e durante le fasi viene documentato tutto sul display LCD.
La temperatura viene controllata in maniera costante e se la temperatura supera i 90°C la macchina passa alla fase successiva (quella dell'attivazione pompa).
Completata la preparazione, il display LCD ce lo fa sapere con un messaggio di chiusura: "il nome caffè è pronto" per poi ricominciare il tutto.
Componenti:
- Arduino Uno R3
- Display LCD Basato su PCF8574, 32 LCD 16 x 2 (I2C)
- Rosso LED
- Verde LED
- 100 Ω Resistenza (2)
- Motore CC (3)
- Pulsante (6)
- 250 kΩ Potenziometro
- Sensore di temperatura [TMP36]
Codice:
Iniziamo a scrivere il codice, partiamo dal setup
dove all'inizio vengono configurati i pin per i componenti (riscaldatore, motori, pulsanti), e viene inizializzato il display LCD.
Inizialmente nel loop
avviene la lettura del potenziometro per determinare il livello dell'acqua, se il livello dell'acqua è inferiore al 25% viene visualizzato un messaggio di attesa e in caso contrario la macchina del caffè è pronta per l'uso.
I pulsanti sono associati a ciascun tipo di bevanda, se un pulsante è premuto e non c'è un processo di preparazione in corso (start==false
) viene avviata la preparazione.
Se il livello dell'acqua è sufficiente il programma entra in un corpo (a livello di codice) specifico per la preparazione della bevanda selezionata.
Specifico che ogni processo segue una sequenza di attivazione di componenti (riscaldatore, motori) e gestione del tempo con timer (tim1
, tim2
, tim3
) / controllo della temperatura.
La temperatura ambiente viene misurata e convertita in gradi Celsius, se la temperatura supera i 90°C viene avviata la preparazione sennò la macchinetta aspetta che la temperatura sia adeguata (il led rosso indica che il riscaldatore sta funzionando).
Gli "stati" (st1
, st2
, ecc...) sono variabili esplicitate per evitare l'avvio simultaneo di più processi.
Quando un timer raggiunge zero il processo viene contrassegnato come completato e la macchina è pronta per cominciarne uno nuovo.
Dopo il completamento di un processo gli stati vengono reimpostati a false per permettere una nuova scelta da parte dell'utilizzatore.
La funzione di pulizia attiva solamente il pompaggio dell'acqua senza macinatura del caffè mentre per il latte viene azionato solo il motore che si occupa della schiuma.
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x20, 16, 2);
#define bt_nero 7
#define bt_chiaro 6
#define bt_espresso 5
#define bt_americano 4
#define bt_latte 3
#define bt_pulizia 2
#define voce 12
#define riscaldatore_acqua 13
#define motore_frullino 9
#define motore_pompa_acqua 10
#define motore_macinino 11
int temperatura = 0;
int bt_chiaroread = 0;
int bt_neroread = 0;
int bt_puliziaread = 0;
int bt_americano_read = 0;
int bt_espresso_read = 0;
int bt_latte_read = 0;
bool st1 = false;
bool st2 = false;
bool st3 = false;
bool st4 = false;
bool st5 = false;
bool st6 = false;
bool tem = false;
bool t = false;
bool start = false;
int tim1 = 15;
int tim2 = 20;
int tim3 = 20;
void setup() {
pinMode(voce, OUTPUT);
pinMode(riscaldatore_acqua, OUTPUT);
pinMode(motore_frullino, OUTPUT);
pinMode(motore_pompa_acqua, OUTPUT);
pinMode(motore_macinino, OUTPUT);
pinMode(bt_pulizia, INPUT_PULLUP);
pinMode(bt_latte, INPUT_PULLUP);
pinMode(bt_americano, INPUT_PULLUP);
pinMode(bt_espresso, INPUT_PULLUP);
pinMode(bt_chiaro, INPUT_PULLUP);
pinMode(bt_nero, INPUT_PULLUP);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(" EHF Coffee ");
lcd.setCursor(0, 1);
lcd.print(" ON ");
digitalWrite(voce, HIGH);
delay(1000);
lcd.clear();
}
void loop() {
int potenziometro = analogRead(A0);
int percentuale = map(potenziometro, 0, 1023, 0, 100);
bt_neroread = digitalRead(bt_nero);
bt_chiaroread = digitalRead(bt_chiaro);
bt_espresso_read = digitalRead(bt_espresso);
bt_americano_read = digitalRead(bt_americano);
bt_puliziaread = digitalRead(bt_pulizia);
bt_latte_read = digitalRead(bt_latte);
lcd.setCursor(0, 0);
lcd.print("Livello Acqua: ");
lcd.print(percentuale);
lcd.print("% ");
if (percentuale >= 25) {
delay(10);
lcd.setCursor(0, 1);
lcd.print(" ");
if (bt_neroread == LOW && !st1) {
tim1 = 10;
tim2 = 20;
st1 = true;
start = true;
}
while (st1) {
blackcoffee();
}
if (bt_chiaroread == LOW && !st2) {
tim1 = 7;
tim2 = 20;
st2 = true;
start = true;
}
while (st2) {
lightcoffee();
}
if (bt_espresso_read == LOW && !st3) {
tim1 = 15;
tim2 = 5;
st3 = true;
start = true;
}
while (st3) {
espresso();
}
if (bt_americano_read == LOW && !st4) {
tim1 = 15;
tim2 = 20;
st4 = true;
start = true;
}
while (st4) {
americano();
}
if (bt_puliziaread == LOW && !st5) {
tim2 = 5;
st5 = true;
start = true;
}
while (st5) {
cleaning();
}
if (bt_latte_read == LOW && !st6) {
tim1 = 15;
tim2 = 15;
tim3 = 30;
st6 = true;
start = true;
}
while (st6) {
latte();
}
} else {
lcd.setCursor(0, 1);
lcd.print("Attendi... ");
}
}
bool temp() {
temperatura = (analogRead(A1) * (5.0 / 1023) - .5) / .01;
if (temperatura > 90) {
tem = true;
} else {
tem = false;
}
return tem;
}
void blackcoffee() {
lcd.setCursor(0, 0);
lcd.print(" caffe Nero ");
digitalWrite(riscaldatore_acqua, HIGH);
delay(1000);
digitalWrite(motore_macinino, HIGH);
while (tim1 != 0) {
if (tim1 < 0) {
tim1 = 0;
}
lcd.setCursor(0, 0);
lcd.print("Macinino ON");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim1) + " Secondi ");
tim1--;
delay(1000);
}
digitalWrite(motore_macinino, LOW);
lcd.setCursor(0, 0);
lcd.print(" Chicchi sono ");
lcd.setCursor(0, 1);
lcd.print(" Macinati ");
delay(1000);
t = temp();
while (start) {
while (t && st1) {
t = temp();
lcd.clear();
while (tim2 != 0) {
if (tim2 < 0) {
tim2 = 0;
lcd.clear();
}
lcd.setCursor(0, 0);
lcd.print("Attiva Pompa ");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim2) + " Secondi ");
tim2--;
digitalWrite(motore_pompa_acqua, HIGH);
delay(1000);
}
lcd.print("Disattiva Pompa ");
delay(1000);
digitalWrite(motore_pompa_acqua, LOW);
delay(1000);
digitalWrite(riscaldatore_acqua, LOW);
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" caffe Nero ");
lcd.setCursor(0, 1);
lcd.print(" Pronto ");
delay(1000);
st1 = false;
start = false;
break;
}
while (!t) {
t = temp();
lcd.setCursor(0, 0);
lcd.print("Temperatura:");
lcd.print(temperatura);
lcd.print("°C ");
lcd.setCursor(0, 1);
lcd.print(" Attendi... ");
}
}
}
void lightcoffee() {
lcd.setCursor(0, 0);
lcd.print(" caffe Chiaro ");
digitalWrite(riscaldatore_acqua, HIGH);
delay(1000);
digitalWrite(motore_macinino, HIGH);
while (tim1 != 0) {
if (tim1 < 0) {
tim1 = 0;
}
lcd.setCursor(0, 0);
lcd.print("Macinino ON");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim1) + " Secondi ");
tim1--;
delay(1000);
}
digitalWrite(motore_macinino, LOW);
lcd.setCursor(0, 0);
lcd.print(" Chicchi sono ");
lcd.setCursor(0, 1);
lcd.print(" Macinati ");
delay(1000);
t = temp();
while (start) {
while (t && st2) {
t = temp();
lcd.clear();
digitalWrite(motore_pompa_acqua, HIGH);
while (tim2 != 0) {
if (tim2 < 0) {
tim2 = 0;
lcd.clear();
}
lcd.setCursor(0, 0);
lcd.print("Attiva Pompa ");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim2) + " Secondi ");
tim2--;
delay(1000);
}
lcd.setCursor(0, 0);
lcd.print("Disattiva Pompa ");
delay(1000);
digitalWrite(motore_pompa_acqua, LOW);
delay(1000);
digitalWrite(riscaldatore_acqua, LOW);
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" caffe Chiaro ");
lcd.setCursor(0, 1);
lcd.print(" Pronto ");
delay(1000);
st2 = false;
start = false;
break;
}
while (!t) {
t = temp();
lcd.setCursor(0, 0);
lcd.print("Temperatura:");
lcd.print(temperatura);
lcd.print("°C ");
lcd.setCursor(0, 1);
lcd.print(" Attendi... ");
}
}
}
void espresso() {
lcd.setCursor(0, 0);
lcd.print(" Espresso ");
digitalWrite(riscaldatore_acqua, HIGH);
delay(1000);
while (tim1 != 0) {
if (tim1 < 0) {
tim1 = 0;
}
lcd.setCursor(0, 0);
lcd.print("Macinino ON");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim1) + " Secondi ");
tim1--;
delay(1000);
}
digitalWrite(motore_macinino, LOW);
lcd.setCursor(0, 0);
lcd.print(" Chicchi sono ");
lcd.setCursor(0, 1);
lcd.print(" Macinati ");
delay(1000);
t = temp();
while (start) {
while (t && st3) {
t = temp();
lcd.clear();
while (tim2 != 0) {
if (tim2 < 0) {
tim2 = 0;
lcd.clear();
}
lcd.setCursor(0, 0);
lcd.print("Attiva Pompa ");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim2) + " Secondi ");
tim2--;
digitalWrite(motore_pompa_acqua, HIGH);
delay(1000);
}
lcd.setCursor(0, 0);
lcd.print("Disattiva Pompa ");
delay(1000);
digitalWrite(motore_pompa_acqua, LOW);
delay(1000);
digitalWrite(riscaldatore_acqua, LOW);
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" Espresso ");
lcd.setCursor(0, 1);
lcd.print(" Pronto ");
delay(1000);
st3 = false;
start = false;
break;
}
while (!t) {
t = temp();
lcd.setCursor(0, 0);
lcd.print("Temperatura:");
lcd.print(temperatura);
lcd.print("°C ");
lcd.setCursor(0, 1);
lcd.print(" Attendi... ");
}
}
}
void americano() {
lcd.setCursor(0, 0);
lcd.print(" Americano ");
digitalWrite(riscaldatore_acqua, HIGH);
delay(1000);
digitalWrite(motore_macinino, HIGH);
while (tim1 != 0) {
if (tim1 < 0) {
tim1 = 0;
}
lcd.setCursor(0, 0);
lcd.print("Macinino ON");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim1) + " Secondi ");
tim1--;
delay(1000);
}
digitalWrite(motore_macinino, LOW);
lcd.setCursor(0, 0);
lcd.print(" Chicchi sono ");
lcd.setCursor(0, 1);
lcd.print(" Macinati ");
delay(1000);
t = temp();
while (start) {
while (t && st4) {
t = temp();
lcd.clear();
while (tim2 != 0) {
if (tim2 < 0) {
tim2 = 0;
lcd.clear();
}
lcd.setCursor(0, 0);
lcd.print("Attiva Pompa ");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim2) + " Secondi ");
tim2--;
digitalWrite(motore_pompa_acqua, HIGH);
delay(1000);
}
lcd.setCursor(0, 0);
lcd.print("Disattiva Pompa ");
delay(1000);
digitalWrite(motore_pompa_acqua, LOW);
delay(1000);
digitalWrite(riscaldatore_acqua, LOW);
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" Americano ");
lcd.setCursor(0, 1);
lcd.print(" Pronto ");
delay(1000);
st4 = false;
start = false;
break;
}
while (!t) {
t = temp();
lcd.setCursor(0, 0);
lcd.print("Temperatura:");
lcd.print(temperatura);
lcd.print("°C ");
lcd.setCursor(0, 1);
lcd.print(" Attendi... ");
}
}
}
void cleaning() {
lcd.setCursor(0, 0);
lcd.print(" Pulizia ");
digitalWrite(motore_pompa_acqua, HIGH);
while (tim2 != 0) {
if (tim2 < 0) {
tim2 = 0;
lcd.clear();
}
lcd.setCursor(0, 0);
lcd.print("Attiva Pompa ");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim2) + " Secondi ");
tim2--;
delay(1000);
}
lcd.setCursor(0, 0);
lcd.print("Disattiva Pompa ");
delay(1000);
digitalWrite(motore_pompa_acqua, LOW);
delay(1000);
digitalWrite(riscaldatore_acqua, LOW);
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" Pulizia ");
lcd.setCursor(0, 1);
lcd.print(" Completata ");
delay(1000);
st5 = false;
start = false;
}
void latte() {
lcd.setCursor(0, 0);
lcd.print(" Latte ");
digitalWrite(riscaldatore_acqua, HIGH);
delay(1000);
digitalWrite(motore_frullino, HIGH);
while (tim1 != 0) {
if (tim1 < 0) {
tim1 = 0;
}
lcd.setCursor(0, 0);
lcd.print("Frullino ON");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim1) + " Secondi ");
tim1--;
delay(1000);
}
digitalWrite(motore_frullino, LOW);
lcd.setCursor(0, 0);
lcd.print(" Latte è ");
lcd.setCursor(0, 1);
lcd.print(" Preparato ");
delay(1000);
t = temp();
while (start) {
while (t && st6) {
t = temp();
lcd.clear();
while (tim2 != 0) {
if (tim2 < 0) {
tim2 = 0;
lcd.clear();
}
lcd.setCursor(0, 0);
lcd.print("Attiva Pompa ");
lcd.setCursor(0, 1);
lcd.print("Per " + String(tim2) + " Secondi ");
tim2--;
digitalWrite(motore_pompa_acqua, HIGH);
delay(1000);
}
lcd.setCursor(0, 0);
lcd.print("Disattiva Pompa ");
delay(1000);
digitalWrite(motore_pompa_acqua, LOW);
delay(1000);
digitalWrite(riscaldatore_acqua, LOW);
delay(1000);
lcd.setCursor(0, 0);
lcd.print(" Latte ");
lcd.setCursor(0, 1);
lcd.print(" Pronto ");
delay(1000);
st6 = false;
start = false;
break;
}
while (!t) {
t = temp();
lcd.setCursor(0, 0);
lcd.print("Temperatura:");
lcd.print(temperatura);
lcd.print("°C ");
lcd.setCursor(0, 1);
lcd.print(" Attendi... ");
}
}
}
Schema elettrico:
Link utili: