Accensione/spegnimento display lcd con 1 pulsante

Ragazzi non ci riesco proprio. Praticamente io all'accensione di arduino ho fatto in modo che il display fosse spento. Alla prima pressione del tasto si accende, facendo cosi partire una serie di scritte fino ad arrivare all'ultima che mi deve restare fissa (non in loop). Dopo di che alla seconda pressione del tasto voglio che si spenga per poi ad un'ulteriore pressione ricominciare il ciclo. Credo sia una cavolata realizzare questa funziona ma non ci riesco proprio. Mi sapreste aiutare?

Posta quello che hai fatto, spiega i collegamenti e le librerie usate.

Sono riuscito a farlo tramite due pulsanti (una cavolata), qui lo sketch.
Le librerie penso si capiscano dalle prime righe. I collegamenti sono quelli di un display i2c e di 2 semplici pulsanti

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int puls = 8;
int puls1 = 7;
int val = 0;
int val1 = 0;
void setup() {
  pinMode(puls, INPUT);
  pinMode(puls1, INPUT);
  lcd.begin(16, 2);
  if (val == 0) {
    lcd.clear();
    lcd.noBacklight();
  }
}
void loop() {
  val = digitalRead(puls);
  val1 = digitalRead(puls1);
  if (val1 == 1) {
    lcd.clear();
    lcd.noBacklight();
  }

  if (val == 1) {
    lcd.backlight();
    lcd.clear();
  lcd.setCursor (0, 0);
  lcd.print(" ALESSIO");
  lcd.setCursor (0, 1);
  lcd.print("1. Progetto");
  delay (4000);
  lcd.clear();
  lcd.setCursor (0, 0);
  lcd.print("Versione 1.0 ");
  lcd.setCursor (0, 1);
  delay(2000);
  lcd.clear();
  lcd.setCursor (0, 0);
  lcd.print("Multipresa");
  lcd.setCursor (0, 1);
  lcd.print("Dom");
  delay(2000);
  }
}

e-Alessio:
Sono riuscito a farlo tramite due pulsanti (una cavolata), qui lo sketch.
Le librerie penso si capiscano dalle prime righe. I collegamenti sono quelli di un display i2c e di 2 semplici pulsanti

#include <Wire.h>

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int puls = 8;
int puls1 = 7;
int val = 0;
int val1 = 0;
void setup() {
 pinMode(puls, INPUT);
 pinMode(puls1, INPUT);
 lcd.begin(16, 2);
 if (val == 0) {
   lcd.clear();
   lcd.noBacklight();
 }
}
void loop() {
 val = digitalRead(puls);
 val1 = digitalRead(puls1);
 if (val1 == 1) {
   lcd.clear();
   lcd.noBacklight();
 }

if (val == 1) {
   lcd.backlight();
   lcd.clear();
 lcd.setCursor (0, 0);
 lcd.print(" ALESSIO");
 lcd.setCursor (0, 1);
 lcd.print(“1. Progetto”);
 delay (4000);
 lcd.clear();
 lcd.setCursor (0, 0);
 lcd.print("Versione 1.0 ");
 lcd.setCursor (0, 1);
 delay(2000);
 lcd.clear();
 lcd.setCursor (0, 0);
 lcd.print(“Multipresa”);
 lcd.setCursor (0, 1);
 lcd.print(“Dom”);
 delay(2000);
 }
}

Sotto il comando if al posto di lcd lcd.backlight() prova a mettere lcd.setBacklight(LOW), poi nel display i contatti dove ci dovrebbe essere scritto LED, devono far contatto tra di loro

Daniele_Cotta1599:
Sotto il comando if al posto di lcd lcd.backlight() prova a mettere lcd.setBacklight(LOW), poi nel display i contatti dove ci dovrebbe essere scritto LED, devono far contatto tra di loro

Questo sketch funziona, ma è con due pulsanti mentre io vorrei far tutto il procedimento con uno solo

Dai, non è difficile. Il tuo problema è che alla pressione del pulsante devi fare due cose diverse (accendere o spegnere) a seconda dello stato attuale del sistema. Ti serve quindi solo un modo per sapere se il display è acceso o spento e il modo pià semplice è di registrati in una variabile quello che hai appena fatto: quando accendi il display la assegni a 1 (tanto per dire, ma qualsiasi valore va bene); quando lo spegni la rimetti a zero. A questo punto nell'if in cui controllo che il pulsante è stato premuto puoi sapere cosa devi fare!

