Automatizzare macchina del caffè.

Ciao a tutti, sono qui (per l'ennesima volta!! :cold_sweat: ) per chiedervi consiglio su come programmare il tutto.
la mia idea è di utilizzare 4 pulsanti:
il primo è per accendere e spegnere la macchina
gli altri tre per fare un caffè corto medio e lungo
ho una scheda relè (4 relè, a logica INVERSA)per dare il segnale alla scheda originale della macchinetta di avviare l'espresso,
utilizzo un ARDUINO UNO R3
poi in base al pulsante premuto (corto medio o lungo) interrompere l'erogazione del caffè ed aspettare nuovi ordini.

il via al timer lo da un sensore amperometrico collegato in serie alla pompa dell'acqua, diciamo che quando questo sensore mi da un valore maggiore di 250(mA) può partire il conto alla rovescia dopo di che spegnere (relè 1 su stato APERTO) la macchina aspettare ad esempio 2 secondi e rialimentarla (relè 1 su stato CHIUSO) per poi essere nuovamente pronto a ricevere un segnale per un'altro caffè (corto medio o lungo)

e magari dopo 30 secondi di INATTIVITà spegnere la macchina definitivamente.

-il primo relè è per l'accenzione della macchina ( quando voglio interrompere l'erogazione in base alla lunghezza desiderata spengo direttamente l'alimentazione dell'intera macchina)

-il secondo relè ha la funzione di dare il via all'erogazione (basta un piccolo impulso di 1-2 sec per far capire alla scheda della macchina del caffè di avviarsi)

gli altri relè vedrò in futuro come implemenarli

io non so benissimo come far si che il tutto funzioni lato software (un minimo me ne intendo ...)
ho trovato su reference la funzione SwitchCase, non so se potrebbe essere utile al mio lavoro...

pensavo di fare 5 stati differenti:

--stato 1 stand-by : in attesa di selezione

--stato 2 CORTO: chiude il relè 2 per un impulso, dopo 5 sec apre relè 1, lo richiude dopo 2 secondi e torna a stato 1

--stato 3 MEDIO: chiude il relè 2 per un impulso, dopo 10 sec apre relè 1, lo richiude dopo 2 secondi e torna a stato 1

--stato 4 LUNGO: chiude il relè 2 per un impulso, dopo 15 sec apre relè 1, lo richiude dopo 2 secondi e torna a stato 1

