Sto cercando di accendere e spegnere un motore tramite lo stesso pulsante. L'idea è che il pulsante inverti una variabile booleana attraverso un interrupt. Nel loop ci sarà l'accensione o lo spegnimento a seconda del valore della variabile.
Allego il codice relativo.
Per quanto riguarda l'hardware ho usato Arduino UNO, l'integrato ULN2003, due led con le relative resistenze, un motorino DC di quelli che escono con gli starter kit di Arduino.
Allego a titolo illustrativo un immagine del circuito realizzato tramite tinkercad, dove ho sostituito i transistor darlington dell'integrato utilizzando componenti discreti.
Ho testato motore ed ic e funzionano entrambi correttamente, utilizzandoli anche in altri progetti e pilotando il motore tramite Arduino.
Anche lo sketch che ho allegato funziona correttamente per alimentare carichi non induttivi, quali ad esempio i led di segnalazione.
Quando collego il motore invece ci sono anomalie di vario genere come start & stop continui del motore o comunque risposte diverse da quelle volute. Ho cercato di debuggare inserendo dei Serial.print nel codice e dal risultato sembrerebbe che all'accensione del motore venga richiamato continuamente l'interrupt, come se ci fossero cambiamenti nello stato logico del pin 2.
Ho anche provato a modificare gli argomenti della funzione attachInterrupt, utilizzando le modalità LOW e RISING con gli stessi risultati.
Mi chiedo se c'è bisogno di ulteriori accorgimenti per stabilizzare lo stato logico sul pin 2.
Grazie in anticipo per la pazienza
Grazie per la risposta. Visto che utilizzando solo dei led lo sketch funziona pensavo fosse legato al carico induttivo del motore. Quando utilizzo anche il motore l'ISR viene richiamata di continuo come se sul pin continuasse a scendere e salire la tensione.
Debounce hardware credo di riuscire a farlo con una rete RC o con un multivibratore monostabile (correggetemi se sbaglio) ma per quanto riguarda quello software non mi viene in mente come fare perché non posso utilizzare nè millis() nè delay() all'interno della funzione dell'interrupt. Con delayMicroseconds() forse?
Leggendo sul reference di Arduino in effetti pensavo fossi vincolato ad utilizzarlo solo hardware.
Vista la risposta precedente mi sono documentato per quanto riguarda debounce software di ISR ed ho trovato questo topic.
Devo ancora fare delle prove riguardo quello che suggeriscono, ma sembrerebbe una soluzione valida anche questa.
Questo non è del tutto corretto
È vero che millis() non viene incrementato all'interno della ISR, ma questo non ti impedisce di leggerne il valore per salvarlo in una variabile e poi fare quel che devi con tutta calma nel loop() principale ed implementare anche un debounce software
Ok, infatti nel topic che avevo linkato nella risposta precedente sfruttano questo principio. Riporto una bozza di ISR scritta in quel topic:
void my_interrupt_handler()
{
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// If interrupts come faster than 200ms, assume it's a bounce and ignore
if (interrupt_time - last_interrupt_time > 200)
{
... do your thing
}
last_interrupt_time = interrupt_time;
}
Proverò appena possibile sia quello hardware che software cosi da averne contezza di persona.
Grazie dei pareri e delle risposte, aggiornerò appena fatto.
Rilancio, verificare se dopo il debtime l'ingresso si trova ancora al livello premuto. Così si tagliano fuori anche i disturbi impulsivi, che senza la doppia lettura verrebbero presi per segnali buoni.
Grazie per i consigli finora arrivati sul debounce: ho provato entrambi i tipi, sia software che hardware e funzionano evitando di interpretare i rimbalzi meccanici del pulsante come nuovi impulsi.
Tutto questo funziona però solo con un carico diverso dal motorino DC, ad esempio se provo ad applicarlo per accendere un semplice led.
Aggiungo che la parte hardware ( Arduino, ULN2003 e DC Motor) è funzionante: è stata testata con un semplice sketch che fa il blynk del motore (accensioni intermittenti con periodi nell'ordine del secondo)
Purtroppo nonostante i debounce di vario tipo sembrano esserci variazioni sulla tensione del pin 2 quando alimento un carico induttivo. Questo si evince semplicemente debbugando attraverso il codice. Non riesco a fare misure adatte in quanto non ho un oscilloscopio.
Potreste dirmi se le ipotesi fatte riguardo questo malfunzionamento sono sensate? Nel caso cosa potrei fare per evitare questi disturbi?
Sono lo stesso tipo di disturbi di cui parla @Claudio_FF? Ammetto che l'ultima modifica suggerita non è stata ancora implementata per motivi di tempo. Grazie
È già alimentato senza usare i 5 volt di arduino come nello schema allegato ad inizio topic. Provato sia con alimentatore da laboratorio che con due pile li ion in serie.