www.mikrocontroller.net

Forum: Compiler & IDEs PPM Signal erzeugen


Autor: David (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi @ all

Ich möchte gerne ein PPM Signal erzegen. Als µC habe ich einen Mega168. 
Das ganze will ich derzeit auf 4 Kanäle limintieren mit Option auf 6.

Das PPM Signal schaut so aus: 
http://www.aerodesign.de/peter/2000/PCM/frame_ppm.gif

Die ADC Kanäle smple ich fortlaufend Interruptbasierend. Sprich ich 
starte mit Kanal 1. Wenn der fertig ist, meldet sich die ISR. Ich lese 
den Wert aus und starte mit Kanal 2. Das mache ich bis zum 4. Kanal und 
dann wieder von vorne. Ist das so sinnvoll?

Nur wie erzeuge ich am Besten das Signal?

Ich habe 2 Zeiten die immer gleich sind. Die Pause mit 0,3ms.
Da der Puls immer zwischen 1 und 2ms liegt, kann ich 1ms immer gleich 
lassen. Die zweiten 1ms entsprechen dann dem AdC Wert.

Zum Schluss habe ich noch den "Auffüllpuls".

Ist es sinnvoll sozusagen mehrere Timer zu verwenden? zB 0,3ms TIMER -> 
1 ms Timer -> Variabler Timer (max 1ms) -> 0,3ms Timer -> 1ms Timer,...

Oder gibt es bessere Strategien?

Ich hoffe es kann mir wer helfen

mfg
David

Autor: unbeschreiblicher Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Die ADC Kanäle smple ich fortlaufend Interruptbasierend. Sprich ich
>starte mit Kanal 1. Wenn der fertig ist, meldet sich die ISR. Ich lese
>den Wert aus und starte mit Kanal 2. Das mache ich bis zum 4. Kanal und
>dann wieder von vorne. Ist das so sinnvoll?

ja.

>Nur wie erzeuge ich am Besten das Signal?

Scheint das typische Modellbau-Fernsteuer-Telegramm zu sein.
Dazu gibt es in der Codesammlung einen Beitrag von Ulrich Radig.
Sonst nimmt man einen Timer im CTC-Modus und übergibt ihm immer den 
nächsten Wert.
Dazu muß nur der ADC-Wert umgerechnet werden...

Autor: unbeschreiblicher Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ist es sinnvoll sozusagen mehrere Timer zu verwenden? zB 0,3ms TIMER ->
>1 ms Timer -> Variabler Timer (max 1ms) -> 0,3ms Timer -> 1ms Timer,...

Nicht wirklich.
Das kann man wunderbar per OC-Interrupts machen bzw. den CTC-TOP-Wert 
ändern.
0,3ms sind für einen Mikrocontroller eine kleine Ewigkeit (300 Takte bei 
1MHz...).

Autor: David (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wenn ich es mit einem Timer mache, muss ich es zwangsläufig mit dem 
16 Bit Timer machen...

Für den Servobereich möchte ich gerne 8 Bit ausnützen (das kann ich ja 
leicht aus dem AD Wandler auslesen).

1ms möchte ich also in 8 Bit teilen. Jedoch wird das ja ziemlich knapp, 
oder.

Bei 20 MHz µC Takt hab ich nur ~78 Takte zwischen den IRQs. Oder sind 8 
Bit zu viel?

Wie kann ich das anders machen?

Gruß David

Autor: David (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab nun mal schnell was geschrieben:
ISR(TIMER1_COMPA_vect)
{
    if(~--time)
    {
  if(pause)
  {
    time = PAUSE;
    pause = 0;
  }
  else
  {
    pause = 1;
    if(++servozaehler < 8)
    {
      time = servo[servozaehler];
    }
    else
    {
      time = lonpulse;
      servozaehler = -1;
    }
  }
    }
}

Pause hat immer einen Fixwert. Nur wie oder wo berechne ich am besten 
longpulse? Das ist ja die gesamte Frametime - 8 * Pause - den 8 
Servopulsen. Nur das ist ja sehr aufwendig. Wo kann ich das am besten 
machen?

Wenn ich die Servoregister fortlaufend über ISR akualisiere. Dann hab 
ich Probkleme. Angenommen ich Sende Puls 0. Während Puls 3 wird Servo 0 
neu gesampled und danach errechne ich den longpulse Wert. Dann geht da 
ein falscher Wert in die Berechnung ein. Wie kann ich das am besten v 
erhindern?

Das samplen nur während der lonpulse Phase zulassen?

Autor: uneinnehmbarer WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: uneinnehmbarer WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>(~--time)

~ ist eine bitweise Invetierung.
Meinst du die hier wirklich?

Mal was anderes:
Was soll das werden? Das RC-Summen-Signal erzeugt Ulrich Radig scheinbar 
erfolgreich (hab mir den Thread nicht noch mal genau angesehen).
Um Servos u.dergl. zu betreiben gibt es einfachere Lösungen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> wenn ich diese gewisse Funktion mehrmals in gewissen Abständen
> aufrufen muss, z.b. bei einer Kalibrierung eines Knopfes/Tasters
> (Widerstandscodiert) und mit anschließender Speicherung des
> Mittelwertes.

Bei jedem ISR Aufruf wird ja nur 1 Servokanal behandelt.
Initialisiere dir lonpulse mit der kompletten Zeitdauer.
Bei jedem ISR Aufruf für einen Kanal ziehst du die für
diesen Kanal benötigte Zeit von lonpulse ab. Wenn alle
Kanäle behandelt sind, steht lonpulse schon auf dem richtigen
Wert. Den übernimmst du dann als time Wert und initialisierst
ihn wieder neu mit der Maximalzeit.

Autor: David (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meinte eigentlich !--time

Danke Karl für den Tipp,das werde ich mal versuchen.

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.