Hallo, vorneweg: Ja, ich habe die SuFu genutzt und ich weis dass es dieses Thema schon 1000x gab, aber ich finde seit Tagen keine Antwort. Ich will mit dem Timer0 (8-Bit reichen mir vorerst zum verstehen/lernen) ein Servo ansteuern. Ich lasse ihn bei 8MHz und einem Presaler von 64 immer von 6 bis 265 zählen (sind dann genau 2ms), und das 10x, so dass ich einen Gesamt-Durchlauf von 20ms habe, was ja der Länge eines Servo-"Befehls" entspricht. Trotzdem will der Servo nicht das machen was er soll. Kann mir da wer helfen? Danke :) Kristian
Ich sollte erwähnen dass ich auf einem AtMega 168 programmiere, was einer meiner Probleme ist, da alle Hilfen etc meist für den AtMega8 geschrieben wurde... MfG
Kristian schrieb: > Ich lasse ihn bei 8MHz und einem Presaler von 64 immer von 6 bis 265 > zählen CTC-Modus wäre besser. Kristian schrieb: > Trotzdem will der Servo nicht das machen was er soll. Und was soll er machen? Und was macht er stattdessen?
So, danke erstmal für die Antworten. Ich hab mich mal in den CTC Modus reinarbeitet, sollte theoretisch richtig sein, denke ich. Eigentlich sollte der Servo jetzt auf eine Stellung fahren und da ruhig verharren. Aber alles was er macht ist ungesund knirschen (was nicht an dem Servo liegt, der ist funktionstüchtig). Ich hab leider kein Oszi um zu sehen was da wirklich aus dem Atmega kommt und ich habe keine Schimmer was ich falsch mache. MfG
Kristian G. schrieb: > Eigentlich sollte der Servo jetzt auf eine Stellung fahren Verstehst du denn selbst, was dein Programm machen soll? Ich verstehe es nicht. Z.B. soll Stellung Werte ab 0 annehmen können; OCR0A wird aber auf (256-Stellung) gesetzt und hätte mit 256 damit ggf. einen Wert, der nicht mehr in 8 Bit passt. Ist das so beabsichtigt? Welchen Sinn hat on bzw. wieso hat sie diesen Namen? Sie ist immer an, wenn der Port aus ist und umgekehrt. Ein paar Worte zur Erklärung, wie das alles zusmmenspielen soll, würde dir vielleicht selbst helfen...
Kristian G. schrieb: > Ich hab leider kein Oszi um zu sehen was da wirklich aus dem Atmega > kommt und ich habe keine Schimmer was ich falsch mache. Werden denn im Simulator die richtigen Signale für den Servo erzeugt? ATmega8 und ATmega168 sind so was von ähnlich, dass die Programme mit minimalen Änderungen übertragbar sind.
Ich denke schon dass ich mein Programm verstehe. Zuerst danke, ja, es müsste 255 heißen, nicht 256. Zu "on": Ich hatte vor ein genau 20ms lange Durchlaufzeit zu haben, bis ich wieder mit dem Impuls für den Servo beginne. Um das zu gewährleisten habe ich 10 Durchläufe durch "servo_counter". Da jetzt aber das Servo "High" Signal auch nur 1ms lang sein kann, muss ich die fehlende 1ms noch nachschieben. Dafür ist das "on" gedacht. Das erste IF behandelt das high-Sognal, das das zweite IF den fehlenden Anteil der 2ms. Mir ist vorhin aufgefallen, dass der Durchlauf aber gar nicht 20ms lang sein muss, sonder 10-20ms. Das würde bedeuten, ich brauche den "on" Teil garnicht, was den Quelltext erheblich vereinfacht.
1 | SIGNAL(TIMER0_COMPA_vect) |
2 | {
|
3 | int Stellung = 64; //nur noch 1.5ms! (0-128) |
4 | servo_counter++; //Zählt bis 10 -> max. 20ms |
5 | if (servo_counter == 1) |
6 | {
|
7 | PORTB = 0x00; //An, also Signal auf "high" |
8 | OCR0A = 255 - Stellung; //Wie lange auf High lassen? Min 1ms, max 2ms -> Min ~128, max ~255 |
9 | }
|
10 | if (servo_counter == 2) |
11 | {
|
12 | PORTB = 0xFF; //Ist die "High-Zeit" für Servo um -> Signal für die restlichen 18-19ms auf "low" |
13 | }
|
14 | if (servo_counter == 10) |
15 | {
|
16 | servo_counter = 0; //10ter Durchlauf -> von vorne (ca 20 ms sind rum). |
17 | }
|
18 | }
|
Nichts desto trotz surrt mein Servo ungesund und bewegt sich unkontrolliert hin und her.
Ich bin nochmal mit dem Debugger durch alles gegangen, dabei ist mir zwar aufgefallen, dass bei "if (servo_counter == 2)" ein "OCR0A = 0xFF;". Sonst stimmen die Timings, aber es ändert immer noch nichts an der Tatsache, dass mein Servo nicht das tut was er soll, ruhig auf einer Stelle stehen.
Was noch fehlt, ist OCR0A wieder zurückzusetzen:
1 | SIGNAL(TIMER0_COMPA_vect) |
2 | {
|
3 | int Stellung = 64; //nur noch 1.5ms! (0-128) |
4 | servo_counter++; //Zählt bis 10 -> max. 20ms |
5 | if (servo_counter == 1) |
6 | {
|
7 | PORTB = 0x00; //An, also Signal auf "high" |
8 | OCR0A = 249 - Stellung; //Wie lange auf High lassen? Min 1ms, max 2ms -> Min ~128, max ~255 |
9 | }
|
10 | if (servo_counter == 2) |
11 | {
|
12 | PORTB = 0xFF; //Ist die "High-Zeit" für Servo um -> Signal für die restlichen 18-19ms auf "low" |
13 | OCR0A = Stellung; |
14 | }
|
15 | if (servo_counter == 3) |
16 | {
|
17 | OCR0A = 249; |
18 | }
|
19 | if (servo_counter == 11) |
20 | {
|
21 | servo_counter = 0; //10ter Durchlauf -> von vorne (ca 20 ms sind rum). |
22 | }
|
23 | }
|
PS: 249 für genau 2ms pro Interrupt.
Jopp, danke, hatte ich ja gerade gemeint, aber auch ohne dem Fehler kommt kein richtiges Signal an, obwohl der Timer im Debugger nun verdammt genau ist. Das versteh ich irgendwie nicht. Ja, die 0.048ms hatte ich vorerst vernachlässigt, aber danke, ich habe nun "OCR0A = 249;" eingefügt.
Kristian G. schrieb: > Jopp, danke, hatte ich ja gerade gemeint, Sorry, bin beim Schreiben unterbrochen worden, und hatte daher etwas länger gebraucht (als ich anfing, war dein Beitrag noch nicht da). ;-) Dann checken, ob der Controller auch tatsächlich mit 8 MHz läuft, und nicht vielleicht doch noch mit 1 MHz.
Hab ich gecheckt, ich hab auch eben ein anderes Programm auf einem AtMega8 getestet, um zu sehen ob der Servo eine Macke hat: Nein, hat er nicht. Ich hab auch den AtMega168 gegen ein anderen getauscht, auch daran liegts nicht. Ein UART habe ich gerade eingefügt, der sendet ohne Probleme, also am Takt kanns nicht hängen.
Ich könnt mir so in den Aller wertesten beißen. -.- Ich habe überall PORTB = 0x00; mit PORTB = 0xFF; verdreht. Und ich zerbrech mir hier seit Tagen den Kopf und war schon kurz davor alles in den Kamin zu werfen. Ich danke euch allen vielmals und danke Gott dafür, das Dummheit doch nicht weh tut... =) Schönen sonnigen Sonntag noch.
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.