Arduino læser PWM-arbejdscyklusværdi med input (analog / digital)

Jeg arbejder på at sammenligne autopiloter som Ardupilot , CC3D , KK2.1.5 . Sammenligningen handler om systemreaktioner / adfærd, som det giver under flyvning. Til dette formål er jeg nødt til at læse PWM-driftscyklussen (som osilascopes – PWM-frekvensen kan variere fra 50 til 430 Hz) fra autopilotkortet. Der er 4 kommandoindgangs-PWMer og 4 esc-styrings-PWMer til en typisk quadrotor. Jeg skal læse 8 driftscyklusværdier med digitale / analoge indgangsben. Hvordan måler jeg driftscyklus på 8 PWM-signaler? Er digital eller analog måling også præcis og hurtigere?

Bemærk om attachInterrupt kommando: I henhold til arduino.cc AtMega328 serien har 2 afbrydelser , Arduino ATmega 2560-serien har 7 afbrydelser.

Svar

Koden vist i mit svar på spørgsmål 18183 , “Læs RC-modtagerkanaler ved hjælp af Interrupt i stedet for PulseIn ”. Dette svar har kode til at læse fire kanaler af RC PWM. Det kan let tilpasses til at arbejde med otte kanaler. Den har en ISR, der kører, når de valgte ben skiftes. Det sorterer ud, hvilke kanaler der er ændret, og gemmer værdien af micros() ved hver ændring.

Se også mit svar på spørgsmål 19106 , “Kan eksterne afbrydelser ELLER” d sammen på “328 (Uno)?” Svaret inkluderer en skitse til generering af passende ISR-kode. Mit svar på spørgsmål 32572 , “Hvordan registreres retningen på en drejekoder?”, viser en anden forekomst.

Digital input, som bruges i koden nævnt ovenfor, tager under en mikrosekund ti mikrosekunder i ISR. Som bemærket i dannyfs kommentar kan udrulning af for loop og (hvor det er muligt) ved hjælp af konstanter i stedet for variabler reducere in-ISR-tiden til 3,4 μs. Bemærk, ISR ind- og udgang tilføj stadig flere mikrosekunder.

10-bit analog input vil på den anden side tage omkring 104 mikrosekunder pr. læsning, en tid der kan sammenlignes med nogle af de pulsbredder, du vil måle. Så det er ikke hurtigt nok. Hvis forringet ADC-nøjagtighed er acceptabel, kan en reduktion af ADC-urets skalafaktor som forklaret i en webside på microsmart.co.za få AD-konverteringstid ned til 20 μs. Dette er omkring tre gange så lang tid som digital input tager, så ret langsom.

Kommentarer

  • > tager en mikrosekund i ISR, det finder jeg usandsynligt. Det er klart, jeg ' er ikke sikker på, hvilke kodestykker du talte om – som de er tre af dem, men et kausalt kig på dem antyder, at det vil kræve mere end 16 flåter for at udføre ISR-legemet – ikke medregnet omkostningerne. Faktisk sagde en lille fugl af mig, at det ville tag tæt på 8us for at udføre dem på en Uno, 🙂
  • @dannyf, jeg kiggede på en af de enklere ISRer (single encoder counting), da jeg skrev det, så det bliver nødvendigt at redigere svaret med korrekt tid. Undskyld!
  • ikke et problem. to forslag: 1) rull mens-løkken ud; 2) brug konstanter snarere end variabler. og jeg ville også gøre rcOld til en statisk inde i ISR, så koden er mere modulær. med det fik jeg eksekveringstiden nede på 3.4us.
  • Kan du dele din kode i stedet for links. AtMega328-serien har også 2 afbrydelser, Arduino ATmega 2560-serien har 7 afbrydelser. Så hvordan kan jeg måle 8 samtidige PWM-signaler? arduino.cc/da/Reference/attachInterrupt
  • @acs, ATmega328 ' har 26 forskellige afbrydelsesvektorer. Vektorerne, der bruges i den henviste kode, er til pin-skift-afbrydelser eller PCINTer, der bruger 3 af disse vektorer. PCINTer fås på 22 af de ATmega328-baserede Nano-ben og et lignende antal på Uno ' s. Se koden, der er vist i de foregående spørgsmål – i øjeblikket har jeg arbejdsfrister til at overholde.

Svar

hvis det gøres analogt, skal du køre pwmen gennem en lpf og udføre en adc på udgangen.

hvis du gør det i digitalt, brug en timerfangstfunktion eller brug ekstern afbryd / pin-skift afbryd for at fange timingen fra en tidsbase.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *