Forum: Compiler & IDEs PPM Signal erzeugen


von David (Gast)


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

von unbeschreiblicher Rahul (Gast)


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...

von unbeschreiblicher Rahul (Gast)


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...).

von David (Gast)


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

von David (Gast)


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?

von uneinnehmbarer WM-Rahul (Gast)


Lesenswert?


von uneinnehmbarer WM-Rahul (Gast)


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.

von Karl H. (kbuchegg)


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.

von David (Gast)


Lesenswert?

Meinte eigentlich !--time

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

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.