--stato 5 SPENTA: relè 1 Aperto, relè 2 Aperto, ed attende solo il tasto 1(accensione e spegnimento macchinetta del caffè, nel caso premuto passa allo stato 1(stand-by)

A monte di tutto gli stati possono AVVIARSI SOLO SE la temperatura della macchina da caffè è giusta (forse qui serve un'altro stato tipo "stato di preparazione"??), e ciò lo deduco da un led sulla scheda originale della macchina da caffè che rimane acceso quando la temperatura è corretta, mentre lampeggia (circa 500ms ON 500ms OFF) quando è fredda o si è raffreddata. ( pensavo di collegare gli estremi del led a dei pin di arduino per leggere quando è acceso o spento... qui potrei avere dei problemi su come farlo... )

(magari posso collegare una fotoresistenza proprio di fronte al led originale (oscurandoli) e leggere il variare della resistenza??)

Io non so tradurre molto bene tutto ciò nel linguaggio di arduino e sono qui per chiedere a voi guru di darmi delle dritte su come fare...

Vi ringrazio già ora per la pazienza che ci mettete a farci imparare cose nuove!!

Frattini :smiley:

Quelli che hai individuato personalmente non li vedo come stati, ma piuttosto come funzioni, e li implementerei come tali. Alla fine dei conti è in realtà addirittura una sola funzione con un parametro variabile.

Al massimo gli stati sono "in riscaldamento", "pronta", "in erogazione", ma non vedo fondamentale gestirli come tali, basta qualche condizione.

Per rilevare la temperatura potresti anche misurare la tensione ai capi del led e, se risulta < 5v potresti anche utilizzare direttamente il positivo del led come segnale da leggere come un input di Arduino. Quando resta HIGH per almeno 1 secondo sei a posto.

Ti direi di provare a buttare giù lo sketch e a postarlo, vediamo poi insieme se c'è qualcosa da sistemare.

SukkoPera:
Quelli che hai individuato personalmente non li vedo come stati, ma piuttosto come funzioni, e li implementerei come tali. Alla fine dei conti è in realtà addirittura una sola funzione con un parametro variabile.

Al massimo gli stati sono "in riscaldamento", "pronta", "in erogazione", ma non vedo fondamentale gestirli come tali, basta qualche condizione.

Per rilevare la temperatura potresti anche misurare la tensione ai capi del led e, se risulta < 5v potresti anche utilizzare direttamente il positivo del led come segnale da leggere come un input di Arduino. Quando resta HIGH per almeno 1 secondo sei a posto.

Ti direi di provare a buttare giù lo sketch e a postarlo, vediamo poi insieme se c'è qualcosa da sistemare.

il problema è che non saprei da dove cominciare sinceramente... hai qualche codice da cui posso prendere spunto?

per la lettura del led se collego un solo pin come posso rilevare una tensione, sono due circuiti separati non hanno la massa in comune...

allogo lo sketch che ho fatto, non saprei come posso migliorarlo... voglio aggiungere un led che si accende all'accensione della macchina ed uno che mi indica in che stato si trova ad esempio facendo un fade in-out mentre attende il comando e lampeggi veloce mentre sta erogando ma non riesco a fare una cosa in multi tasking perché non so usare la funzione millis().

// pin dei pulsanti di controllo
int const pulsOn = 13;
int const pulsCorto = 12;
int const pulsMedio = 11;
int const pulsLungo = 10;
//pin dei relay
int const relayACCEN = 9;
int const relayAVVIO = 8;

//tempi di lavoro in millisecondi
int const corto = 5000;
int const medio = 10000;
int const lungo = 15000;
int tempoLEDon = 0;


void setup() {
  //setto ad input i pin dei pulzanti
  pinMode(pulsOn, INPUT);
  pinMode(pulsCorto, INPUT);
  pinMode(pulsMedio, INPUT);
  pinMode(pulsLungo, INPUT);
  //abilito la resistenza di pull-up per i 4 pulsanti
  digitalWrite(pulsOn, HIGH);
  digitalWrite(pulsCorto, HIGH);
  digitalWrite(pulsMedio, HIGH);
  digitalWrite(pulsLungo, HIGH);
  //setto ad input il pin del fotoresistore
  pinMode(A0, INPUT);
  //setto i relay in OUTPUT
  pinMode(relayACCEN, OUTPUT);
  pinMode(relayAVVIO, OUTPUT);
  //seriale per debug
  Serial.begin(9600);

}

void loop() {
  int fotores = analogRead(A0);
  Serial.println(fotores);
  if (fotores > 1000 && tempoLEDon > 10) {

    if (pulsCorto == LOW) {
      caffecorto(corto);
    }
    if (pulsMedio == LOW) {
      caffemedio(medio);
    }
    if (pulsLungo == LOW) {
      caffelungo(lungo);
    }

  }
  else {
    tempoLEDon++;
  }
}

void caffecorto(int tempoEROG) {
  digitalWrite(relayAVVIO, LOW);
  delay(700);
  digitalWrite(relayAVVIO, HIGH);
  delay(tempoEROG);
  digitalWrite(relayACCEN, HIGH);
  delay(2000);
  digitalWrite(relayACCEN, LOW);

}
void caffemedio(int tempoEROG) {
  digitalWrite(relayAVVIO, LOW);
  delay(700);
  digitalWrite(relayAVVIO, HIGH);
  delay(tempoEROG);
  digitalWrite(relayACCEN, HIGH);
  delay(2000);
  digitalWrite(relayACCEN, LOW);
}
void caffelungo(int tempoEROG) {
  digitalWrite(relayAVVIO, LOW);
  delay(700);
  digitalWrite(relayAVVIO, HIGH);
  delay(tempoEROG);
  digitalWrite(relayACCEN, HIGH);
  delay(2000);
  digitalWrite(relayACCEN, LOW);
}

Beh, non sei lontano dal traguardo, hai provato a farlo girare? Qualche appunto:

  • Per settare i pin come input con i pullup basta fare pinMode (pin, INPUT_PULLUP);
  • Su pulsCorto/ecc... credo dovresti fare una digitalRead() :).
  • tempoLEDon arriverà a 10 in meno di un secondo, come l'hai gestito.
  • delay() prende millisecondi come argomento!

Quanto alla massa comune... beh, non puoi collegarla?

frattomatti:
// pin dei pulsanti di controllo
int const pulsOn = 13;

suggerimento:
const byte pulsOn = 13;

io sono arrivato a questo punto, ancora non l'ho provato perchè lato hardware ho solo abbozzato i collegamenti.

// pin dei pulsanti di controllo
const byte pulsOn = 13;
const byte pulsCorto = 12;
const byte pulsMedio = 11;
const byte pulsLungo = 10;
//pin dei relay
const byte relayACCEN = 9;
const byte relayAVVIO = 8;

//tempi di lavoro in millisecondi
int const corto = 5000;
int const medio = 10000;
int const lungo = 15000;
int tempoLEDon = 0;


void setup() {
  //setto ad input i pin dei pulzanti ed abilito la resistenza di pullup
  pinMode(pulsOn, INPUT_PULLUP);
  pinMode(pulsCorto, INPUT_PULLUP);
  pinMode(pulsMedio, INPUT_PULLUP);
  pinMode(pulsLungo, INPUT_PULLUP);
  //setto ad input il pin del fotoresistore
  pinMode(A0, INPUT);
  //setto i relay in OUTPUT
  pinMode(relayACCEN, OUTPUT);
  pinMode(relayAVVIO, OUTPUT);
  //seriale per debug
  Serial.begin(9600);

}

void loop() {
  // legge la fotoresistenza ed incrementa di 1 ogni millisecondo tempoLEDon solo quando è maggiore di 1000
  int fotores = analogRead(A0);
  Serial.println(fotores);
  if (fotores > 1000) {
    tempoLEDon++;
  }
  else {
    tempoLEDon = 0;
  }
  
  //se tempoLEDon ha raggiunto 2000, ovvero 2 secondi perche delay da 1 ms, può eseguire caffè
  if (tempoLEDon > 2000) {

    if (digitalRead(pulsCorto) == LOW) {
      caffecorto(corto);
    }
    if (digitalRead(pulsMedio) == LOW) {
      caffemedio(medio);
    }
    if (digitalRead(pulsLungo) == LOW) {
      caffelungo(lungo);
    }
  }

  delay(1);
}

void caffecorto(int tempoEROG) {
  digitalWrite(relayAVVIO, LOW);
  delay(700);
  digitalWrite(relayAVVIO, HIGH);
  delay(tempoEROG);
  digitalWrite(relayACCEN, HIGH);
  delay(2000);
  digitalWrite(relayACCEN, LOW);
}

void caffemedio(int tempoEROG) {
  digitalWrite(relayAVVIO, LOW);
  delay(700);
  digitalWrite(relayAVVIO, HIGH);
  delay(tempoEROG);
  digitalWrite(relayACCEN, HIGH);
  delay(2000);
  digitalWrite(relayACCEN, LOW);
}

void caffelungo(int tempoEROG) {
  digitalWrite(relayAVVIO, LOW);
  delay(700);
  digitalWrite(relayAVVIO, HIGH);
  delay(tempoEROG);
  digitalWrite(relayACCEN, HIGH);
  delay(2000);
  digitalWrite(relayACCEN, LOW);
}

ho un problema in questa parte, la macchina è una di quelle automatiche che macina e comprime il caffè senza intervenire. io devo far partire il "delay(tempoEROG)" solo dopo un segnale che prendo con un amperometro (diciamo che mi da un valore che solitamente sta attorno alle 25mA e quando la pompa dell'acqua lavora raggiunge 700mA circa...) (altro problema è che questo segnale è molto ballerino, cioè quando sta in lavoro varia molto velocemente da 0 a 700 circa 20 volte al secondo, credo sia dovuto al fatto che la pompa è a membrana ed ha un assorbimento variabile nel tempo)

Quindi le domande sono due:
1- un modo per far "attendere" il segnale dall'amperometro
2- puo crearmi problemi il fatto che è un segnale non stabile

void caffecorto(int tempoEROG) {
  digitalWrite(relayAVVIO, LOW);
  delay(700);
  digitalWrite(relayAVVIO, HIGH);
  delay(tempoEROG);  <-------
  digitalWrite(relayACCEN, HIGH);
  delay(2000);
  digitalWrite(relayACCEN, LOW);
}

Forse ci sono riuscito che ne pensate??

void caffecorto(int tempoEROG) {
  digitalWrite(relayAVVIO, LOW);
  delay(700);
  digitalWrite(relayAVVIO, HIGH);

  amper = (((4.88758 * analogRead(pinAmper)) - 2495) * 10);
  // debug per amperometro
  Serial.print(amper);
  Serial.print("-mA // letto: ");
  Serial.println(analogRead(pinAmper));

  while (amper < pompON) {
    amper = (((4.88758 * analogRead(pinAmper)) - 2495) * 10);
    // debug per amperometro
    Serial.print(amper);
    Serial.print("-mA // letto: ");
    Serial.println(analogRead(pinAmper));
  }

  delay(tempoEROG);
  digitalWrite(relayACCEN, HIGH);
  delay(2000);
  digitalWrite(relayACCEN, LOW);
}