Ciao.

Si lo so che non è difficile ho fatto cose più complesse ma sono bloccato proprio a questa situazione, ti spiego il perchè:
intanto qui lo sketch di come ho pensato fin dall’inizio

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int puls = 8;
int val = 0;
int stato=0;
void setup() {
  pinMode(puls, INPUT);
  lcd.begin(16, 2);
  if (val==0){
  lcd.clear();
  lcd.noBacklight();
  }
}
void loop() {
  val = digitalRead(puls);
  if (val==1) {
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("ciao");
  lcd.setCursor(0, 1);
  lcd.print("ciao1");
  delay(2000);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("ciao2");
  lcd.setCursor(0, 1);
  lcd.print("ciao3");
  delay(2000);
}
}

Praticamente da spento riesco ad accenderlo ma non a spegnerlo dato che, se mettessi nel loop l’if per val=0 per far spegnere il display, non appena mi stampa tutte le scritte si spegne visto che è un pulsante e dopo la pressione si riporta al valore 0 (mentre io voglio che l’ultima scritta rimanga fissa). Non risolvo mettendo un interruttore perchè il valore rimarrebbe fisso a 1 e il ciclo si ripeterebbe all’infinito sorvolando completamente quello che vorrei

Se rileggi con attenzione il mio post precedente dovresti arrivarci. Ti dò ancora qualche suggerimento: Innanzitutto NON devi testare val=0. non ha senso. val è zero se il pulsante NON è premuto ed in quella situazione non devi fare niente. Vedo che hai già una variabile stato che non usi. beh, usala per "ricordarti" se il display è acceso o spento: dentro l'if val==1 se stato=0 allora accendi e metti stato=1, se stato=1 spegni e metti stato=0. Così ti è più chiaro?

ciao

P.S. attenzione al debouncing. Puoi mettere un piccolo delay nel loop; non è elegante ma è semplice e funziona.

Credo si sia capito che sto cercando di imparare e ho capito il tuo discorso; ho provato a tradurlo in questo modo
Grazie mille dell’aiuto

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int puls = 8;
int val;
int stato = 0;
void setup() {
  pinMode(puls, INPUT);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.noBacklight();
  if ((val == 1) && (stato = 1)) {
    lcd.clear();
    lcd.noBacklight();
    stato = 1 - stato;
  }
}
void loop() {
  val = digitalRead(puls);
  if ((val == 1) && (stato = 0)) {
    stato = 1 - stato;
    delay (50);
    lcd.backlight();
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("S);
    lcd.setCursor(0, 1);
    lcd.print("i");
    delay(2000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("c");
    lcd.setCursor(0, 1);
    lcd.print("i");
    delay(2000);
  }
}

Qualche suggerimento:

  • Ripassa la differenza tra = e ==
  • Cerca di dare dei nomi più espliciti alle variabili. Ad esempio potresti chiamare val premuto e stato acceso.
  • Non trovi poi che manchi qualcosa nello sketch? Tipo la parte di spegnimento? Da qualche parte dovrai pur metterla ;).

SukkoPera: - Non trovi poi che manchi qualcosa nello sketch? Tipo la parte di spegnimento? Da qualche parte dovrai pur metterla ;).

Non è proprio che manchi... è nel posto sbagliato. Dai Alessio che ce l'abbiamo quasi fatta! :-)

Ragazzi grazie davvero dell’aiuto, mi state facendo capire che anche se sono cose “semplici” (per me ancora no :D) sono fondamentali.
Non ero a conoscenza della differenza tra gli uguali, correggetemi se sbaglio:
premuto==1 sta per “controllare se è vera questa condizione”;
premuto=1 sta per assegnare valore 1 a questa variabile.
Ho preso i vostri consigli di chiamare le variabili in modo più specifico per rendere la lettura più intuitiva e devo dire che funziona.
Dopo di ciò ho modificato ancora il programma, ora leggendolo capisco che:
-all’accensione di arduino dal setup faccio in modo che il display sia spento;

  • se premo il pulsante diventando 1 e contemporaneamente il display è spento, accendi portando la variabile “acceso” a 1 per utilizzarla nell’istruzione di spegnimento, ed esegui le istruzioni;
  • se premo il pulsante diventando 1 e contemporaneamente il display è acceso, spegnilo e porta “acceso” a 0 per utilizzarla nell’istruzione di accensione.
    Da spento riesco ad accenderlo ma dopo che finisce i print si spegne automaticamente. Dove ho sbagliato?
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
int puls = 8;
int premuto;
int acceso = 0;
void setup() {
  pinMode(puls, INPUT);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.noBacklight();
}
void loop() {
  premuto = digitalRead(puls);
  if ((premuto == 1) && (acceso == 0)) {
    acceso = 1;
    delay (50);
    lcd.backlight();
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("S");
    lcd.setCursor(0, 1);
    lcd.print("i");
    delay(2000);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("c");
    lcd.setCursor(0, 1);
    lcd.print("23");
    delay(2000);
  }
  if ((premuto == 1) && (acceso == 1)) {
    acceso = 0;
    lcd.clear();
    lcd.noBacklight();
  }
}

