Dubbio su interrupts e delay

Salve a tutti, sto lavorando ad un progetto che deve implementare multi threading e mi era venuto qualche dubbio…

  1. se nella void loop ho un delay (ipotizziamo di 10 minuti) e viene generato un Interrupt, quest’ultimo viene eseguito? Cosa succede al delay, viene interrotto o finirà solo dopo i 10 minuti prestabiliti?

  2. cosa succede se prima che una funzione associata ad un Interrupt finisca quest’ultimo viene invocato una seconda volta? Vengono diciamo “messi in coda” o succede casino?

E ora ho un paio di domande riguardanti ai Timer :
3) come prima… Un evento associato ad un timer viene eseguito anche se nella void loop c’è un delay molto lungo, e cosa succede a questo delay?

  1. si possono inserire dei delay all’interno di funzioni associate ad un timer?

Grazie!

1) quando viene generato un'interrupt viene eseguito la parte di codice relativa salvando il punto in cui il programma principale si è interrotto, finita l'esecuzione dell'interrupt il programma prosegue dal punto precedente. Se avviene durante un delay, che per il micro è una funzione come un'altra, il dalay viene momentaneamente interrotto e poi proseguirà. Il tempo finale del delay sara il tempo impostato + il tempo di esecuzione dell'interrupt. Se l'esecuzione dell'interrupt è veloce e il delay molto lungo il tempo è pressoché identico con o senza interrupt. Il delay termina dopo il tempo prestabilito. alla fine è un semplice ciclo for.

2) un secondo interrupt viene messo in coda ed eseguito subito dopo, poi riprende il codice principale. Se è lo stesso interrupt poiché il flag è unico potrebbe essere ignorato poiché già segnalato come attivo. Non succede nessun casino. al massimo ragiona in modo diverso da quello che ci si aspetta.

3) si viene eseguito e il delay si ferma e poi riprende. Se abbastanza lungo non ci si accorge della differenza.

4) si ma non è consigliabile se non per delay molto brevi e funzionali.

Il multithreading su Arduino non esiste. Le azioni vengono eseguite in modo sequenziale molto velocemente da sembrare contemporanee, ma sempre sequenziali sono. Diverso è il discorso di un multiprocessore che può eseguire più istruzione in parallelo contemporaneamente.

grazie 1000!

PaoloP: 4) si ma non è consigliabile se non per delay molto brevi e funzionali.

l'unico delay che ho è un delayMicroseconds(10) (serve per il sensore di distanza) che viene eseguito ogni circa 30ms... secondo te è sufficientemente breve o mi conviene gestirlo meglio coi timer evitando anche questo delay?

PaoloP: Il multithreading su Arduino non esiste. Le azioni vengono eseguite in modo sequenziale molto velocemente da sembrare contemporanee, ma sempre sequenziali sono. Diverso è il discorso di un multiprocessore che può eseguire più istruzione in parallelo contemporaneamente.

si questo mi era chiarissimo :) intendevo anchio multithreading virtuale :)

E’ breve e funzionale. :wink:
Altrimenti non c’è il tempo materiale perché il suono emesso rimbalzi e torni al sensore.
Forse potresti abbassarlo a 8 microsecondi, ma non ne sono sicuro.

Ottimo… In realtà avevo pensato come alternativa di creare un timer che esegue una funzione ogni 10uS, con un contatore che ogni (per esempio) 1000 conteggi (quindi dopo ogni 10ms) attivi il Pin trigger del sensore e al successivo conteggio (il 1001) lo disattivi e resetti il contatore.
In questo modo ho un impulso di 10uS ogni 10mS senza usare nessun delay.
Però ho l’impressione che si occupino più risorse in questo modo che usando un delayMicroseconds (10) all’interno di un timer da 10ms… Che ne pensi? (sembra ingarbugliato ma rileggendolo spero si capisce) XD

Ultimissima cosa, che intendevi prima col dire che l’interrupt potrebbe essere “lo stesso” di prima e viene ignorato? Io ho bisogno che nessun Interrupt venga ignorato, ma al massimo vengano messi in coda se sono molto vicini l’un l’altro…

Il registro degli interrupt è uno solo e ogni interrupt aziona una flag. Se un interrupt si scatena mentre lo stesso interrupt è in esecuzione viene messo in coda, se un terzo viene attivato è ignorato poiche il flag è già attivo. Esempio. Se tu premi un pulsante collegato all'interrupt questo esegue una routine. Se durante la routine premi nuovamente il pulsante la richiesta è messa in coda. Se durante l'esecuzione della prima routine premi per la terza volta la richiesta è ignorata. La routine verrà eseguita solo due volte e non tre. Se tu programmai un timer per un evento ogni 10ms e la routine dura 2 millisecondi non è possibile avere un interrupt doppio all'interno della routine. Se programma un timer ogni 5ms e la routine dura 6ms allora al quinto millisecondo avrai una richiesta di interrupt che è messa in coda. Se programma un timer ogni 2ms e la routine dura 7, al sesto millisecondo avrai una richiesta di interrupt che viene ignorata poiché è la terza consecutiva durante l'esecuzione di un interrupt precedente.

Non sto riuscendo in nessun modo a trovare documentazione a riguardo... Su internet trovo che quando è in corso un Interrupt tutti gli altri vengono ignorati e non che quello successivo viene messo in coda... Dove posso trovare qualcosa che spiega il funzionamento nel dettaglio?

Nel datasheet del micro. L'Arduino UNO usa l'ATmega328P --> http://www.atmel.com/Images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet.pdf

Comunque rileggendolo, pag 13, non è il terzo che viene ignorato, ma già il secondo, ovvero il successivo, se identico. Gli altri interrupt, se diversi, vengono messi in coda ed eseguiti in ordine di priorità. Ma solo uno per tipo. Gli eventuali altri vengono ignorati.

Quindi è importante che la routine associata ad un interrupt duri meno dell'intervallo tra due interrupt, altrimenti lo perdi.