Go Down

Topic: Uscita impulsiva per 3 secondi (Read 1 time) previous topic - next topic

pablos

#15
Mar 28, 2013, 10:30 pm Last Edit: Mar 28, 2013, 10:55 pm by pablos Reason: 1
io avrei fatto un array di tempi e un solo millis() di controllo nel loop.

Siccome il millis restituisce i millesimi che a te non servono toglierei le ultime tre cifre (/1000) ottenendo i secondi e preleverei solo l'ultima parte int (potresti farlo anche con i byte raggiungeresti un massimo di 4 minuti circa), poi a ogni ciclo loop confronto tutto l'array con il millis trascorsi, sempre /1000

Supponendo di avere 10 pin con funzione impulso regolabile a piacere:

salvare 10 uns long costa 4 byte*10 ... 40 byte ti permette un impulso da 1 sec a 49 giorni (sprecato)
salvare 10 uns int costa 2 byte*10 ...20 byte ti permette un impulso da 1 sec a 18 ore circa (sprecato)
salvare 10 byte costa 1 byte*10 ...10 byte ti permette un impulso da 1 sec a 4 min circa (ottimizzato)

non ho fatto i conti precisi ma +/- siamo li

ciao
no comment

leo72

L'idea di un array la appoggio, un pò meno quella di usare i valori in secondi. Alla fine il risparmio è relativo in uno sketch nel complesso piccolo. Inoltre si aggrava di codice il programma per cui ad un risparmio di Ram ci devi aggiungere un consumo maggiore di Flash.

gpb01

#17
Mar 29, 2013, 08:26 am Last Edit: Mar 29, 2013, 08:29 am by gpb01 Reason: 1

...
Ora ho incontrato un problema...ovvero se invio due comandi consecutivi tipo "J1 J2" il sistema non risponde in multitasking bensì accende prima il Relè 1,dopo due secondi spegne il Relè 1,
poi accende il relè 2,dopo due secondi spegne il Relè 2...
...

Pietro,
Arduino NON possiede un sistema operativo che gestisce i vari task o i vari processi ... su Arduino TUTTO è demandato al tuo codice quindi, se vuoi fare cose che sembrano funzionare in "multitask" ... le devi gestire tu. ;)

Come ti è stato ben suggerito, costruisciti una serie di variabili (esempio, come ti ha detto pablos, un array) che usi per memorizzare le varie tempistiche, sapere quando hai attivato un determinato pin, calcolare quanto tempo è passato e, al momento giusto disattivarlo.

In pratica il tuo loop() deve sempre girare (senza mai fermarsi in pause o attese) effettuando più cose ...

... leggere la seriale e vedere se ci sono dei nuovi comandi
... eventualmente creare una coda di comandi ricevuti
... processare gli eventuali comandi in coda
... gestire una serie di "timer virtuali" (ovvero delle variabili in cui memorizzi tu il tempo) legati ai vari eventi
... attivare e disattivare i vari pin (o eseguire altre funzioni) in funzione dei comandi e dei tempi
... ecc. ecc.

In realtà è più complicato a spiegarsi che a farsi ... se ti metti li con pazienza e implementi un pezzetto per volta, vedrai che non avrai problemi ;)

Guglielmo

P.S. : Altrimenti ... http://www.leonardomiliani.com/2012/leos-un-semplice-so-per-arduino/ ... che ti aiuta proprio in queste cose ;)
Search is Your friend ... or I am Your enemy !

leo72


P.S. : Altrimenti ... http://www.leonardomiliani.com/2012/leos-un-semplice-so-per-arduino/ ... che ti aiuta proprio in queste cose ;)

Grazie per la segnalazione.  ;)
Il leOS è un piccolo scheduler che può eseguire piccoli compiti (task) ad intervalli regolari ed in totale trasparenza per il codice utente, eseguendo questi task in background. Quindi una volta lanciato, l'utente si può scordare del task che ha schedulato.

MauroTec

Leggevo ieri sera i post e naturalmente mi è venuta una soluzione, volevo usare Arduino IDE dopo tanto tempo che non lo uso per scrivere qualcosa passo passo, ma non ho ancora tempo, vedremo se riesco o se la cosa cade nel dimenticatoi.

Quando si crea un protocollo software ci si deve chiedere se questo deve essere generalizzato o specifico, quelli specifici sono più efficienti e semplici da implementare.

Se inviamo i dati in pacchetto, es >02552550025500< invio 8 byte + 2 10 byte totali. > rappresenta l'inizio degli 8 byte, dopo questo carattere/codice posso cominciare a coservare i dati in un array di almeno 8 byte, oppure 16, 24, ecc.

Il carattere < indica che lo stream ricevuto è terminato ed è completo e non devo scriverlo nell'array.

La posizione di ogni elemento già ci indica quale relè devo comandare, cioè quale pin, vero non proprio direttamente ma possiamo anche creare un altro array di 8 byte contenente gli pin, tanto l'indice di entrambe gli array è comune.

Già questo è un primo passo, il seguente è scrivere una funzione da dare in pasto a leOS o altro scheduler, se lo scheduler permettesse interrogazione circa il completamento di un task si potrebbe chiedere nel loop() miotask è stato processato, es scheduler.isTaskTermined(miotask) se ritorna true, posso cominciare nuovamente a leggere dalla seriale per vedere se ci sono altri comandi.

Questo già fa capire che lo scheduler non serve, perchè prima che tutti i rele siano stati messi nello stato specificato io non posso ricevere altri byte. Invece lo scheduler può tornare utile quando voglio prendere dei dati dalla seriale metterli nel buffer darli in pasto ad uno scheduler che li processa ogni millesimo di secondo e io tra un millesimo e l'altro eseguo codice nel loop che svolge altre funzioni come ad esempio l'intercettazione dei pulsanti premuti, ma non mi aspetto più dati dalla seriale.

Però lo scheduler di leo può tornare utile per il fatto che oltre ad eseguire codice ogni millesimo di secondo, permette di specificare il timeout almeno credo, ma forse allora è più indicato secTimer sempre di leo.

Ciao.
AvrDudeQui front end per avrdude https://gitorious.org/avrdudequi/pages/Home

leo72

Volendo basterebbe spedire un singolo byte ogni 8 pin da impostare. Il byte avrebbe così lo stato degli 8 pin nei valori 0 per off/low e 1 per on/high.
Però si parla di complicazioni che ad un principiante non è consigliato suggerire, ci arriverà da solo quando cercherà il modo di ottimizzare il software.

Tornando al leOS, ne ho scritte 2 versioni. La prima è basata su un timer con risoluzione di 1 ms ma non permette di impostare il timeout. La seconda, leOS2, gestisce il timeout ma nel senso che se un task si blocca e freeza tutto il micro, un bel reset rimette ogni cosa a posto  ]:D
Il leOS non è un RTOS quindi non gestisce nessuno scambio di task mediante salvataggio e ripristino dello stato dei registri del microcontrollore. Ci ho lavorato per un po' ad una terza versione del leOS che avesse questa capacità ma al momento mi sono fermato perché si va un pò troppo oltre le mie capacità nonché si rende il leOS troppo complicato, esulando dai motivi per cui è nato, essere cioè un prodotto facilmente usabile anche da un niubbo.

Go Up