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
>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...
>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...).
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
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?
>(~--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.
> 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.