Variazione variabili con tastierino LCD

Buongiorno,
sono un neofita sia dell'elettronica che della programmazione. Ho costruito un dispositivo per la fotografia "water drop". Si tratta di fotografare lo scontro di gocce d'acqua. Il circuito controlla un'elettrovalvola, che rilascia le gocce (dimensione in millisecondi definita dal codice), controlla l'intervallo fra le gocce (sempre in millisecondi), e il ritardo dello scatto della macchina fotografica. Al momento il codice permette, molto semplicemente di cambiare con 2 tasti del "LCD Shield" il delay fra le due gocce (un tasto aumenta e uno diminuisce), e con altri due il delay dello scatto. Vorrei capire come creare un menù per poter cambiare anche gli intervalli di apertura dell'elettrovalvola e poter cambiare così anche le dimensioni delle due gocce.
Pensavo a una cosa tipo: spostare un cursore con i tasti destro e sinistro, e variare il valore in corrispondenza del cursore con i tasti su e giù.
La parte hardware non da problemi, funziona perfettamente ed ho già ottenuto delle belle foto. Il circuito è alimentato da 19,5V, un regolatore di tensione porta il voltaggio a 12V, e questo alimenta sia la scheda Arduino, che l'elettrovalvola. Un pulsante di scatto fa partire la sequenza. e gli impulsi per lo scatto e l'apertura valvola partono dalla scheda regolarmente con i tempi programmati. Per isolare la scheda dalla macchina e dalla valvola ho utilizzato due optoisolatori 4n25, e per l'apertura valvola ho aggiunto un transistor controllato dall'optoisolatore.

Allego una foto scattata con il sincronizzatore e il codice

Ringrazio chiunque mi possa aiutare
Lorenzo

// caratteri SPECIALI
byte heart[8] = {
  B00000,
  B01010,
  B11111,
  B11111,
  B11111,
  B01110,
  B00100,
  B00000
};

byte drop[8] = {
  B00100,
  B00100,
  B01110,
  B01110,
  B11111,
  B11111,
  B11111,
  B01110
};

byte frecciagiu[8] = {
  B00100,
  B00100,
  B00100,
  B10101,
  B11111,
  B01110,
  B01110,
  B00100
};

byte verticale[8] = {
  B01110,
  B01110,
  B01110,
  B01110,
  B01110,
  B01110,
  B01110,
  B01110
};

// definizione PIN arduino
const int Start = 12;
const int Flash = 11;
const int Goccia = 2;

// pulsante di scatto
int saltamacacoState = HIGH;

// ritardi (regolabili da display solamente "intervalloGocce" e "ritardoFlash"
int goccia1 = 50;
int goccia2 = 50;
int intervalloGocce = 80;
int ritardoFlash = 136;


// gestione del display con tastiera
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define BUTTON A0

// valori delle resistenze tasti del display
int SELECT[]  =  {720, 800};
int LEFT[]    =  {480, 520};
int RIGHT[]   =  {0, 100};
int UP[]      =  {120, 280};
int DOWN[]    =  {300, 350};

void setup() {

  // creazione dei caratteri SPECIALI
  lcd.createChar(0, heart);
  lcd.createChar(1, drop);
  lcd.createChar(2, frecciagiu);
  lcd.createChar(3, verticale);

  // inizializzazione display
  lcd.begin(16, 2);

  // inizializzazione dei PIN arduino
  pinMode(Flash, OUTPUT);
  pinMode(Goccia, OUTPUT);
  pinMode(Start, INPUT_PULLUP);
}

void loop() {
  int button (analogRead(BUTTON)); // interroga la tastiera e varia i parametri a seconda del tasto premuto
  analogRead(BUTTON); {
    if ( LEFT[0] <= button && button <= LEFT[1] ) {
      intervalloGocce = intervalloGocce - 1;
    }
    if ( RIGHT[0] <= button && button <= RIGHT[1] ) {
      intervalloGocce = intervalloGocce + 1;
    }
    if ( UP[0] <= button && button <= UP[1] ) {
      ritardoFlash = ritardoFlash + 1;
    }
    if ( DOWN[0] <= button && button <= DOWN[1] ) {
      ritardoFlash = ritardoFlash - 1;
    }




    // quando si preme il pulsante "SALTAMACACO" che è il controllo di inizio della sequenza
    saltamacacoState = digitalRead(Start);
    if (saltamacacoState == LOW) {

      delay(1000); // aspetta 1 secondo
      digitalWrite(Goccia, HIGH); // apre il solenoide 1
      delay(goccia1); //tiene aperto per tempo "goccia1" per la prima goccia
      digitalWrite(Goccia, LOW); //chiude il solenoide 1
      delay(intervalloGocce); //aspetta il tempo "intervalloGocce" prima di rilasciare la seconda goccia
      digitalWrite(Goccia, HIGH); // apre il solenoide 1
      delay(goccia2); //tiene aperto per tempo "goccia2" per la seconda goccia
      digitalWrite(Goccia, LOW); //chiude il solenoide 1

      delay(ritardoFlash); //aspetta il tempo "ritardoFlash" prima di scattare la foto

      digitalWrite(Flash, HIGH); //fa scattare la macchina
      delay(500); //tempo necessario perchè la macchina scatti
      digitalWrite(Flash, LOW); // interrompe il cortocircuito sullo scatto

      delay(3000);
    } //pausa per evitare falsi contatti e triggers
    else {
      digitalWrite(Flash, LOW);
      digitalWrite(Goccia, LOW);




      // scrive a monitor alternativamente: l'introduzione e i valori dei parametri impostati
      // ogni refresh di un secondo aggiorna i valori se vengono modificati dal VOID precedente
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("PECOS Dripper");
      lcd.setCursor(14, 0);
      lcd.write(byte(1));
      lcd.setCursor(15, 0);
      lcd.write(byte(1));
      lcd.setCursor(0, 1);
      lcd.print("Valori impostati");
      delay(1000);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("G1");
      lcd.setCursor(3, 0);
      lcd.print("G1-G2");
      lcd.setCursor(9, 0);
      lcd.print("G2");
      lcd.setCursor(12, 0);
      lcd.print("Foto");
      lcd.setCursor(2, 0);
      lcd.write(byte(3));
      lcd.setCursor(8, 0);
      lcd.write(byte(3));
      lcd.setCursor(11, 0);
      lcd.write(byte(3));
      lcd.setCursor(2, 1);
      lcd.write(byte(3));
      lcd.setCursor(8, 1);
      lcd.write(byte(3));
      lcd.setCursor(11, 1);
      lcd.write(byte(3));
      lcd.setCursor(0, 1);
      lcd.print(goccia1);
      lcd.setCursor(3, 1);
      lcd.print(intervalloGocce);
      lcd.setCursor(9, 1);
      lcd.print(goccia2);
      lcd.setCursor(12, 1);
      lcd.print(ritardoFlash);
      delay(1000);
    }

  }

}

Macchina_SCATTA_parametri_CAMBIANO_prova_GOCCIA.ino (4.44 KB)

