Ich arbeite daran, Autopiloten wie zu vergleichen Ardupilot , CC3D , KK2.1.5 . Der Vergleich bezieht sich auf Systemreaktionen / -verhalten, die es während des Fluges gibt. Zu diesem Zweck muss ich den PWM-Arbeitszyklus (wie bei Osilascopes – die PWM-Frequenz kann zwischen 50 und 430 Hz variieren) von der Autopilotkarte lesen. Es gibt 4 Befehlseingabe-PWMs und 4 Esc-Steuer-PWMs für einen typischen Quadrotor. Ich muss 8 Tastverhältniswerte mit digitalen / analogen Eingangspins lesen. Wie messe ich das Tastverhältnis von 8 PWM-Signalen? Ist die digitale oder analoge Messung präzise und schneller?
Hinweis zum Befehl attachInterrupt : Laut arduino.cc haben AtMega328-Serien 2 Interrupts Die Arduino ATmega 2560-Serie hat 7 Interrupts.
Antwort
Der in meiner Antwort auf Frage 18183 gezeigte Code: „Lesen Sie RC-Empfängerkanäle mit Interrupt anstelle von PulseIn ”. Diese Antwort enthält Code zum Lesen von vier RC-PWM-Kanälen. Es kann leicht an acht Kanäle angepasst werden. Es hat einen ISR, der ausgeführt wird, wenn sich ausgewählte Pins ändern. Es sortiert, welche Kanäle sich geändert haben, und speichert den Wert von micros()
bei jeder Änderung.
Siehe auch meine Antwort auf Frage 19106 : „Können externe Interrupts auf dem“ 328 (Uno) ODER „d zusammen sein?“ Diese Antwort enthält eine Skizze zum Generieren eines geeigneten ISR-Codes. Meine Antwort auf Frage 32572 , „Wie erkennt man die Richtung eines Drehgebers?“, zeigt eine andere Instanz.
Digitaleingang, as Die Verwendung in dem oben erwähnten Code dauert im ISR unter eine Mikrosekunde zehn Mikrosekunden. Wie in dannyfs Kommentar erwähnt, kann das Abrollen der for
-Schleife und (soweit möglich) die Verwendung von Konstanten anstelle von Variablen die In-ISR-Zeit auf 3,4 μs reduzieren Fügen Sie noch einige Mikrosekunden hinzu.
Der 10-Bit-Analogeingang benötigt dagegen etwa 104 Mikrosekunden pro Messwert, eine Zeit, die mit einigen der zu messenden Impulsbreiten vergleichbar ist. Es ist also nicht schnell genug. Wenn eine verschlechterte ADC-Genauigkeit akzeptabel ist, kann der ADC-Takt-Skalierungsfaktor verringert werden, wie in einer Webseite bei microsmart.co.za erläutert Die AD-Konvertierungszeit wird auf 20 μs gesenkt. Dies ist ungefähr dreimal so lange wie die digitale Eingabe, also ziemlich langsam.
Kommentare
- > dauert im ISR weniger als eine Mikrosekunde, das finde ich unwahrscheinlich. Offensichtlich bin ich ' nicht sicher, über welche Codeteile Sie gesprochen haben – als Sie sind drei von ihnen, aber ein kausaler Blick auf sie würde darauf hindeuten, dass es mehr als 16 Zecken dauern wird, um den Körper des ISR auszuführen – ohne den Overhead zu zählen. Tatsächlich sagte ein kleiner Vogel von mir, dass dies der Fall sein würde Nehmen Sie fast 8us, um sie auf einem Uno auszuführen 🙂
- @dannyf, ich habe mir einen der einfacheren ISRs (Single Encoder Counting) angesehen, als ich das geschrieben habe, also muss ich die Antwort mit korrekt bearbeiten Zeit. Entschuldigung!
- kein Problem. Zwei Vorschläge: 1) Rollen Sie die while-Schleife ab. 2) Verwenden Sie Konstanten anstelle von Variablen. und ich würde rcOld auch innerhalb des ISR statisch machen, damit der Code modularer ist. Damit habe ich die Ausführungszeit auf 3.4us reduziert.
- Können Sie Ihren Code anstelle von Links freigeben? Die AtMega328-Serie verfügt über 2 Interrupts, die Arduino ATmega 2560-Serie über 7 Interrupts. Wie kann ich also 8 simultane PWM-Signale messen? arduino.cc/en/Reference/attachInterrupt
- @acs, ATmega328 ' s haben 26 verschiedene Interruptvektoren. Die im referenzierten Code verwendeten Vektoren sind für Pinwechselinterrupts oder PCINTs, die 3 dieser Vektoren verwenden. PCINTs sind für 22 der ATmega328-basierten Nano-Pins und eine ähnliche Nummer für Uno ' verfügbar. Bitte beziehen Sie sich auf den Code in den vorherigen Fragen – im Moment habe ich Arbeitsfristen einzuhalten.
Antwort
Wenn dies analog erfolgt, führen Sie das pwm durch ein lpf und führen Sie eine ADC am Ausgang durch.
Wenn dies digital erfolgt, verwenden Sie die Erfassungsfunktion eines Timers oder verwenden Sie einen externen Interrupt / Pinwechsel-Interrupt um das Timing außerhalb einer Zeitbasis zu erfassen.