mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PWM Messung am Modellbauempfänger


Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ....

Autor: Eddy Current (chrisi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!

Autor: Michael K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Werde ich heute abend mal ausprobieren ....

Danke!
Michael

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Autor: Ulrich Radig (radiguli) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Einen SourceCode findet ihr bei mir auf der Homepage! AVR und für die 
Philips ARM LPC2138.

Gruss
Ulrich Radig

Autor: Michael K. (mmike)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Axel R. (axelr) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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"

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.