Ciao, tieni presente che "premuto" è una variabile, non il pulsante... se non la aggiorni conterrà un valore "vecchio".

Poi, come ti avevo suggerito, aggiungi un piccolo delay nel loop (fai 100 millisecondi). Poi prova a toglierlo e vedrai a cosa serve!

pippettiello: Ciao, tieni presente che "premuto" è una variabile, non il pulsante... se non la aggiorni conterrà un valore "vecchio".

Poi, come ti avevo suggerito, aggiungi un piccolo delay nel loop (fai 100 millisecondi). Poi prova a toglierlo e vedrai a cosa serve!

Ci sono riuscito! Inizialmente mi sono soffermato sulla tua prima affermazione: "è una variabile,non il pulsante.... se non la aggiorni conterrà un valore "vecchio"." Io pensavo che alla pressione del pulsante la variabile letta diventa 1 e quando rilascio diventa 0; invece rimane salvata?Scusa se rimane salvata non sarebbe un interruttore? Dopo questa modifica ha funzionato, ma nel primo ciclo invece di spegnersi ricominciava da capo, dopo questo tutti gli altri successivi funzionavano perfettamente (stavo per impazzire pure per questo). Allora ho letto il tuo secondo suggerimento, ho inserito il delay ed ha funzionato! Praticamente senza delay il primo ciclo non facevo in tempo a togliere il dito che ne ripartiva un altro?

e-Alessio:
Io pensavo che alla pressione del pulsante la variabile letta diventa 1 e quando rilascio diventa 0; invece rimane salvata?Scusa se rimane salvata non sarebbe un interruttore?

No, no, premuto è proprio una variabile. Solo che sei tu a doverla assegnare (ad esempio con premuto=digitalRead(puls) ma potresti anche scrivere premuto=47 :slight_smile:
Quello che forse intendi tu è la funzione digitalRead(puls): questa sì che ha sempre in tempo reale lo stato del pulsante.

e-Alessio:
Praticamente senza delay il primo ciclo non facevo in tempo a togliere il dito che ne ripartiva un altro?

Esattamente! Il loop viene eseguito migliaia di volte al secondo (ed anche di più). E poi tieni presente che un pulsante reale (a differenza di quello teorico) non commuta in maniera pulita, ma rimbalza per alcuni millisecondi, ed è come se tu lo premessi a ripetizione… certo se nel loop ci sono dei delay non te ne puoi accorgere.

pippettiello: No, no, premuto è proprio una variabile. Solo che sei tu a doverla assegnare (ad esempio con premuto=digitalRead(puls) ma potresti anche scrivere premuto=47 :-) Quello che forse intendi tu è la funzione digitalRead(puls): questa sì che ha sempre in tempo reale lo stato del pulsante.

Esattamente! Il loop viene eseguito migliaia di volte al secondo (ed anche di più). E poi tieni presente che un pulsante reale (a differenza di quello teorico) non commuta in maniera pulita, ma rimbalza per alcuni millisecondi, ed è come se tu lo premessi a ripetizione... certo se nel loop ci sono dei delay non te ne puoi accorgere.

Beh che dire... grazie mille del tuo aiuto e quello degli altri! Siete stati molto gentili e bravi nell'aiutarmi :) Ora avevo in mente un'altra cosa che a breve scriverò qui in sezione, se hai voglia sarei felice ci dessi un'occhiata ;) Come misurare potenza assorbita con una pinza amperometrica Grazie ancora