Vorweg: Ich steige gerade erst in die Mikrocontroller Programmierung ein. Nach meinen ersten Erfahrungen beim Nachbau und dem Einspielen der Firmware bei diesem RFID Leser (Beitrag "USB RFID Tag Leser"), habe ich mir ein kleines Test Board mit einem Atmega8 erstellt um das programmieren in C und AVR's besser kennen zu lernen. Nach dem ich mich durch etliche AVR Tutorials, Foren Beiträge und dem Datenblatt gelesen und viel gelernt habe (LED, TASTER, TIMER) kann ich ein Problem nicht beheben. Die Servoansteuerung funktioniert über einen Timer (funktioniert). Ich habe sie aus dem Artikel: Modellbauservo Ansteuerung übernommen. Wie der Titel schon sagt, soll das Board den Lauf eines (oder mehrere) Servos verzögern (verlangsamen). Der Wert den ServoValue[1] in der while Schleife erhält verändere ich in Abhängigkeit mit dem Wert der vom RC Empfänger kommt. Das Signal vom RC Empfänger wird über ein ISR Interrupt an INT1 gelesen (positive Flanke: Timer Start - Negative Flanke: Timer stop). Ein weiterer Timer zählt die Takte zwischen den Flanken und speichert diese in die Variable SignalDauer. Problem: Im Testaufbau verändert der Servo1 seine Position nicht. Der Oszillograph zeigt, das das Signal vom RC Empfänger anliegt. Irgendetwas im Code muss falsch sein. Da ich aber keine Erfahrung habe und mich schon sehr gefreut habe so weit zu kommen, finde ich nun den Fehler nicht. Ich fange erst an Interruppts zu verstehen. Über jeden noch so kleinen Tipp wäre ich dankbar!! Tobi
Etwas, das sofort auffällt: Wird die Int1 ISR aufgerufen und ist z.B. ISC10 = 0, so wird steigende_Flanke() aufgerufen, in der wiederum ISC10 auf 0 gesetzt wird. Wenn ISC10 = 1 ist, verhält sich's ähnlich. Das sollte wohl alternierend sein und so ist's das nicht. Natürlich darf es dann in der ISR nicht zweimal ein if-Block sein, sondern das muss ein if/else werden.
Danke MWS! Das wars - nach dem abziehen von 1ms vom Eingangssignal geht es jetzt. Leider Ruckeln die beiden angeschlossenen Servos ab und zu. Besonders wenn der Servo1, der durch den RC-Empfänger bedient wird, in Bewegung ist. Was entweder durch Störung der Versorgungspannung durch die Servos ausgelöst wird oder vom Code bedingt ist!? Ich hab dazu schon mal was im Forum gelesen. Ansonsten freue ich mich auch über jede andere Kritik. Für mich ist das Programmieren ganz neu.
Mittlerweile habe ich die Servos (5V Versorgungskabel) über ein extra Netzgerät verbunden um Spannungsverluste oder Stromverluste über das BEC RC System (Batterie) zu umgehen. Leider bleibt das Servozittern bestehen. Ich habe das im Forum gefunden: Beitrag "Re: Servo delay board" Da durch die Entkoppelung der Stromversorgung keine Besserung eintrat, muss es doch an der Programmierung liegen?!
Hallo Tobias, Servos reagieren auf Pulsänderungen im Bereich 2-5µs. Wenn man die Servoimpulse per Software erzeugt und eine Interruptroutine dazwischen funkt fangen die an zu zittern. Erzeuge den Servoimpuls mit einer freilaufenden PWM (16 Bit), bei der Du nur die Pulslänge veränderst. Grüße, Kurt
Kurt Harders schrieb: > Hallo Tobias, > Servos reagieren auf Pulsänderungen im Bereich 2-5µs. Wenn man die > Servoimpulse per Software erzeugt und eine Interruptroutine dazwischen > funkt fangen die an zu zittern. Erzeuge den Servoimpuls mit einer > freilaufenden PWM (16 Bit), bei der Du nur die Pulslänge veränderst. Ich glaub dir die 2-5µs Alternativ könnte man mal versuchen, die Zeitmess ISR massiv zu vereinfachen. So wie die jetzt geschrieben ist, ist die ja auf maximalen Zeitverbrauch ausgelegt. Da wurde so ziemlich alles gemacht, was man nicht tut.
1 | ISR (INT1_vect) |
2 | {
|
3 | static uint8_t last; |
4 | |
5 | if (MCUCR & (1 << ISC10)) // Testen auf steigende Flanke |
6 | {
|
7 | last = TCNT0; |
8 | MCUCR &= ~(1 << ISC10); // INT1 fallende Flanke |
9 | }
|
10 | else // Dann muss es steigende Flanke sein |
11 | {
|
12 | SignalDauer = TCNT0 - last; |
13 | MCUCR |= (1 << ISC10); |
14 | }
|
15 | }
|
Das sollte massiv schneller laufen. Mal sehen. Wenn die Zeitverzögerung durch die ISR eine Rolle spielt, dann sollte sich das Verhalten eigentlich verbessern, wenn auch nicht unbedingt komplett ausmerzen. Da du aber anscheinend sowieso nur 2 Servos brauchst, könnte man natürlich auch mit dem Timer 1 und seinen beiden PWM Einheiten die Servopulse erzeugen. Die vernünftigere Lösung wäre es (in diesem Fall) auf jeden Fall, auch wenn ich noch nicht nachgerechnet habe, wie sich dann das Timing mit dem 16 Bit Timer ausgeht.
Hallo Karl Heinz, mein Vorschlag kommt ja nicht aus der Theorie. Ich bin der Entwickler des Flüsterantriebs, der in der aktuellen Version, an der ich nicht mehr beteiligt bin :-), mit einem ATMega8 2 Servos mit Timer1 und den beiden OC ansteuert. Bei einer der Schnittstellenvarianten des Antriebs konmmt alle 50µs ein Interrupt für die serielle Ansteuerung (Selctrix-Protokoll) und das Servo steht stabil auf seiner Position. Selbst Digitalservos brummen/summen nicht. Kurz die Nutzung des Timers: 16-Bit Timer mit Vorteiler für 0,1µs Takt. Der Timer zählt bis 20.000, da die Servos alle 20ms einen Impuls erwarten. Der Start des Timers erfolgt "von Hand" und es werden beide Ausgänge gesetzt. Die Pins werden bei OC zurückgesetzt. Das Ende der 20ms wird in der inneren Prozessorschleife erkannt. Jede Lösung ohne Timer/PWM mit einem "störenden" Interrupt wird zum Zittern des Servos führen, denn auch Deine kurze Routine wird > 8 Zyklen benötigen, also für > 1µs die Pulserzeugung behindern. Grüße, Kurt
Kurt Harders schrieb: > Hallo Karl Heinz, > mein Vorschlag kommt ja nicht aus der Theorie. Nein, nein. So war das auch nicht gemeint. Wenn ich mir das Programm des TO so ansehe, dann denke ich nicht, dass er zwei Servoansteuerungen mit PWM alleine hinkriegt (er hat 2 Servos, Fast PWM mit Top Wert per Register ist also keine Lösung für ihn). Deshalb wollte ich ihm mal was geben, damit er mal seine ärgsten Timingfehler rauskriegt. Wenn das reicht, dann hat er Glück gehabt, wenn nicht, dann nicht.
Ich lese gespannt mit und Danke euch schon mal! @Kurt Harders: ich bin auch Besitzer einer Vespa ;)
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.
