Arduino leest PWM duty cycle-waarde met input (analoog / digitaal)

Ik ben bezig met het vergelijken van stuurautomaten zoals Ardupilot , CC3D , KK2.1.5 . De vergelijking gaat over systeemreacties / gedragingen die het geeft tijdens de vlucht. Voor dit doel moet ik de PWM-duty-cycle (zoals osilascopes – de PWM-frequentie kan variëren van 50 tot 430 Hz) waarden van de stuurautomaatkaart lezen. Er zijn 4 PWMs voor opdrachtinvoer en 4 PWMs voor esc-besturing voor een typische quadrotor. Ik moet 8 duty cycle-waarden lezen met digitale / analoge input-pinnen. Hoe meet ik de duty-cycle van 8 PWM-signalen? Zijn digitale of analoge metingen ook nauwkeurig en sneller?

Opmerking over attachInterrupt commando: Volgens arduino.cc AtMega328-series hebben 2 interrupts , Arduino ATmega 2560-serie heeft 7 interrupts.

Antwoord

De code die wordt weergegeven in mijn antwoord op vraag 18183 , “Lees RC-ontvangerkanalen met Interrupt in plaats van PulseIn ”. Dat antwoord heeft code om vier kanalen van RC PWM te lezen. Het kan gemakkelijk worden aangepast om met acht kanalen te werken. Het heeft een ISR die wordt uitgevoerd wanneer geselecteerde pinnen veranderen. Het sorteert welke kanalen zijn gewijzigd en slaat de waarde van micros() bij elke wijziging op.

Zie ook mijn antwoord op vraag 19106 , “Kunnen externe interrupts OR” d samen zijn op de “328 (Uno)?” Dat antwoord bevat een schets voor het genereren van de juiste ISR-code. Mijn antwoord op vraag 32572 , “Hoe de richting van een roterende encoder te detecteren?”, toont een ander voorbeeld.

Digitale invoer, zoals gebruikt in de hierboven genoemde code, duurt minder dan een microseconde tien microseconden in de ISR. Zoals opgemerkt in de opmerking van dannyf, kan het uitrollen van de for -lus en (waar mogelijk) het gebruik van constanten in plaats van variabelen de in-ISR-tijd verkorten tot 3,4 μs. Let op: ISR entry en exit voeg nog steeds enkele microseconden toe.

10-bits analoge invoer, aan de andere kant, duurt ongeveer 104 microseconden per meting, een tijd die vergelijkbaar is met sommige van de pulsbreedtes die je gaat meten. Het is dus niet “snel genoeg. Als verminderde ADC-nauwkeurigheid acceptabel is, kan het verlagen van de ADC-klokschaalfactor, zoals uitgelegd in een webpagina op microsmart.co.za breng de AD-conversietijd terug tot 20 μs. Dit is ongeveer drie keer zo lang als digitale invoer, dus nogal traag.

Opmerkingen

  • > duurt minder dan een microseconde in de ISR, dat vind ik onwaarschijnlijk. Het is duidelijk dat ik ' m niet zeker weet over welke codestukken je het had – zoals het zijn er drie. maar een causale blik op hen zou suggereren dat er meer dan 16 tikken nodig zijn om het lichaam van de ISR uit te voeren – de overhead niet meegerekend. In feite zei een klein vogeltje van mij dat het zou neem dicht bij 8us om ze uit te voeren op een Uno, 🙂
  • @dannyf, ik keek naar een van de eenvoudigere ISRs (single encoder counting) toen ik dat schreef, dus ik zal het antwoord met correct moeten bewerken tijd. Sorry!
  • geen probleem. twee suggesties: 1) rol de while-lus uit; 2) gebruik constanten in plaats van variabelen. en ik zou ook rcOld statisch maken in de ISR, zodat de code modulair is. daarmee heb ik de uitvoeringstijd teruggebracht tot 3.4us.
  • Kun je je code delen in plaats van links? De AtMega328-serie heeft ook 2 interrupts, de Arduino ATmega 2560-serie heeft 7 interrupts. Dus hoe kan ik 8 gelijktijdige PWM-signalen meten? arduino.cc/en/Reference/attachInterrupt
  • @acs, ATmega328 ' s hebben 26 verschillende interruptvectoren. De vectoren die worden gebruikt in de code waarnaar wordt verwezen, zijn voor pin-change-interrupts of PCINTs, die drie van die vectoren gebruiken. PCINTs zijn beschikbaar op 22 van de ATmega328-gebaseerde nano-pinnen, en een vergelijkbaar aantal op Uno ' s. Raadpleeg de code die in de vorige vragen werd getoond – op dit moment moet ik deadlines halen.

Antwoord

indien gedaan in analoog, voer de pwm door een lpf en voer een adc uit op de output;

indien gedaan in analoog, gebruik dan de opnamefunctie van een timer, of gebruik een externe interrupt / pin change interrupt om de timing van een tijdbasis vast te leggen.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *