PPM Signal erzeugen

Gast #465136
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
Gast #465149
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...
Gast #465152
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...).
Gast #465168
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
Gast #465201
Lesenswert?
• ▲
▼
Hab nun mal schnell was geschrieben:
1
ISR(TIMER1_COMPA_vect)
2
{
3
    if(~--time)
4
    {
5
  if(pause)
6
  {
7
    time = PAUSE;
8
    pause = 0;
9
  }
10
  else
11
  {
12
    pause = 1;
13
    if(++servozaehler < 8)
14
    {
15
      time = servo[servozaehler];
16
    }
17
    else
18
    {
19
      time = lonpulse;
20
      servozaehler = -1;
21
    }
22
  }
23
    }
24
}

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?
Gast #465219
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.
#465223
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.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.