pulsante, comando passo-passo

Sera a tutti

Mi aiutereste in questo dubbio atroce per favore?

ho un led che accendo e spengo da web, anche arduino in base alle decisioni dette dal programma può farlo e infine anche manualmente con un pulsante su una porta input.

in pratica un passo-passo un impulso spegne e un impulso accende, il problema nasce quando premo il pulsante.

Questo capita perchè quando io premo il bottone arduino passerà almeno 10 volte nel void loop quindi uomo-macchina vanno in crisi :slight_smile:

Mi viene spontaneo memorizzare in una variabile lo stato del pulsante fino al suo rilascio, ma non riesco a trovare un percorso logico per un corretto funzionamento
Non posso usare un delay perchè ovviamente ci sono altri 100 controlli in sequenza e la velocità è fondamentale.

boolean pulsMem = false;

void loop()
{

val = digitalRead(BUTTON);

if (val == HIGH )
{
pulsMem = true;
}
else
{
pulsMem = false;
}

if (val == HIGH && ledState == true && pulsMem==true)
{
setLedEnabled(false);
pulsMem=false;
}

if (val == HIGH && ledState == false && pulsMem==true)
{
setLedEnabled(true);
pulsMem=false;
}

// pulsMem=true;

}

riesco a spegnerlo ma non ad accenderlo, cambiando alcune cose riesco ad accenderlo ma non a spegnerlo, in altri casi si incasina e lampeggia, mi sfugge qualcosa, ma non so cosa sono in trip totale :slight_smile:

grazie

Usa 2 variabili che setti al primo giro .

boolean stato1=0;
boolean uscitaLED;
...
loop()
{
....
tasto= val = digitalRead(BUTTON);  
if (stato == 0 && tasto == HIGH && uscitaLED ==0)  // accende il LED
{
delay (5)  // per debounce
uscitaLED =1;
accendi il LED;
stato =1;
}

if (stato == 0 && tasto == HIGH && uscitaLED ==1)  // spegne il LED
{
delay (5)  // per debounce
uscitaLED =0;
spegne il LED;
stato =1;
}

if (stato == 1 && tasto == LOW)  // aspetta che il tasto é stato rilasciato
{
delay (5)  // per debounce
uscitaLED =0;
spegne  il LED;
stato =1;
}

I 5msecondi di ritardo messo nel ciclo servono per il debounce e vengono eseguito solo una volta nel momento di premere il tasto e nel momento di rilascio del tasto. Questo ritardo puó essere acettabile, ma non conoscendo tutto il progrtto non so dirlo.

Ciao Uwe

[RISOLTO]
Grazie UWE, ieri sera ho staccato presto e ti rispondo un po' in ritardo,
Ho provato il tuo esempio, ma mi sono incasinato un po', mentre lo studiavo pensavo "devo trovare il modo saltare i controlli (IF) finchè il pulsante resta premuto" oviamente dopo aver invertito lo stato del led.
E se mettessi un contatore

così ho ottenuto questo

// condensatore ceramico in parallelo d'obbligo altrimenti non funziona
const int ledPin = 40; // pin del relè
#define BUTTON 38 // pin di input dove è collegato il pulsante
long cont; // contatore

void setup()
{
pinMode(BUTTON, INPUT);
pinMode(ledPin, OUTPUT);
}

void loop()
{
if (digitalRead(BUTTON) == HIGH) cont++; else cont=0;

if (digitalRead(ledPin)==LOW && cont == 1) //accendi
{
cont++;
//delay(5); // da usare senza condensatore
digitalWrite(ledPin, HIGH);
}

if (digitalRead(ledPin)==HIGH && cont == 1) //spegni
{
cont++;
//delay(5); // da usare senza condensatore
digitalWrite(ledPin, LOW);
}
}

Spiego per chi volesse utilizzarlo dove in molti impianti ci sono comandi luci con pulsanti in parallelo (non interruttori):

Il contatore: quando premo il cont inzia a sommare +1 al cont precedente che era 0 (0+1=1)
successivamente con cont=1 il programma passa al primo IF se il led è spento lo accende per non fargli eseguire anche l'IF successivo devo rendere cont diverso da 1 sommando un +1 (altrimenti lo spegnerebbe immediatamente)

La variabile cont: in un primo tempo l'ho dichiarata come intera (int cont;) notando però che il led lampeggiava, grande stupore non può essere che la variabile assuma di nuovo 0 e poi 1 col tasto sempre premuto, per cui ho detotto che il contatore in un tempo velocissimo arrivasse alla fine per poi resettarsi (non conosco il limite dell' intero). Così ho pensato il contatore del millis dura ore se non giorni e viene dichiarato come variabile long. Con (long cont;) può restare premuto quanto volete.

Il condensatore : Però non andava ancora bene il pulsante 3 volte su 10 faceca cilecca (qualche volta si accendeva e si spegneva subito) nonostante ci fosse una resistenza di pull-down da 10k, forse il pulsante provoca qualche disturbo che con un delay così basso arduino acchiappa tutto, proviamo un condensatore in parallelo al pulsante (condensatore ceramico 100.000pF codice 104Z) in parallelo al pulsante...... miracolo!! è perfetto!! il condensatore stermina qualsiasi picco di tensione si crea durante l'avvicinamento dei contatti.

Ora proviamo a togliere anche i delay(5), fantastico funziona perfettamente anche senza :slight_smile:

Non volevo delay perchè il programma è molto lungo e controlla decine di ingressi (500 millisec x 20 ingressi = 10 secondi) molto facile che in questo modo alcuni impulsi di input vengano persi.

Ora provo a farlo col tuo sistema uwefed

Ciao