Leggere duty cycle con arduino

Salve, come da titolo, Arduino può leggere un duty cycle inviato da un altro Arduino? Ad esempio se io con un Arduino mando un duty cycle con analogwrite tramite il Pin digitale 3 ad un altro Arduino e leggo il valore con analogread nel Pin analogico A0 dell'altro Arduino, leggo il valore corretto? O ci sono disturbi dovuti alla caduta di tensione sul filo ? Capisco che analogwrite li manda fino a 255 mentre analogread li legge fino a 1023, però vabbè se è solo questione di unità di misura non è un problema. ah e metterei entrambi a massa comune

analogWrite() e analogRead() non sono funzioni "speculari", a dispetto del nome, che in verità è un po' fuorviante.

Come giustamente dici, analogWrite() attiva un segnale PWM su di un pin, mentre analogRead() legge un livello analogico, ovvero valore preciso della tensione presente sul pin (tra 0 e 5V).

Sicuramente si può dedurre il duty cycle in qualche modo, ma sinceramente non mi sono mai posto il problema e non saprei qual è il modo più conveniente. Probabilmente si può usare un interrupt CHANGE, ma aspetta suggerimenti di qualcuno più ferrato di me.

Diciamo che vorrei utilizzarlo come metodo alternativo alla comunicazione i2c e alla seriale. Cioè anziché inviare un byte ad esempio come nella i2c, mando un duty cycle. Il duty cycle, essendo compreso tra 0 e 255, può essere letto come un byte. Sempre compensando la caduta di tensione sul filo che è effettivamente calcolabile immagino. Diciamo che é curiosità, per capire se viene effettivamente bene

Non credo che potrai leggerlo con una precisione così elevata. Inoltre la caduta di tensione c'entra poco, se hai capito come funziona il PWM...

Diciamo che é curiosità, per capire se viene effettivamente bene

Non viene bene e non conviene e sarebbe comunque una comunicazione unidirezionale. Detto ciò qualcosa è possibile fare, ma occorre fare ricorso almeno ad un filtro passa basso per convertire il PWM in un segnale molto simile ad una differenza di potenziale continua proporzionale al valore di PWM, in questo caso un pin analogico riuscirebbe a fare il suo lavoro.

Ricavare informazioni dal segnale PWM è fattibile, ma impegna risorse hardware interne alla MCU, come ad esempio il Timer1 e il pin Input capture e c'è da vere se si trova qualche libreria specifica.

Alternative, c'è n'è, c'è la serial sofware, mi pare anche onewire software ecc, non sono il massimo della efficienza ma lavora. L'alternativa ancora è di usare un DAC (Digital Analogic Converter) esterno che però dovrai collegare in qualche modo o via ISP o I2c per cui, mi sembra sprecato, ma questo lo decidi tu se lo è o meno, quindi dal DAC esce una tensione continua che entra in un pin analogico a cui fa capo il convertitore ADC (Analogic Digital Convert) presente nella MCU.

Ciao.

Io pensavo più a pulseIn()
lo usavo per leggere il pwm del RSSI di un xbee che ha un segnale modulato... magari mi sbaglio. Attendi altri punti di vista...

Io pensavo più a pulseIn()

Ricordami come funziona pulseIn(), mi pare si usi in codice bloccante, per cui per il momento che misuri la larghezza dell'impulso altre porzioni di codice restano non eseguite.

lo usavo per leggere il pwm del RSSI di un xbee che ha un segnale modulato... magari mi sbaglio. Attendi altri punti di vista...

Se lo hai usato con successo posta un esempio di uso se è semplice. Può essere che se ha risolto il tuo di problema risolva anche il suo.

Ciao.

Sono da smartphone ma questo è simile a quello che ho usato io... anche se io facevo "campionamento"...
Edit: prima domanda dell'op.

ichigokurosaki:
Salve, come da titolo, Arduino può leggere un duty cycle inviato da un altro Arduino?

non mi sembra che parli di bloccante, stati finiti e strutturazione dati... ed io ho ribadito... attendi altri punti di vista...

