Sono sicuramente paranoico e me ne scuso, ma ho sempre il dubbio che (e non so per quale motivo) io mi possa perdere dei segnali che arrivano sui pin.
Tempo fa avevo chiesto consigli su come evitare lo stop del programma durante la l'acquisizione della temperatura con sonde DS18B20. Ho risolto mettendo nello sketch la richiesta di calcolo della temperatura, faccio girare il programma normalmente e dopo cinque secondi (ho super abbondato) viene richiesta la temperatura e nuovamente viene richiesto il calcolo della temperatura al sensore.
Al mio arduino ci sto collegando sempre più cose. Oltre ad un conteggio di impulsi (che ovviamente devo essere letti tutti), ora vorrei provare a collegarci un DHT22. Ho cercato sui datasheet e sembra non vi siano problematiche simili ai sensori Dallas, unico accorgimento è che tra una lettura e l'altra devono passare almeno due secondi.
Veniamo alla mia richiesta: pensate possa essere una soluzione quella di inserire nello sketch una semplicissima funzione tipo blink (pin 1 sec a livello alto e uno a livello basso) utilizzando ovviamente la funzione millis().
Farei la stessa cosa su un altro arduino dove gira SOLO lo sketch di blink. Colelgo i due arduino all'oscilloscopio e vedo se l'arduino "farcito e caricato" rallenta rispetto a quello libero.
E' una prova stupida oppure posso effettivamente vedere se lo sketch subisce rallentamenti?
Allora parlare di rallentamento su una MCU single core single thread non ha senso non vi è nulla che può rallentarla con occupazione risorse da altri processi, quello che accade è che se sta facendo qualcosa (Es. un ciclo while) le altre istruzioni (esterne al while) non possono essere eseguite.
Hai necessità di ricevere impulsi e devi catturarli tutti? la soluzione è l'uso degli interrupt che come dice il loro nome interrompono il flusso standard dell'esecuzione del codcie per fare ciò che c'è nell'ISR dell'interrupt (la quale deve essere eseguita nel minor tempo possibile poiché quando sei dentro l'ISR gli interrupt sono disattivi) nel tuo caso potresi limitarti ad incrementare una variabile, nel loop principale quando hai terminato di leggere la temperatura verificherai il valore della variabile e farai ciò che devi
@fabpolli: Mi sono espresso male, in effetti è come dici tu: intendo proprio che se la MCU è impegnata a fare altro (vedi esempio dei sensori DS18B20 che impiegano fino a 750ms per inviare il dato) non esegue altre istruzioni.
Approfondisco la mia fobia: un sensore mi invia impulsi per ogni W assorbito. Nel peggiore delle ipotesi potrei avere un impulso ogni secondo e questo non dovrebbe essere un problema.
Vorrei aggiungere un anemometro e qua gli impulsi si fanno più veloci. Se ad esempio una struzione richiedesse 750ms, potrei perdermi qualche impulso. Convengo con te che l'utilizzo degli interrupt sia la soluzione (a proposito, ci sono problemi nell'utilizzare 2 pin di interrupt? Uno per anemometro ed uno per il sensore assorbimenti?)
@Matteo: spesso le soluzioni più semplici sono le migliori! Il tuo suggerimento mi evita di scomodare l'oscilloscopio Grazie!
Ripeto, è una mia fobia (stupida) quella di pensare che vi siano ritardi "esagerati" dovuti ad alcune istruzioni o cicli ecc.
In questo caso potrebbe non essere una fobia ma una casistica reale, non so quanti impulsi dia l'anemometro in un secondo ma se fossero anche solo due potresti perderli (o perderne uno) se stai interrogando la sonda DS18B20.
Se stai usando una uno hai la possibilità di definire due ISR su due distinti interrupt (pin 2 e 3) senza problemi.
Unica cosa dentro l'ISR fai il meno possibile e non puoi usare millis() ad esempio perché dentro l'ISR come detto gli interrupt sono spenti. (Se proprio ti serve il tempo usa micros() )
L'utilizzo di un secondo arduino è già stato pianificato nel caso riscontrassi problematiche.
Preferirei ovviamente evitare hardware aggiuntivo, ma se necessario ben venga.
Pensavo di poter ribattere al caro Guglielmo ed invece ecco che la sua dritta si rivela fondata.
Dico questo perché per i primi due minuti vedevo un tempo di loop di 300ms circa (165 e 285) e non mi sembrava il caso di scomodare i microsecondi.
Poi a quanto pare arduino (in realtà è un nodemcu) si è stabilizzato. Invio i dati della durata loop ad un serverino ogni minuto e i valori sono sempre compresi tra 0 e 1ms. Ovviamente qua ci sta a verificare con i microsecondi.
occhio che alcune librerie bloccano gli interrupt quando devono eseguire letture o altro per cui occorre verificare le librerie in uso se si vogliono usare gli interrupt
Patrick_M:
occhio che alcune librerie bloccano gli interrupt quando devono eseguire letture o altro per cui occorre verificare le librerie in uso se si vogliono usare gli interrupt
... la micros(), contrariamente alla millis(), è comunque "interrupt safe", tanto è vero che la si può usare all'interno di una ISR
Aggiorno giusto per dare qualche info.
Aggiornato lo sketch per leggere in microsecondi.
tempo loop quando non deve fare quasi nulla ma verificare solo se c'è un impulso e calcolare il delta tra un impulso e l'altro più un paio di moltiplicazioni: 800us circa
tempo loop per leggere valore umidità e temperatura da un DHT22: 278477us
tempo loop per leggere i valori di temperatura di 3 sonde DS18B20 (con codice ottimizzato per non avere ritardi): 44825us
Lo sketch gira su un nodemcu ed ogni valore letto lo butta su seriale ed invia al server tramite MQTT.
E' attivo un loop anche per aggiornamento dello sketch via OTA.
Proprio ora, per leggere DHT22 e 3 sonde Dallas: 320729us