Buongiorno,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del nostro regolamento, ti chiedo cortesemente di presentarti QUI (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con MOLTA attenzione il su citato REGOLAMENTO ... Grazie. :slight_smile:

Subito dopo esserti presentato aggiungi alcuni dettagli sull'lcd usato per capire di che prodotto stiamo parlando per capire quali solo le caratteristiche dell'lcd in questione (Es. numero di pulsanti, riche/colonne, ecc.)

Come suggerito aggiungo informazioni sul "LCD Shield". Si tratta di un display LCD tipo IORobot, 16x2, con sei pulsanti (Select, destra, sinistra su, giù e Reset). E' predisposto per essere collegato direttamente alla scheda Arduino UNO, ma nel mio caso ho utilizzato un Arduino NANO, collegandolo agli stessi Pin. Deve essere collegato al Pin A0 della scheda per poter essere letto correttamente, alla pressione di ogni pulsante corrisponde un diverso valore di resistenza, quindi deve essere descritto nel codice quali sono i valori corrispondenti ai diversi pulsanti. E' presente un potenziometro per regolare l'intensità luminosa del display.

ecco il link:

Ciao, il codice che hai postato è quello attualmente caricato sulla nano? Perché questa parte

int button (analogRead(BUTTON)); // interroga la tastiera e varia i parametri a seconda del tasto premuto
  analogRead(BUTTON);

per come è scritta non dovrebbe funzionare, nel senso che non dovresti riuscire a cambiare i parametri in quando manca l'assegnazione alla variabile button del valore ritornato dalla analogRead

int button = analogRead(BUTTON); // interroga la tastiera e varia i parametri a seconda del tasto premuto

e la seconda lettura (non cambiando mai il pin di lettura) non serve.

Ti posso consigliare un post che ho aperto qualche settimana fa e che aveva lo stesso soggetto: ho ricevuto diverse soluzioni valide.
Nel tuo caso i tasti sono analogici come nel mio caso quindi basta adattare i suggerimenti.
il post è QUESTO.

GattoRum:
Come suggerito aggiungo informazioni sul "LCD Shield". Si tratta di un display LCD tipo IORobot, 16x2, con sei pulsanti ...

Guarda, in generale, quando indichi un componente, metti il link al pordotto così ci aiuti a capire ESATTAMENTE quale è (visto che di LCD fatti in quel modo ne esistono parecchi).

Guglielmo

Oltre alla tua idea di visualizzare contemporaneamnete i quattro parametri e passare dall'uno all'altro per poi modificarne il valore esiste un'altra strada, ovvero creare N "pagine" che visualizzeranno di volta in volta un solo valore per impostaro e una sempre visibile (quando non si è in modalità di "modifica parametri)" che mostri gli attuali parametri di funzionamento. Sono entrambe mediamete semplici ed ognina di esse ha le sue "criticità" implementative.
Adesso prima di procedere oltre sta a te dichiarare qual'è l'idea che preferisci come punto di partenza, essendo (cito la tua presentazione) neofita per quanto riguarda la programmazione da studiare ne avrai e dovrai avere anche una buona dose di pazienza per imparare nozioni nuove ma con tempo e voglia il tuo progetto è sicuramente realizzabile!

@fabpolli

la definizione dei valori relativi ai tasti è poco prima nel codice:

// gestione del display con tastiera
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define BUTTON A0

// valori delle resistenze tasti del display
int SELECT[]  =  {720, 800};
int LEFT[]    =  {480, 520};
int RIGHT[]   =  {0, 100};
int UP[]      =  {120, 280};
int DOWN[]    =  {300, 350};

Comunque ti confermo che è la versione caricata e funziona.

>GattoRum: in conformità al regolamento, punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie. :slight_smile:

Guglielmo

fabpolli:
Oltre alla tua idea di visualizzare contemporaneamnete i quattro parametri e passare dall'uno all'altro per poi modificarne il valore esiste un'altra strada, ovvero creare N "pagine" che visualizzeranno di volta in volta un solo valore per impostaro e una sempre visibile (quando non si è in modalità di "modifica parametri)" che mostri gli attuali parametri di funzionamento. Sono entrambe mediamete semplici ed ognina di esse ha le sue "criticità" implementative.
Adesso prima di procedere oltre sta a te dichiarare qual'è l'idea che preferisci come punto di partenza, essendo (cito la tua presentazione) neofita per quanto riguarda la programmazione da studiare ne avrai e dovrai avere anche una buona dose di pazienza per imparare nozioni nuove ma con tempo e voglia il tuo progetto è sicuramente realizzabile!

Questa che suggerisci era la mia idea iniziale, che poi ho temporaneamente accantonato per completare il circuito e testarlo.
Ho seguito quindi la strada più semplice per vedere se riuscivo a ottenere qualche foto buona.
Adesso che ho visto che funziona pensavo di migliorarne la funzionalità aggiungendo anche la possibilità di variare tutti i parametri, e non solo i due delay. Vorrei anche aggiungere la possibilità di una terza ed eventualmente una quarta goccia, quindi i parametri potrebbero diventare 6 o 8 ( i quattro esistenti più dimensione e delay terza goccia e dimensione e delay quarta goccia).
Questo sarebbe fattibile con il sistema che suggerisci, cioè aggiungendo N pagine.
Potrei in un futuro pensare di aggiungere anche più elettrovalvole (con le dovute modifiche hardware), e quindi questo approccio sarebbe certamente il più efficace.
Ripeto avevo temporaneamente accantonato questa soluzione perchè non riuscivo a venirne fuori e volevo testare il sincronizzatore.

Ciao, la definzione dei tasti l'avevo vista, la domanda era volta a conoscere il prodotto per sapere se oltre a quelli definiti ne esistessero altri, tutto li.

GattoRum:
Ripeto avevo temporaneamente accantonato questa soluzione perchè non riuscivo a venirne fuori e volevo testare il sincronizzatore.

Ed è stata anche un'idea buona, adesso sai che va, puoi migliorarlo controllando che tutto continui a funzionare
Tu dici che è caricato e funzionante, bene, mi risulta impossibile leggendo il codice, non potendo provare non insisto anche se credo che definendo int button venga inizializzata a zero e quindi dovrebbe entrare sempre in quest'if

if ( RIGHT[0] <= button && button <= RIGHT[1] )

Comunque venendo alla tua richiesta ti suggerirei di modificare leggermente la strutura del programma in modo tale da suddividere le varie funzionalità in modo chiaro e aperto a pussibili aggiunte future. Ti metto giù un'idea di una possibile implementazione, quando hai modificato il programma e verificato che tutto continui a funzionare si può proseguire con le modifiche, quindi la mia idea da proporti è la seguente:
Definirei una variabile che contenga lo stato attuale del programma (di tipo byte va benissimo) e creerei una serie di possibili stati Es.

#define STATO_ATTESA 0
#define STATO_SCATTAFOTO 1
#define STATO_MODIFICA 2
...ecc

Nel loop la prima cosa da fare è leggere lo stato del pulsante

digitalRead(Start)

Se è stato premuto allora setti la variabile stato a STATO_SCATTAFOTO altrimenti controlli se è stato premuto il pulsante select per entrare nello STATO_MODIFICA
SUbito dopo queste operazioni tramite una serie di if o ancora meglio uno switch (visto che non l'hai usato puoi sfruttare la cosa per apprenderne il funzionamento) che verifichi il valore della variabile stato, se è STATO_SCATTAFOTO fai quello che adesso è dentro l'if

saltamacacoState == LOW

altrimenti se è nello stato STATO_MODIFICA entrerai nella prima pagina che ti consentirà di modificare i vari parametri se sei nello STATO_ATTESA mostrerai i valori attuali.
Intanto prova a fare quanto suggerito, se hai dubbi chiedi, quando hai finito le modifiche e funzionando rimetti il codice che lo verifichiamo assieme e continueremo le necessarie modifiche.

ok, grazie del suggerimento, proverò a vedere cosa riesco a fare.