Forum: Mikrocontroller und Digitale Elektronik Mehrere Servosignale auswerten


von Manuel Keßler (Gast)


Lesenswert?

Hallo,

ich möchte gerne für ein Modellflugprojekt mehrere Servosignale
auswerten, miteinander verrechnen (z.B. verschiedene Mischer) und
wieder Signale ausgeben. Das ist im Prinzip auch relativ
unproblematisch, solange man sich mit einem Signal begnügt, da gibt es
ja mehrere Möglichkeiten (Polling, INT-Pin, Capture).

Ich brauche aber mehrere (genau 4 Eingänge und 5 Ausgänge). Zudem ist
die Reihenfolge der Impulse nicht vorgegeben, d.h. bei einer Anwendung
könnten die Impulse vom Empfänger der Reihe nach an Eingang 1-2-3-4
auflaufen, bei einer anderen Anwendung an 4-2-3-1. Sieht man sich mal
den Empfängerausgang am Oszi an, können sich da durchaus zwei
aufeinanderfolgende Kanäle um einige zig Nanosekunden überlagern oder
auch eine Pause dazwischen sein. Erschwerend kommt hinzu dass einer
oder mehrere Kanäle voher noch durch andere Geräte laufen, z.B. einen
Kreisel. Damit sind letztendlich die High- und Lowflanken der einzelnen
Kanäle vollständig asynchron zueinander (auf jedem Kanal einzeln habe
ich natürlich die 1-2 ms bzw. entsprechende Pause).

Die Ausgabe ist unproblematisch, da kann ich die einzelnen Kanäle in
nacheinander ausgeben, aber bei der Eingabe hakt es. Überlappende
Impulse am Eingang zu ignorieren und dann für diesen Kanal eben den aus
dem nächsten Impulstelegramm zu nehmen ist auch keine Lösung, da wird
dann die Reaktionszeit zu lang. Ein gemeinsamer Interrupt geht auch
nicht wirklich gut, weil ich ja während der Verarbeitung im Interrupt
(Timer lesen, feststellen welcher Kanal den Interrupt ausgelöst hat,
Timerwert passend unterbringen) quasi blind auf den anderen Kanälen bin
und damit möglicherweise andere Flanken verpasse oder nach
Interruptende im nächsten Interrupt zu spät verarbeite (Latenzzeit) und
damit unangenehmen Jitter bekomme.

Kurz gesagt, ich möchte vier Impulsbreiten an vier Pins asynchron
messen. 8 Bit Auflösung halte ich für das Minimum. Verarbeitung und
Ausgabe ist dann kein Problem mehr. Am liebsten AVR, notfalls auch PIC
oder M16C.

Gibt es noch andere Ideen?

Ciao,
  Manuel

von HanneS (Gast)


Lesenswert?

Wie wärs mit Polling in Timer-ISR im Raster von 10µs? (Dann entstehen
gültige Werte von 100 bis 200.)
Macht bei mir ein 2313 mit 8MHz (Mega8 wäre aber besser) mit 4 Kanälen.
Allerdings kommen die Impulse nacheinander, wobei die Reihenfolge egal
ist. Für Überlappungen müsste dieses Prinzip aber auch funktionieren,
brauchst dann eben für jeden Kanal ein eigenes Zählregister...

Bit- & Bytebruch...
...HanneS...

von Martin (Gast)


Lesenswert?

Hallo Manuel,


Bin auch gerade bei einen Projekt mit Servo Ansteuerung, Ein und
Ausgänge.
Habe leider auch noch nicht die richtige Lösung, Was noch als Problem
hinzu kommt, ist
Das einige Empfänger ( Multiplex) immer zwei Kanäle gleichzeitig
ausgeben 1+2, 3+4 usw.

Mit freundlichen Grüßen
Martin

von Stefan Kleinwort (Gast)


Lesenswert?

Hi Manuel,

3 Eingänge kannst Du mit INT0, INT1 und Analog-Comparator-Int
bewältigen. In der IR-Routine den Timerstand bei steigender bzw.
fallender Flanke merken und daraus die Pulslänge berechnen.

1 Eingang kannst Du per Input-Capture-Funktion abdecken.

Die Ausgänge entweder mit den PWM-Funktionen oder auch per
Timer-IR-Software.

Wichtig ist, dass die IR möglichst kurz sind (bzw. die anderen IR
möglichst rasch wieder enabled sind), um ungewollte Delays zu
minimieren. Die IR also am Besten in Assembler schreiben. Ich denke, es
sollte machbar sein, 8-Bit-Genauigkeit (Worstcase) damit zu erreichen.

Stefan

von ingo (Gast)


Lesenswert?

Hallo Manuel,

die Lösung heisst in diesem Fall PIC. Diese verfügen über einen
B-Change Interupt für die Bits 4 bis 7.
Ich habe folgendes gemacht:
Der Timer 1 (16Bits) ist frei laufend und wird alle µ Sec.
incrementiert. Taucht nun an PB4 - PB7 ein Envent auf so wird der
Interupt ausgelösst. Im Interupthaendler lese ich den gesamten Port und
den Timer 1 aus. Diese Werte lege ich auf einem Stack ab, der maximal 8
Events aufnehmen kann.
Im Hauptprogramm arbeite ich diesen Stack kontinuierlich ab und sehe
nach, was passiert ist. Wurde ein Kanal gesetzt, dann wird der
Timerwert als Startwert gespeichert. Ist ein Kanal auf Low gegangen,
dann als Endwert. Haben sich zwei Kanäl durch überlappung geändert,
dann wird den Kanälen der Timerwert entsprechend der Änderung als
Start- oder Endwert zugewiesen.
Der Rest ist eine reine Fleissaufgabe. Hat man zwei Timerwerte für
einen Kanal, dann wurde ein Impuls vermessen. Aus dem Timerabstand
errechnet sich die Impulsbreite. Diese muss auf Plausibilität und
Gültigkeit überprüft werden.
Wenn ein Eventzeitpunkt um ist (sprich einer oder mehrere Kanäle haben
sich geändert), dann hat man mindestens eine mSec Zeit für die
Berechnungen.

GRUSS
INGO

von Matthias Pues (Gast)


Angehängte Dateien:

Lesenswert?

Hi, das problem, das die signale asyncron ankommen ist tatsächlich eines
;-), aber eine ähnliche lösung wurde hier schon einmal vorgestellt. Mit
einem Attiny26, der hat einen Pin-change-interrupt auf 11 pins (von 20)
für 4 eingänge und 5 ausgänge also geeignet.
Uboot-Stocki hatte zunächst in der Codesammlung etwas veröffentlicht:
http://www.mikrocontroller.net/forum/read-4-7047.html
und ich hab mich aucheinmal daran versucht und sein programm für meine
idee "verwurstet". ich hoff, daß hilft dir, wenn du meine eigenen
kommentare verstehst. das programm baut aber darauf auf, daß die
signale hintereinander kommen, das müßte verändert werden. es werden 3
signale auf 4 drehzahlsteller gemixt (hoffentlich, da ich es noch nicht
mit hardware ausprobiert habe).
Gruß Matthias

von Harald Manske (Gast)


Lesenswert?

Hallo Manuel,

ich bastel gerade an einem sehr ähnlichen Projekt. Allerdings sind
meine Anforderungen noch etwas höher - 8 Eingänge + 8 Ausgänge +
Änderung der Mischfunktionen etc. per PDA

Ich verwende dazu einen ATMega162, welcher den oben schon erwähnten Pin
Change Interrupt auslösen kann. Wenn ein solcher Interrupt kommt, wird
in meinem Programm eine Routine aufgerufen, die den aktuellen Zustand
des Eingangsports mit dem Zustand vor dem Pegelwechsel vergleicht.(XOR)
Dadurch kann ganz einfach herausgefunden an welchem Pin die Änderung
stattgefunden hat und die Impulslänge nach Ingos Verfahren (Ende -
Start) berechnet werden.

Diese Berechnung findet bei mir übrigens nicht in der Interruptroutine
statt. Dort wird lediglich ein Flag gesetzt und dann in der
Hauptschleife wegen diesem Flag in die zuständige Funktion gesprungen.

