cosa è meglio "usare"

un dispositivo che monitora 4 ingressi e pilota 4 uscite
i segnali di ingresso vanno a livello alto per un tempo da 3 millisecondi a 20 millisecondi circa

le uscite dovrebbero seguire a ruota gli ingressi con la particolarità che il tempo potrebbe variare da

    • da zero a 20% ( a mia scelta)

che arduino usare?

Manca qualche dettaglio, gli impulsi sono in qualche modo correlati tra loro oppure sono asincroni e possono comparire anche contemporaneamente?

Le uscite devono attivarsi esattamente alla fine dell'impulso corrispondente?

Che tempo intercorre tra un impulso e il successivo?

Sembrerebbe un lavoro da bitbang in assembly più che da tipo di Arduino. Per dire, in assembly gestire impulsi da 3ms (anche accavallati) sarebbe una sciocchezza anche per un vecchio Z80.

Non credo che con un Arduino MEGA tu abbia problemi ...

... hai ben 6 pin che gestiscono l'interrupt (... quello vero, NON il pinChangeInt) quindi dovresti riuscire a scrive e un programma con tempi di risposta estremamente brevi. Hai inoltre anche 6 timers che, se ben programmati, fanno il lavoro per te senza troppo impegno di codice :wink:

Guglielmo

EDIT: QUI un esempio di come usare un Timer per generare un singolo impulso di durata predeterminata.

Claudio_FF:
Sembrerebbe un lavoro da bitbang in assembly più che da tipo di Arduino. Per dire, in assembly gestire impulsi da 3ms (anche accavallati) sarebbe una sciocchezza anche per un vecchio Z80.

Direi che è inutile scomodare l'assembly per questa cosa, si fa tranquillamente in C puro, ma tenuto conto delle tempistiche direi pure con un normale sketch Arduino senza usare "trucchi". :slight_smile:
Ovviamente mancano tutti i dettagli, p.e. non è chiaro se l'impulso in uscita deve essere contemporaneo a quello in ingresso, in questo caso serve sapere la latenza massima ammessa, o se deve iniziare subito dopo la fine dell'impulso in ingresso, cosa obbligatoria nel caso in cui gli impulsi devono avere una durata in funzione di quella in ingresso, pertanto vanno prima misurati e poi si emette l'impulso in uscita.

Io andrei sulla Arduino Zero. Tutti i pin digitali, eccetto il pin 4, hanno l'interrupt ed è più veloce della Arduino UNO/Mega.
Ma è un AMD e non un AVR. Quindi niente controllo diretto delle porte.

La ZERO usa un processore 32 bit ATSAMD21G18 con core Cortex M0+, non riesco a capire cosa intendi con "niente controllo diretto delle porte." perché su tutti le mcu/micro hai il controllo diretto delle porte.
In fin dei conti anche sulla ZERO hai la digitalwrite per manipolare direttamente lo stato dei gpio, se vuoi maggiore velocità basta che accedi direttamente ai relativi registri macchina del micro, esattamente come si fa con gli AVR, anche se la cosa è un pochino più complessa in quanto i gpio dei processori ARM offrono molte più opzioni di quelle presenti su i processori AVR.
Alla fine il concetto di base è lo stesso per tutti i micro, se con le cpu core ARM da un lato non c'è il supporto delle avrlibc, molto comodo, dall'altro lato hai il supporto della CMSIS che è l'equivalente delle avrlibc al cubo. :slight_smile:

PaoloP:
Io andrei sulla Arduino Zero. Tutti i pin digitali, eccetto il pin 4, hanno l'interrupt ed è più veloce della Arduino UNO/Mega.

... guarda che stiamo parlando di millisecondi NON di microsecondi :stuck_out_tongue_closed_eyes:

Guglielmo

Ma pure con i microsecondi si riesce a fare con gli AVR se non ci sono altre cose da fare che richiedono molto tempo cpu, dove non si arriva con il polling software basta usare i timer, visto che consentono il controllo del tempo con risoluzione fino a 62.5 ns e latenza massima, per gestire il relativo interrupt, di circa 1 us.
Come ho già detto in un altro topic, sotto il cofano di Arduino c'è molto di più di quello che si vede. :slight_smile:

