Lacune di programmazione

Ciao a tutti, sono nuovo del forum e di arduino. Ho nozioni di programmazione dalle scuole superiori e scarse conoscenze elettroniche. Da poco mi sto accingendo con i vari tutorial proprio per ampliare le mie conoscenze in genere.. A proposito di "input" ho finalmente capito il concetto di resistenze pull-up e pull-down; adesso sto studiando il debounce. Ho capito il problema e sto leggendomi le varie soluzioni software che sono state inventante per evitare il "bounce". In pratica il tutto è legato a dei cicli di loop dove all'interno c'è un piccolissimo delay che filtra il rumore del rimbalzo del tasto. Mi chiedevo, ma in un programma "normale" dove ci sono diverse istruzioni come può essere garantito il funzionamento di questa routine in modo tale da leggere l'input proprio nel momento che uno preme un tasto?

Forse mi sono spiegato male e/o forse il problema è più ampio; quello che vorrei esprimere è: se il loop principale del programma è "rallentato" dall'esecuzione di una serie di istruzioni, come può essere garantito ad esempio il monitoraggio di una serie di input e/o l'esecuzione di altre funzioni volte al normale funzionamento del "sistema fisico" al quale arduino è collegato?

Se usi Delay() il programma si ferma. Devi scrivere una porzione di codice che esegua un ciclo nel quale controlla che il tempo trascorso non sia superiore ad un dato valore ed all’interno di quel ciclo eseguire tutte le operazioni che vuoi.

time_exit = millis() + intervallo;
do {
  (codice)
} while (millis() < time_exit);

se il sistema sta eseguendo molte istruzioni che mettono a rischio la lettura di un segnale, come quello di un tasto, o di un segnale molto breve o che richiede precisione, si usano gli interrupt. In pratica, quando un'interrupt viene attivato su uno o più PIN, quando arriva un segnale il codice in esecuzione viene "congelato" e viene eseguito il codice interrupt, che scrivi tu. È buona norma tenere gli interrupt veloci, per vari motivi; quindi non verrà eseguito il codice riguardante il pulsante, ma verrà settata una variabile globale (e volatile) in modo che il loop controlli il valore di questa variabile (e lo azzeri).. Per esempio la comunicazione seriale funziona così. Ogni bit che arriva lancia un'interrupt, il bit viene salvato in un buffer, quando si raggiungono 8 bit (un byte), il byte viene copiato in un altro buffer e il primo buffer svuotato. Il secondo buffer è quello che accedi quando usi la funzione Serial.read(): leggi un byte, che viene cancellato dal buffer dei byte, o -1 se il buffer è vuoto.

Se fai un interrupt con un pulsante devi eliminare via hardware il rimbalzo del pulsante senó viene chiamata li programma di interrupt 3-4 volte ad ogni attivazione di pulsante.

La seriale del Arduino ha una piccola memoria che memprizza i dati che arrivano; non devono essere scaricati subito. La cosa é diversa per le seriali realizzate via software.

Ciao Uwe

leo72:
Se usi Delay() il programma si ferma. Devi scrivere una porzione di codice che esegua un ciclo nel quale controlla che il tempo trascorso non sia superiore ad un dato valore ed all’interno di quel ciclo eseguire tutte le operazioni che vuoi.

time_exit = millis() + intervallo;

do {
  (codice)
} while (millis() < time_exit);

Ho capito, ci studio un attimo. Grazie per ora

Provo a fare un esempio semplificato di cosa vorrei fare solo per capire se il mio è un problema di interrupt ;-)

C'è un loop principale, ammettiamo che in questo loop ci sono 2 funzioni che vengono chiamate, una legge/imposta la temperatura, l'altra funzione gestisce il menù per impostare la temperatura desiderata ecc.. Diciamo che in condizioni normali il menù non è mai richiamato dall'utente, quindi il loop gira liscio e quindi la lettura viene costantemente monitorata alla velocità di millisecondi. Nel momento che uno preme un pulsante e quindi il loop principale entra nella funzione legata alla gestione dei menu, tutto il loop principale si ferma. Quindi fino che l'utente non finisce di smanettare nei menu, il loop non torna mai alla "funzione" di lettura della temperatura.

Questo è il concetto che dicevo. Al di la della soluzione tecnica con Arduino, il mio è proprio un limite di programmazione dato che non ho mai fatto roba del genere ma solo programmini scolastici che generalmente hanno un inizio e una fine. PS: Arduino è multitasking?

arduino non è multitasking. Il problema che hai è ben diverso da quello che avevo capito. la tua funzione menu è loccante, ovvero finché l'utente non finisce di inserire i dati non esegue il loop. Poiché non puoi mettere la parte relativa al menu o al sensore in un processo/therad a parte, devi modificare le tua funzione menu per NON essere loccante. Ciò comporta probabilmente la riscrittura della tua funzione, che non deve più sfruttare loop interni ma il loop principale, oppure dal loop del menu richiamare la funzione relativa alla lettura del sensore.