Das funktioniert auch schon relativ gut, leider hab ich noch ein
kleines bischen Zittern auf dem Servo. Das werde ich aber durch die
Verwendung von Assembler Routinen (momentan komplett C) und einer
Glättung vor der Ausgabe noch hinbekommen - denke ich.

Die von dir gewünschten 8 Bit Auflösung sind schon ein bischen arg
viel. Ich denke 100 Schritte sind schon mehr als brauchbar. Versuch
doch einfach mal am Sender 100 verschiedene Hebelstellungen
vorzugeben... du wirst sehen, dass ist gar nicht so einfach. Besonders
wenn du dir den Sender wie ein Modellflieger auf dem Platz umhängst,
anstatt ihn auf den Tisch zu legen :)

Ich würde gerne etwas genaueres über dein Projekt wissen. Deine
Emailadresse klingt als ob das ganze wie bei mir eine Projektarbeit für
deine Hochschule ist.

Viele Grüße!

von Manuel Keßler (Gast)


Lesenswert?

Hallo,

erstmal vielen Dank, an alle, die mit jeder Menge Anregungen geholfen
haben. Ich fasse kurz zusammen:
@HanneS: Polling in der ISR laesst wahrscheinlich doch etwas wenig
Spielraum, um noch rumzurechenen. Also Auflösung noch runterdrehen?
@Martin: Der normale PPM-Empfänger? Oder nur unter PCM?
@Stefan: Eigentlich würde ich ungern 4 Signale auf 4 verschiedene Arten
messen und damit 4 Routinen zu debuggen haben.
@Ingo: Das gefällt mir schon ganz gut, sowas ähnliches hatte ich mit
PIC16F84 auch schon probiert, aber der hat ja keinen Stack (größere
PICs natürlich schon). Ausserdem habe ich da keinen C-Compiler und
PIC-Assembler finde ich persönlich ziemlich scheußlich zu
programmieren.
@Matthias: Der entscheidende Tip. Interrupt on Pin Change auf dem
Atmel.
@Harald: So ähnlich wird es wohl werden. Projekt für Hochschule ist
schon nicht ganz falsch, allerdings habe ich den Studentenstatus schon
einige Tage hinter mir gelassen, mittlerweile bin ich bei der
Habilitation ;-)

Ich werde also jetzt die Hardware von Matthias und die Software(-idee)
von Ingo kombinieren, und wenn ich viel Glück habe, liegt in meiner
Grabbelkiste sogar noch so ein ATtiny26 rum und wartet auf Einsatz.
Anwendung ist übrigens ein heliähnlicher Drehflügler, der eine Art
120°-Mischer ohne Collective (also nur Nick und Roll) sowie eine Art
V-Mischer braucht. Mischung in der Anlage ist nicht möglich, weil ja
noch die Kreisel mit eingeschleift werden sollen.

Also nochmal Danke an alle, ich hatte schon befürchtet, VHDL lernen zu
müssen um ein FPGA mit mehreren unabhängigen Countern zu befüllen (BTW:
Gibt es überhaupt ein CPLD/FPGA mit, sagen wir, 200 Zellen/Flip-flops
und weniger als 100 Pins? Also möglichst niedrigem Pin/Gate Verhältnis?
SO-16 Gehäuse oder so wäre ja absolut ausreichend).

Ciao,
  Manuel

von Stefan Kleinwort (Gast)


Lesenswert?

Hi Manuel,

wenn Du den AVR mit Pin-Change benutzen willst: schau mal nach dem
mega48, meines Wissens ist der schon erhältlich, ist schön klein und
hat alle Features der mega-Serie. Die Nachfolger mit mehr Speicher
(mega88 und mega168) brauchen wohl noch ein paar Tage, bis sie
verfügbar sind. Dafür gibt es auch einen In-System-Debugger (one-wire),
ich weiss ja nicht, welches Budget Du für das Projekt hast ...

Im Pin-Change-IR beachten, dass sich auch (kurz hintereinander) mehrere
Signale ändern können. Es kann also manchmal sein, dass Du in einer
IR-Routine mehr als ein Signal zu verarbeiten hast (ist kein Problem,
nur denken muss man dran).

Viel Spaß, Stefan

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.