Veramente a me risulta che la pulseIn() sia bloccante, tanto è che è una "funzione" che ritorna un valore alla fine dell'acquisizione ...

Reads a pulse (either HIGH or LOW) on a pin. For example, if value is HIGH, pulseIn() waits for the pin to go from LOW to HIGH, starts timing, then waits for the pin to go LOW and stops timing. Returns the length of the pulse in microseconds or gives up and returns 0 if no complete pulse was received within the timeout.

... inoltre, non la vedo molto adatta adatta a calcolare un duty-cycle di un segnale dato che non solo ti serve la durata dell'impulso, ma ANCHE il periodo di tutto il segnale ::slight_smile:

La cosa è fattibile con un timer ed un interrupt che scatta sul "CHANGE", ma sicuramente NON la vedo come una grande idea per un sistema di trasmissione dati.

Per inciso, ci sono MCU economicissime, come il PIC16F1619 di Microchip, che hanno al loro interno una periferica fatta apposta per quello che l'OP chiede (misura del duty-cycle); nel caso particolare si chiama SMT (Signal Measurement Timer) che, tra le altre cose, restituisce periodo e duty-cycle del segnale che gli si applica :wink:

Guglielmo

gpb01:
Per inciso, ci sono MCU economicissime, come il PIC16F1619 di Microchip, che hanno al loro interno una periferica fatta apposta per quello che l'OP chiede (misura del duty-cycle); nel caso particolare si chiama SMT (Signal Measurement Timer) che, tra le altre cose, restituisce periodo e duty-cycle del segnale che gli si applica :wink:

Guglielmo

Ah interessante :slight_smile: eventualmente ci sarebbe la possibilità di misurare il duty cycle allo stesso modo in cui si misurano i giri di un encoder digitale? Perché mi sembra che l"encoder dà un onda' quadra giusto? Correggetemi se sbaglio

La risposta completa te l'ha data Guglielmo, usi una interrupt CHANGE e misuri la durata del fronte alto e basso e calcoli il duty cycle in base a questi due tempi.
Mi sa che la pulsein, oltre ad essere bloccante, ti fornisce solo una delle due misure che ti servono, vado a naso perchè non mi sono andato a leggere bene in dettaglio come funziona, ancora.
Con questo sistema, però, ti si apre un altro problema, come distingui quando c'è il cambio di valore?
Cioè se devi passare 2 byte come fai a capire dove finisce il primo e dove inizia il secondo?
Devi stabilire delle regole anche per questo.
Magari regole banali, però ti servono per capire quando inizia la comunicazione, dove inizia un nuovo byte, quando finisce la comunicazione, come validi il pacchetto ricevuto per vedere se ci sono stati errori, ecc.
Tutte quelle cose che negli altri sistemi di comunicazione sono già implementate e rodate :wink:
E poi la frequenza da utilizzare commisurata alla precisione delle letture, se non usi multipli puoi arrivare ad avere una misura di durata di un impulso che si colloca a metà tra due misure valide e a quel punto cosa prendi? arrotondi per eccesso o per difetto? hai il 50% di sbagliare di UNO la tua misura, è accettabile?

ichigokurosaki:
Arduino può leggere un duty cycle inviato da un altro Arduino?

Si, e senza grossi problemi, a meno che il tuo codice non richieda particolari risorse di calcolo altrove.
Nel mondo degli aggeggi radiocomandati si usa un segnale PPM, che praticamente può "incapsulare" su un pin circa 8 segnali PWM. Ci sono librerie già pronte sia per la codifica che per la decodifica di un segnale PPM.

gpb01:
hanno al loro interno una periferica fatta apposta per quello che l'OP chiede

Forse c'è da fare un po' di chiarezza su questo, leggere un duty cycle con un analog read è un po' una contraddizione in termini.

ichigokurosaki:
ci sarebbe la possibilità di misurare il duty cycle allo stesso modo in cui si misurano i giri di un encoder digitale?

Più o meno è questo che significa "misurare il duty cycle". :slight_smile:

