Arduino legge il valore del ciclo di lavoro PWM con input (analogico / digitale)

Sto lavorando per confrontare i piloti automatici come Ardupilot , CC3D , KK2.1.5 . Il confronto riguarda le reazioni / comportamenti del sistema che dà durante il volo. A tal fine, ho bisogno di leggere i valori del ciclo di lavoro PWM (come gli osilascope – la frequenza PWM può variare da 50 a 430 Hz) dalla scheda autopilota. Ci sono 4 PWM di ingresso di comando e 4 PWM di controllo esc per un tipico quadrirotore. Devo leggere 8 valori di duty cycle con pin di ingresso digitale / analogico. Come misuro il duty cycle di 8 segnali PWM? Inoltre, la misurazione digitale o analogica è precisa e veloce?

Nota sul comando attachInterrupt : Secondo arduino.cc , la serie AtMega328 ha 2 interruzioni , La serie Arduino ATmega 2560 ha 7 interrupt.

Risposta

Il codice mostrato nella mia risposta alla domanda 18183 , “Leggi i canali del ricevitore RC utilizzando Interrupt invece di PulseIn “. Quella risposta ha il codice per leggere quattro canali di RC PWM. Può essere facilmente adattato per funzionare con otto canali. Ha un ISR che viene eseguito quando i pin selezionati cambiano. Ordina i canali modificati e memorizza il valore di micros() a ogni modifica.

Vedi anche la mia risposta alla domanda 19106 , “Le interruzioni esterne possono essere OR” d insieme su “328 (Uno)?” Quella risposta include uno schizzo per la generazione del codice ISR appropriato. La mia risposta alla domanda 32572 , “Come rilevare la direzione di un codificatore rotante?”, mostra unaltra istanza.

Ingresso digitale, come utilizzato nel codice menzionato sopra, richiede un microsecondo dieci microsecondi nellISR. Come indicato nel commento di dannyf, lo srotolamento del ciclo for e (dove possibile) luso di costanti invece delle variabili può ridurre il tempo di ISR a 3,4 μs. Nota, ingresso e uscita ISR aggiungere ancora diversi microsecondi.

Lingresso analogico a 10 bit, daltra parte, impiegherà circa 104 microsecondi per lettura, un tempo paragonabile ad alcune delle larghezze di impulso che misurerai. Quindi non è abbastanza veloce. Se laccuratezza dellADC ridotta è accettabile, è possibile ridurre il fattore di scala dellorologio dellADC come spiegato in una pagina web su microsmart.co.za ottenere un tempo di conversione AD fino a 20 μs. Questo è circa tre volte il tempo impiegato dallingresso digitale, quindi piuttosto lento.

Commenti

  • > impiega meno di un microsecondo nellISR, lo trovo improbabile. Ovviamente ' non sono sicuro di quali parti di codice stavi parlando, poiché sono tre di loro. ma uno sguardo causale su di loro suggerirebbe che ci vorranno più di 16 tick per eseguire il corpo dellISR, senza contare le spese generali. In effetti, un mio uccellino ha detto che sarebbe prendi quasi 8us per eseguirli su uno, 🙂
  • @dannyf, stavo guardando uno degli ISR più semplici (conteggio del codificatore singolo) quando lho scritto, quindi sarà necessario modificare la risposta con la corretta tempo. Spiacenti!
  • non è un problema. due suggerimenti: 1) srotolare il ciclo while; 2) usa le costanti piuttosto che le variabili. e vorrei anche rendere rcOld una statica allinterno dellISR in modo che il codice sia più modulare. con ciò, ho ridotto il tempo di esecuzione a 3,4us.
  • Puoi condividere il tuo codice invece dei link. Inoltre, la serie AtMega328 ha 2 interruzioni, la serie Arduino ATmega 2560 ha 7 interruzioni. Allora come posso misurare 8 segnali PWM simultanei? arduino.cc/en/Reference/attachInterrupt
  • @acs, ATmega328 ' hanno 26 diversi vettori di interrupt. I vettori utilizzati nel codice di riferimento sono per interrupt di cambio pin, o PCINT, che utilizzano 3 di quei vettori. I PCINT sono disponibili su 22 pin Nano basati su ATmega328 e un numero simile su Uno '. Si prega di fare riferimento al codice mostrato nelle domande precedenti: al momento ho delle scadenze di lavoro da rispettare.

Risposta

se fatto in analogico, esegui il pwm attraverso un lpf ed esegui un adc sulluscita;

se fatto in digitale, usa una funzione di cattura del timer, o usa interrupt esterno / interrupt di cambio pin per acquisire il tempo da una base di tempo.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *