Hallo Leute, ich weiß es ist ein leidiges Thema und auch schon 3 Millionen mal diskutiert, aber ich hab wirklich jeden Thread zu dem Thema per Such-Funktion gelesen. Hier mein Problem. Ich möchte mit einem ATMega88 die Pulsweiten der einzelnen Kanäle messen, die von einem Modellbauempfänger ausgegeben werden. Dabei ist sichergestellt, daß die Kanäle nacheinander (PPM) ausgegeben werden; Beispiel: __ Kanal 1: _| |_________________ _ Kanal 2: ____| |______________ __ Kanal 3: ________| |___________ _ Kanal 4: ___________| |________ Soweit so gut. Mein Problem ist jetzt nur daß sich die Reihenfolge in der die Kanalausgänge vom Empfänger zu den Eingängen am µC ändern können bzw. nicht vorher feststehen, wobei ich hierfür evtl. eine Lösung habe, zu der ich sehr gerne andere Meinungen hören würde! Nämlich zuerst auf das dekodierte PPM Signal (RC-Summensignal, Impulstelegramm, .... dauert bei meiner Graupner Anlage 22.5ms) synchronisieren. Dafür starte ich einen Timer mit Overflow bei rund 6ms. Der Timercounter wird immer beim auslösen eines externen Interrupts auf 0 gesetzt. Da nur 4 Kanäle verarbeitet werden und jeder Kanal eine maximale Pulslänge von ca. 2,1ms hat verstreichen max. 8,4ms bis alle Kanäle abgearbeitet sind. Da danach keine externen Interrupts ausgelöst werden läuft der gestartete Timer irgendwann in den Overflow Interrupt. Ab hier soll dann die eigentliche Messung der Kanäle beginnen. Da ich ja keine Kenntnis über die Reihenfolge der Kanäle habe behaupe ich einfach es sei mir egal und setze bei jeder ermittelten Pulsweite für einen entsprechenden Kanal ein Bit in einer Variable (z.B. Kanal 1: Bit 0, Kanal 2: Bit 1, .....) Im Hauptprogramm prüfe ich die Flagvariable auf die Bits 0 - 3 und wenn alle gesetzt sind, sind alle Pulsweiten gemessen ..... Dann erfolgt ein wenig rechnen und dann die Ausgabe was kein Problem ist.... Mein zweites Problem ist, daß wenn die Empfängerausgänge beispielsweise an PORT B0 - B4 hängen und die externen Interrupts eingeschaltet sind folgendes "Phänomen" auftritt: Ausgehen vom obigen Bild löst PCINT0 aus wenn der Pegel von Kanal 1 high geht. Ich merk mir dem Timer Wert und gut. Danach löst wieder PCINT0 aus wenn der Pegel auf low geht. Timer Wert gespeichert, alles wunderbar. Problem jetzt ist nur, daß Kanal 2 sofort danach schon high wird, was keinen externen INT an PCINT1 mehr auslöst! Theoretisch könnte ich den Endwert von Kanal 1 als Startwert für Kanal 2 nehmen (die Zeitdifferenz ist vernachlässigbar bzw. wenn mit dem Oszi gemessen, dann als fester Wert verfügbar), aber dann habe ich das Problem, nicht zu wissen in welcher Reihenfolge die Empfängerausgänge an den µC - Eingängen angeschlossen sind. Also hier sollte ich dann wohl erst rausfinden in welcher Reihenfolge die Signal nacheinander kommen (sortieren) und dann wie beschrieben vorgehen ....., oder ? Eine andere Alternative die ich heute abend mal kurz anprobiert habe ist das permanente Pollen der Eingänge. Hier ein kleines Codefragment (für nur 2 Kanäle): uint8_t LastState = 0x00; uint8_t States[100]; uint8_t StateIndex = 0; uint8_t ChangeState; for (;;) { ChangeState = PINB ^ LastState; if (ChangeState > 0) { State[StateIndex++] = PINB & 0b00000011; if (StateIndex == 100) { uint8_t i; for (i = 0; i < 100; i++) usart_putc (State[i]); exit (1); } LastState = PINB; } } Dieser Code wird (wie die "Checker" sicher schon kapiert haben) prüfen, ob sich an den Input Pins was getan hat und wenn ja, dann wird der aktuelle Zustand in einem Array für eine spätere Ausgabe per RS-232 gespeichert. Die ausgegebene Bitabfolge sieht dann folgendermassen aus: 0000 0000 0000 0001 0000 0010 0000 0000 0000 0001 0000 0010 0000 0000 Also erkannt wird das "high" gehen von PB0 aber nicht mehr das low gehen, da die nächste erkannte Änderung das "high" gehen von PB1 ist. Danach wird dann noch das "low" gehen von PB1 erkannt ...... Gibt's da nicht irgendwas schlaues wie man dies so bitweise verwurstelt, um bei Unkenntnis der Kanalreihenfolge immer die richtigen Start- und Endwerte in einem Array ablegt (z.B. PWMStart[4], PWMEnd[4]) um dann wenn alle Flags der Messungen gesetzt sind, die Pulsweiten berechnen kann ? So langsam raucht mir die Birne .... und ich wäre für Input sehr dankbar ! Grüße, Michael
Hab das Gleiche (?) Projekt auf dem Tisch... allerdings ist bei mir die Kanalreihenfolge sehr wohl bekannt. Du hast vier Eingänge. Du programmierst einen Pinchange-Interrupt. byte AktuellerKanal = 0; // unbekannt OnPinchangeInterrupt { if (AktuellerKanal != 0) // Beende laufende Messung, und speichere Messwert für Kanal X switch (PORTA & 0x0F) { case 0x01: AktuellerKanal = 1; // Starte PWM Messung break; case 0x02: AktuellerKanal = 2; // Starte PWM Messung break; case 0x04: AktuellerKanal = 3; // Starte PWM Messung break; case 0x08: AktuellerKanal = 4; // Starte PWM Messung break; default: AktuellerKanal = 0; break; } } Was wird das überhaupt? Ein Quattrocopter?
Gut geraten Chrisi! Bin noch am Anfang und spare noch für die Regler und Motoren, aber das kommt noch ! Die meisten Projekte werten ja direkt das PPM Signal aus und das zurecht, weils viel einfacher ist, aber ich wollte eben wissen ob es auch so geht ....
Ja, das macht auch Sinn. Ich denke der Code oben sollte unabhängig von der Reihenfolge sein. Bei mir liegt hier ein ATmega168... allerdings für ein Modellboot. Viel Erfolg!
>Unkenntnis der Kanalreihenfolge Legst du nicht die Funktion fest, die mit dem jeweiligen Pin des Mikrocontrollers zusammenhängt? Deine Methode des Vergleichens der Zustände der Eingänge ist doch wunderbar. Da spielt die Reihenfolge in der die Kanäle kommen keine Rolle. Eigentlich brauchst du dir in einem Array nur den Zustand der Eingänge und einen Zeitstempel merken. Und das dann nacheinander abarbeiten. Vielleicht hilft dir das hier auch noch: http://www.hanneslux.de/avr/mobau/index.html
Hallo, Einen SourceCode findet ihr bei mir auf der Homepage! AVR und für die Philips ARM LPC2138. Gruss Ulrich Radig
Besten Dank für die Antworten ! @STK500-Besitzer: > Legst du nicht die Funktion fest, die mit dem jeweiligen Pin des > Mikrocontrollers zusammenhängt? Das schon, aber ich möchte erst eine "allgemein" funktionierenden "Algorithmus" basteln, damit ich dieses Rad nicht immer neu erfinden werde (Denn ob Servo - Winkelgeschwindigkeitsverzögerer, Delta-Mischer oder was auch schon war oder noch kommt ...). Für den Copter dann müssen die Kanäle entsprechend zugeordnet werden ... da hast Du recht! > Eigentlich brauchst du dir in einem Array nur den Zustand der Eingänge > und einen Zeitstempel merken. Und das dann nacheinander abarbeiten. Schon .... da haperts eben mit den "Bits" ein wenig ..., aber ich kämpfe weiter ! @Ulrich: Besten Dank ! Deine und die Seite von Hannes sind bei solchen Projekten immer meine erste Informationsquelle! Was ich auf Deiner Seite gefunden habe ist ein der Code ein RC-Summensignal auszuwerten oder zu erzeugen. Ich versuche ja die vom Empfänger schon dekodierten Pulsweiten zu messen .... falls ich's übersehen habe, wär's super wenn Du mir den direkten Link geben könntest ! Ich such noch mal .... Grüße, Michael
Haben wir wohl alle schon mal durch, die Sache. ich verwende das Summensignal (Sind bei mir zwar nur zwei Kanäle, aber vom Prinzip egal). Da steht eineindeutig fest, welcher Kanal wann an der Reihe ist :-)) Gruß AxelR. zur Info: Beitrag "Servoausgänge verUNDen"
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.