Jeg jobber med å sammenligne autopiloter som Ardupilot , CC3D , KK2.1.5 . Sammenligningen handler om systemreaksjoner / atferd som den gir under flyturen. For dette formålet må jeg lese PWM-driftssyklusen (som osilaskoper – PWM-frekvensen kan variere fra 50 til 430 Hz) fra autopilotkortet. Det er fire PWM-er for kommandoinngang og 4 PWM-er for kontroll for en typisk quadrotor. Jeg må lese 8 driftssyklusverdier med digitale / analoge inngangspinner. Hvordan måler jeg driftssyklus på 8 PWM-signaler? Er også digital eller analog måling presis og raskere?
Merk om attachInterrupt kommando: I følge arduino.cc AtMega328-serien har 2 avbrudd , Arduino ATmega 2560-serien har 7 avbrudd.
Svar
Koden vist i mitt svar på spørsmål 18183 , «Les RC-mottakerkanaler ved hjelp av Interrupt i stedet for PulseIn ”. Svaret har kode for å lese fire kanaler med RC PWM. Den kan enkelt tilpasses til å fungere med åtte kanaler. Den har en ISR som kjører når valgte pinner endres. Det sorterer ut hvilke kanaler som er endret, og lagrer verdien av micros()
ved hver endring.
Se også mitt svar på spørsmål 19106 , «Kan eksterne forstyrrelser ELLER» d sammen på «328 (Uno)?» Svaret inkluderer en skisse for å generere passende ISR-kode. Mitt svar på spørsmål 32572 , «Hvordan oppdager du retningen til en roterende koder?», viser en annen forekomst.
Digital inngang, som brukt i koden nevnt ovenfor, tar under en mikrosekund ti mikrosekunder i ISR. Som bemerket i dannyfs kommentar, kan rulling av for
loop og (hvor det er mulig) ved bruk av konstanter i stedet for variabler redusere in-ISR-tiden til 3,4 μs. Merk, ISR-inn- og utgang fortsatt legge til flere mikrosekunder.
10-bit analog inngang, derimot, vil ta rundt 104 mikrosekunder per avlesning, en tid som kan sammenlignes med noen av pulsbredden du skal måle. Så det er ikke raskt nok. Hvis svekket ADC-nøyaktighet er akseptabelt, kan en reduksjon av ADC-klokkeskalafaktoren som forklart i en webside på microsmart.co.za få AD-konverteringstid ned til 20 μs. Dette er omtrent tre ganger så lang tid som digital inngang tar, så ganske sakte.
Kommentarer
- > tar under en mikrosekund i ISR, det synes jeg er usannsynlig. Det er åpenbart at jeg ' er usikker på hvilke kodestykker du snakket om – som de er tre av dem. men et kausalt blikk på dem antyder at det vil ta mer enn 16 flått å utføre ISR-legemet – uten å telle overhead. Faktisk sa en liten fugl av meg at det ville ta nærmere 8us for å utføre dem på en Uno, 🙂
- @dannyf, jeg så på en av de enklere ISRene (single encoder counting) da jeg skrev det, så må redigere svaret med riktig tid. Beklager!
- ikke noe problem. to forslag: 1) rull ut mens løkken; 2) bruk konstanter i stedet for variabler. og jeg vil også gjøre rcOld til en statisk inne i ISR slik at koden er mer modulær. med det fikk jeg kjøringstiden nede på 3.4us.
- Kan du dele koden din i stedet for lenker. AtMega328-serien har også 2 avbrudd, Arduino ATmega 2560-serien har 7 avbrudd. Så hvordan kan jeg måle 8 samtidige PWM-signaler? arduino.cc/en/Reference/attachInterrupt
- @acs, ATmega328 ' har 26 forskjellige avbruddsvektorer. Vektorene som brukes i den refererte koden, er for pin-endringsavbrudd, eller PCINT-er, som bruker 3 av disse vektorene. PCINT-er er tilgjengelige på 22 av de ATmega328-baserte Nano-pinnene, og et lignende antall på Uno ' s. Vennligst referer til koden som er vist i de forrige spørsmålene – for øyeblikket har jeg arbeidsfrister å oppfylle.
Svar
hvis det gjøres analogt, kjør pwm gjennom en lpf og utfør en adc på utgangen.
hvis du gjør det i digital, bruk en timerfunksjon eller bruk ekstern avbryt / pin-endringsavbrudd for å fange timingen av en tidsbase.