astrobeed:
La ZERO usa un processore 32 bit ATSAMD21G18 con core Cortex M0+, non riesco a capire cosa intendi con "niente controllo diretto delle porte."

PORTC = 0;

Certo che non puoi usare PORTC = 0 sulla ZERO, cosa che non fa parte di wiring anche sugli Arduino a 8 bit visto che si tratta di manipolazione diretta dei registri macchina, però lo fai nel giusto modo per i micro con core ARM.
p.e. sulla ZERO con questo codice, l'ho trovato in rete, commuti un pin con una frequenza di qualche MHz, impossibile da fare con la classica digitalwrite

#include <Arduino.h>

#define PIN 10

#ifdef _VARIANT_ARDUINO_ZERO_
volatile uint32_t *setPin = &PORT->Group[g_APinDescription[PIN].ulPort].OUTSET.reg;
volatile uint32_t *clrPin = &PORT->Group[g_APinDescription[PIN].ulPort].OUTCLR.reg;

const uint32_t  PinMASK = (1ul << g_APinDescription[PIN].ulPin);
#endif

void setup() {
  pinMode(PIN, OUTPUT);
}

void loop() {
  while(1) {
#ifdef _VARIANT_ARDUINO_ZERO_
  *setPin = PinMASK;
  *clrPin = PinMASK;
#else
    digitalWrite(PIN, HIGH);
    digitalWrite(PIN, LOW);
#endif
  }
}

Claudio_FF:
Manca qualche dettaglio, gli impulsi sono in qualche modo correlati tra loro oppure sono asincroni e possono comparire anche contemporaneamente?

Le uscite devono attivarsi esattamente alla fine dell'impulso corrispondente?

Che tempo intercorre tra un impulso e il successivo?

Sembrerebbe un lavoro da bitbang in assembly più che da tipo di Arduino. Per dire, in assembly gestire impulsi da 3ms (anche accavallati) sarebbe una sciocchezza anche per un vecchio Z80.

il tempo tra l impulso di entrata e quello di uscita deve essere il più basso possibile meglio quasi zero,

gli impulsi di entrata arrivano "in sequenza" mai due allo stesso tempo,
il "tempo" tra impulsi sullo stesso pin può arrivare al massimo a 65 impulsi secondo

se una mega può farlo e resta anche un po di poco di calcolo per le cose di "contorno" sta bene

La butto lì:
Centralina elettronica, motore 4 cilindri, variare angolo (durata) dell'iniezione.....

Ci ho preso?

Aggiungo:

Dato il numero di giri direi diesel

Ricapitoliamo le cose, abbiamo quattro segnali distinti in ingresso sotto forma di impulsi, non hai specificato se negativi o positivi, con una durata compresa tra 3 e 20 ms, inoltre questi impulsi arrivano in sequenza e sono sempre singoli, non ci sono mai due, o più, impulsi in contemporanea, il numero massimo di impulsi su un canale è 65 in un secondo, il che pone un limite allo loro durata di non oltre 15.3 ms se arrivano con questa frequenza su un solo canale, manca un dato importante la separazione temporale minima tra due impulsi consecutivi.
Altra domanda, gli impulsi arrivano sempre tutti e quattro, in sequenza, oppure possono arrivare solo su un canale oppure su 2 o 3 canali per un tot tempo ?
Se gli impulsi arrivano in sequenza è sempre identica, p.e. 1-2-3-4, oppure può variare, se varia lo fa in modo random oppure c'è una legge matematica che definisce la variazione ?
Meglio ancora se ci dici esattamente cosa devi misurare così ci facciamo un'idea migliore della cosa, in tutti i casi non si risolve in modo semplice usando solo funzioni di libreria Arduino, tocca lavorare low level con i timer, la gestione dei GPIO e gli interrupt.
In linea di massima è un problema molto simile alla gestione dei segnali di una ricevente RC e relativa generazione, previa elaborazione, di comandi per dei servo, cosa che si fa senza problemi con Arduino.

impulsi sono positivi

la sequenza é immutabile sempre 1234

per la la separazione temporale minima tra due impulsi consecutivi non riesco a comprendere cosa intendi

Vediamo se riesco a ricapitolare io:

ragionando su un solo canale, con 65 impulsi al secondo il tempo tra un impulso e il successivo e di 15,4 millisecondi
se un singolo impulso dura fino a 20 milliscondo è chiaro che l'impulso successivo arriva quando il precedente non è ancora finito, si sovrappongono per circa 4,6 millisecondi, in pratica non hai un treno di impulsi ma un segnale continuo
quindi non solo quello che vuoi fare non possibile, è anche impossibile che tu abbia degli impulsi come li hai descritti
inoltre è evidente che se vuoi regolare la durata dell'impulso, aumentandola, serve che in ingresso ci sia un tempo "vuoto" lungo almeno il tempo che vuoi aggiungere,
se come dici è il 20 percento e l'impulso in ingresso arriva a 20 millisecondi l'impulso in uscita deve essere di 24 millisecondi (20+20%)

questo da una frequenza massima di 1/0.024 ovvero poco più di 41 Hz

quindi o accorci gli impulsi massimi o riduci la cadenza degli impulsi

peggio ancora se l'impulso lo devi "accorciare"
per saperne la durata devi per forza sapere quando inizia, ma anche quando finisce
quindi non puoi far iniziare l'impuslo di uscita prima che quello in ingresso finisca

casomai, non so se ti può andare bene, potresti "interrompere" l'impulso d'uscita a cadenza regolare

mi speigo con un esempio:

al millisecondo 0 comincia l'impulso in ingresso
ammesso che finisca al millisecondo 10, e tu lo volessi accorciare del 10%
dovresti farlo partire al millisecondo 10 e interromperlo al millisecondo 19, durata 9 millisecondi, ovvero 10-10%

in alternativa potresti fare così, misurando in decimillesimi di secondo
al decimillesimo 0 arriva l'impulso
al decimillesimo 1 avvii l'impulso di uscita
al decimillesimo 10 lo interrompi
per riprenderlo al decimillesimo 11
per interromperlo al decimillesimo 20

e via così

in questa maniera puoi avviare l'impulso di uscita subito e "allungare il brodo" per ridurre la durata della conduzione dell'impulso, non il tempo totale, che invece deve essere almeno pari alla durata dell'ingresso, come mostrato nell'esempio 1

ce lo dici che cosa vuoi fare?
che magari viene fuori un'idea alternativa....

te hai ragione ho notato anche io queste "stranezze " anche se ho messo 20 millisecondi "circa"
l impulso massimo effettivo che ho letto era di 17,3 millisecondi ma qui siamo proprio al massimo estremo,

comunque per il tempo di regolazione va bene anche la lettura dell 'impulso precedente

es: lettura canale 1, 6 millisecondi si memorizza da qualche parte
lettura canale 1, 7 millisecondi si memorizza da qualche parte, uscita canale 1, 6 millisecondi piu
correzione che puo essere al max piu o meno del 20% es 5 o 6,5 millisecondi

questo e quello che mi interessa, il "cuore" del sistema
l inizio dell'ingresso corrisponde con l inizio dell uscita (interrupt ?)

gpb01:
Non credo che con un Arduino MEGA tu abbia problemi ...

... hai ben 6 pin che gestiscono l'interrupt (... quello vero, NON il pinChangeInt) quindi dovresti riuscire a scrive e un programma con tempi di risposta estremamente brevi. Hai inoltre anche 6 timers che, se ben programmati, fanno il lavoro per te senza troppo impegno di codice :wink:

Guglielmo

EDIT: QUI un esempio di come usare un Timer per generare un singolo impulso di durata predeterminata.

si hai ragione una mega e si va sul sicuro