Prova a descrivere cosa vuoi fare più in generale, mi sembra che siamo in un "problema xy".

daysleeper:
Forse c'è da fare un po' di chiarezza su questo, leggere un duty cycle con un analog read è un po' una contraddizione in termini.

... e cosa ha a che vedere con la mia frase ? ? ? :o

Guglielmo

pulseIn() può leggere sia la durata della parte positiva che di quella negativa, quindi anche il periodo e il duty cycle. E' bloccante per il tempo di misura. Bisogna vedere se il loop può essere bloccato per qualche istante senza problemi.

Datman:
pulseIn() può leggere sia la durata della parte positiva che di quella negativa, quindi anche il periodo e il duty cycle.

NI ... non può fare le due cose simultaneamente, ma in due misurazioni successive, durante le quali ... le cose potrebbero essere cambiate :wink:

Guglielmo

gpb01:
... e cosa ha a che vedere con la mia frase ? ? ? :o

Guglielmo

Semplicemente che, secondo me, non era ancora chiaro cosa l'op stesse effettivamente chiedendo, vedi anche l'obiezione di Succo Pera sulla comprensione del PWM.
La frase era solo un pretesto per dire che non ci può essere qualcosa di "fatto apposta" per risolvere un problema non ancora definito, e che quindi per poter dare buone risposte era il caso di migliorare la domanda iniziale. :wink:

gpb01:
NI ... non può fare le due cose simultaneamente, ma in due misurazioni successive, durante le quali ... le cose potrebbero essere cambiate :wink:

Mi hai preceduto con la stessa obiezione che stavo per fare pure io :wink:

Datman:
pulseIn() può leggere sia la durata della parte positiva che di quella negativa, quindi anche il periodo e il duty cycle.

Anche a metterle in sequenza, una HIGH e l'altra LOW, leggeresti un fronte di un ciclo e l'altro del ciclo successivo, mai sullo stesso ciclo, per come è fatta la funzione, perchè da quando la attivi aspetta un ciclo completo prima di iniziare il conteggio.

daysleeper:
Semplicemente che, secondo me, non era ancora chiaro cosa l'op stesse effettivamente chiedendo ...

A me quello che l'OP stesse chiedendo è sembrato molto chiaro:

ichigokurosaki:
Salve, come da titolo, Arduino può leggere un duty cycle inviato da un altro Arduino? ...

... ovvero "dato un segnale PWM generato da un Arduino, posso leggerlo con un altro Arduino e saperne il duty-cycle?". La cosa è anche corroborata dalla spiegazione di quale era la sua intenzione ... usare il PWM per trasmettere dati ::slight_smile:

Che poi abbia mischiato "mele" (analogWrite) con "pomodori" (analogRead) è un altro paio di maniche :smiley: :smiley: :smiley: ...
... dovuto, probabilmente, alla scarsa conoscenza di come funzionano quelle due funzioni (... dove anche "wiring" ci mette del suo ... se invece di analogWrite() l'avesse chiamata pwmWrite(), sarebbe stata molto più corretta).

Guglielmo

Scusate faccio una risposta riassuntiva perché a causa della rete che se ne era andata si è cancellata la mia risposta.
Avete proposto pulseln;
Poi change e interrupt però sconsigliandola;
Piuttosto una MCU esterna economica;
Poi dalle vostre risposte mi sono reso conto che io pensavo che un duty cycle del 50% veniva letto come 2.5V invece viene semplicemente letto come 5V 0V 5V 0V 5V 0V... e quindi qui il mio errore.
Poi avete parlato di segnale PPM;
Poi avete sconsigliato pulseln;
In conclusione, sembrerebbe meglio o quello che ha detto Guglielmo con una mcu esterna, oppure con un segnale PPM. Farò comunque delle prove e aggiornerò

Scusate se ho scritto un po' strano XD

... fai pure ma ricorda che ... come sistema per "trasmissione dati" ... non lo vedo né funzionale, né affidabile, né efficiente. Per cui, salvo che per "divertirsi", questa cosa non è di alcuna utilità ::slight_smile:

Guglielmo