Led autonomo

Salve a tutti,
non riesco a fare una cosa, probabilmente sbaglio tutto:
vorrei rendere autonomo un led, mi spiego,
la prima volta che viene premuto un pulsante il led si accende e si conta quanto il pulsante rimane premuto,
dalla seconda volta in poi il pulsante viene premuto e rilasciato subito ed il led deve rimanere acceso per il tempo contato in precedenza, ho usato Bool ma probabilmente non ci capisco una mazza,
in breve:

int button = 2;
int led = 4;
int buttonstate = 0;
unsigned long starttempo;
unsigned long tempocontato;
bool primavolta;

void setup() {

 pinMode (buttonstate, INPUT);
 pinMode (led, OUTPUT);
 primavolta = true;

}

void loop() {

 buttonstate = digitalRead(button);

 if (buttonstate == HIGH) {

   if (primavolta) {

     digitalWrite (led, HIGH);
     starttempo = millis ();
     if (buttonstate == LOW) {

       tempocontato = (millis() - starttempo);
       digitalWrite (led, LOW);
       primavolta = false;

     }

   } else {
     digitalWrite (led, HIGH);
     delay (tempocontato);
     digitalWrite (led, LOW);
   }

 }

}

mi aiutate?
grazie

>SimoneBez: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post qui sopra (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.

Guglielmo

a ok! scusami...
comunque nel mentre l'ho modificato,
ora è già meglio, ma sembra che ogni volta aggiunga il tempo di pressione del pulsante:

int button = 2;
int led = 4;
int buttonstate = 0;
unsigned long starttempo;
unsigned long tempocontato;
bool primavolta;

void setup() {
 
  pinMode (buttonstate, INPUT);
  pinMode (led, OUTPUT);
  primavolta = true;
}

void loop() {
  buttonstate = digitalRead(button);

  if (buttonstate == HIGH) {

    if (primavolta) {
      digitalWrite (led, HIGH);
      starttempo = millis ();
      primavolta = false;

    } else {
       digitalWrite (led, HIGH);
       delay (tempocontato);
       digitalWrite (led, LOW);      
    }
  
  } else {
    digitalWrite (led, LOW);
    tempocontato = (millis() - starttempo);    
  }

}

Io vedo, prevedo e stravedo, come un noto frate
Se non metti un buon debounce avrai grosse delusioni

gia... e poi
nel primo else (quando non sei nel ciclo primavolta ma il pulsante è ancora premuto) usi un delay che non è ancora stato impostato quindi il led si spegne dopo un tempo zero

p.s.
hai riscritto un nuovo post ma devi modificare il tuo primo post e aggiungere i tag code...

>SimoneBez: ... sto sempre attendedo che tu sistemi il tuo primo post seguendo quanto ti ho scritto nel mio post#1 (... dove era chiaramente indicato che NON dovevi scrivere un nuovo post, ma editare quello esistente). Grazie.

Guglielmo

Patrick_M:
gia... e poi
nel primo else (quando non sei nel ciclo primavolta ma il pulsante è ancora premuto) usi un delay che non è ancora stato impostato quindi il led si spegne dopo un tempo zero

p.s.
hai riscritto un nuovo post ma devi modificare il tuo primo post e aggiungere i tag code...

In realtà (l'ho provato) rimane acceso, solo che ogni volta dopo la prima, il led rimane acceso incrementando il tempo autonomamente, in apparenza aggiungendo sempre lo stesso tempocontato...

[/quote

Standardoil:
Io vedo, prevedo e stravedo, come un noto frate
Se non metti un buon debounce avrai grosse delusioni

Già, infatti è proprio lì che sbaglio... Suggerimenti?

Sì,
per cominciare vedi un de-bouce hardware, cerca se trovi il pdf di "arduino basic connection" oppure in alternativa cerca sul santo
ti consiglio debounce HW per due ragioni

  1. è sempre meglio che SW
  2. se già ti incastri adesso sul SW non è che dovendoci fare "anche" il de-bounce sia più semplice...

Ad esempio un condensatore da 1uF con 47 ohm in serie, tra il pin del pulsante e massa.
Se il pulsante non è particolarmente delicato, puoi omettere la resistenza.

SimoneBez:
Già, infatti è proprio lì che sbaglio... Suggerimenti?

Detto che come già ti è stato segnalato il debounce (molto meglio se hardware in generale ma in questo caso anche per non crearti ancora più problemi lato software) è necessario al corretto funzionamento il tuo errore non è li.
Il suggerimento è questo, per mantenere la struttura del codice che hai fatto, devi usare un altra variabile booleana per sapere se devi memorizzare starttempo oppure no e non devi mettere a false la variabile primavolta in quel punto, il perché lo lascio dedurre a te altrimenti ti aiuto troppo :slight_smile:

È anche necessaria, ancor più dell'anti rimbalzo, una resistenza di pull down o di pull up. Adottando una logica diretta, come viene spontaneo fare, devi mettere una resistenza verso massa; se, invece, adotti la logica negata, puoi usare le resistenze di pull up interne, scrivendo:
pinMode(buttonstate, INPUT_PULLUP);

Versione bloccante, non completa, solo come ispirazione

if (digitalRead(button)){
   If (tempocontato){
      DigitalWrite(led,1);
      Delay (tempocontato);
      DigitalWrite(led,0);
   }
   else{
      Unsigned long int localtime=Millis();
      DigitalWrite(led,1);
      While (digitalRead(button));
      Tempocontato = Millis()-localtime;
      DigitalWrite (led,0)
   }
}

metti a posto minuscole e cose del genere che è scritto da furbofono

EDIT
questo post è (anche) una parziale risposta a fabpolli, che proponeva di mantenere la struttura precedente
Secondo me è un errore, cavalli così malati vanno abbattuti. E si riparte da capo evitando gli errori passati
Anche questa gigantesca rottura di gabbasisi di leggere un pulsante in una variabile usata una sola volta per un test...
Ma (come direbbe il mio amico Salvo) dadovemmincchiavvviene ?
chi glielo ha insegnato? I sette nani?
Chi è stato il primo che la ha usata? Che merita di mangiare travasandosi la minestra dal piatto al bicchiere e usando la forchetta...
Ebbasta. Che imparino a ragionare "Lean'
Tutti che parlano di ste strxxate. Ma nessuno che lo FA sul serio...

Grazie a tutti per i consigli, apprezzo anche il "te lo dico ma non tutto così impari", mi aspettavo proprio questo da questo forum, ci lavoro e poi vi faccio sapere.

Standardoil:
Versione bloccante, non completa, solo come ispirazione...
...scritto da furbofono

della serie digitalRead() istruzione comune, DigitalWrite() istruzione propria :wink:
scusa, non ho resistito. :stuck_out_tongue:

Standardoil:
EDIT
questo post è (anche) una parziale risposta a fabpolli, che proponeva di mantenere la struttura precedente
Secondo me è un errore, cavalli così malati vanno abbattuti.

Fornire il codice completo funzionante non lo ritengo molto istruttivo, il 90% degli utenti copie e incolla ok, capito quasi zero. Facendogli correggere a poco a poco il loro codice lo ritengo più istruttivo che non buttare giù il codice funzionante, ci metterei 30 secondi a farlo e invece, spesso, impegno svariate ore del mio tempo per cercare di portare gli utenti ad arrivarci da soli, poi sono punti di vista e non li discuto

Giusto, ma il mio codice non è ne completo ne funzionante, grazie per il complimento: significa che i miei spunti sono fatti talmente bene che sembrano programmi "veri"
Non lo sono
Qualcosa lo "dimentico"sempre...
Alle volte anche involontariamente..
Se lo OP guarda, capisce e sa mettere a posto, bene
Sennò se ne traggono conclusioni

E aggiungo
Se si dà uno sguardo al mio programma e a quello originale si vede che io ho cambiato una sola cosa importante.
Per il resto e tutta roba dello OP (a parte dettagli)
Quindi non è che ho suggerito molto...

Ciao a tutti, ho potuto lavorarci poco ma alla fine sono arrivato a qualcosa.
Funziona benone e sono contento. Grazie a tutti dell'aiuto, specialmente a Standardoil che mi ha indirizzato a dovere.

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

const int button = 2;
const int led = 4;
int buttonstate;
unsigned long int starttempo;
unsigned long int tempocontato;
bool primavolta;

void setup() {
  lcd.begin (16, 2);
  pinMode (buttonstate, INPUT);
  pinMode (led, OUTPUT);
  primavolta = true;
}

void loop() {
  buttonstate = digitalRead(button);
  
    if (primavolta) {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("PRIMA VOLTA");
      lcd.setCursor(0,1);
      lcd.print("ATTESO INPUT");
      if (buttonstate ==  HIGH) {
        lcd.setCursor(0,1);
        lcd.print("PULSANE PREMUTO");      
      digitalWrite (led, HIGH);
      starttempo = millis ();
       while (buttonstate == HIGH) {
         tempocontato = millis() - starttempo;
         buttonstate = digitalRead(button); 
       }
       digitalWrite(led, LOW);
       primavolta = false;   
    }
  }else {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("SECONDA VOLTA");
      lcd.setCursor(0,1);
      lcd.print("ATTESO INPUT");
      if (buttonstate == HIGH) {
        lcd.setCursor(0,1);
        lcd.print("PULSANE PREMUTO");
        digitalWrite(led, HIGH);
        delay(tempocontato);
        digitalWrite(led, LOW);    
      }
    }
}

grazie per aver condiviso il tuo risultato
anche perchè hai fatto un lavoro "tuo", solo ispirato ai miei suggerimenti: bravo
il che, en passant (in francese nel testo NDR), ha fugato i dubbi di chi mi aveva indicato che fornire la soluzione era deleterio
come si è dimostrato non ho fornito la soluzione e la cosa non è stata deleteria
buona giornata