Guten Abend Ich beschäftige mich seid einigen Wochen damit einen Servo an meinen Atmega8 anzuschließen. Nach mehrmaligem durchlesen dieverser Tutorials zum Thema Timer und dem Studieren verschiedener fertiger Servocontroller hab ich jetzt den Grundansatz für meinen eigenen Servocontroller fertig. beim test nimmt der Servo auch tatsächlich die gewünschte Stellung ein, aber er zittert extremst. Der Servoarm bewegst sich bis zu 2mm hin und her und der Servo surrt dementsprechend laut. ich weiß nicht wo der Fehler liegen könnte, wenn ich die Zeiten mit _delay festleg Funktionirt es. Hoffentlich kann mir jemand von euch sagen wo der Fehler liegt. Vielen Dank im Vorraus Mit freundlichen Grüßen Windhund
@ Windhund (Gast)
>Hoffentlich kann mir jemand von euch sagen wo der Fehler liegt.
In deinem Konzept des Vorladens (was für ein schreckliches Wort) des
Timers. Nutzer Timer 1 im 16 Bit Modus und mach eine stinknormale PWM.
Die ist 100% jitterfrei und 0% CPU-lastig. Problem gelöst.
MFG
Falk
Ich habs auch mit dem 8 bit timer ans laufen bekommen :-) Das Problem war das ich dem Servo immer zu schnell ein neues Signal gegeben hab. Jetzt habe ich in zeile 41 aus der 2 ne 20 gemacht so das der servo seltener ein signal bekommt jetzt zittert er nicht mehr. :-) Jetzt möchte ich gerne das sich die Position auch ändert also das der Servo hin und her leuft. Kann vom prinzip her doch garnicht so schwer sein oder? Ich muss ja eigentlich nur immer den wert von vorlader[0] ändern. Aber der Servo nimmt nur die erste Position ein und bleibt in dieser. Kann sich ja nur um eine kleinigkeit handeln, aber ich find den fehler nicht... Währe toll wenn ihr mir nochmal helfen könntet. Mit freundlichen Grüßen Windhund
Uwe ... schrieb: > volatile dieses Problem gelöst...
1 | TCNT0 = vorlader[servo_index]; // set time for next interrupt |
2 | |
3 | servo_index++; |
4 | if(servo_index==20) |
5 | {
|
6 | servo_index=0; |
7 | }
|
..und dem nächsten vorgebeugt: Wenn "servo_index" Werte über 1 erreicht führt "vorlader[servo_index]" zu zufälligen Ergebnissen, da der Controller einfach auf die folgenden Speicherbereiche zugreift, als wäre das array lang genug... Noch liegen da wohl Nullen, aber wenn du mehr Variablen einführst gibt das nur noch bullshit. Noch ein kleiner Tipp: Die Vorgabe sagt ein Signalzyklus für den Servo dauert 20ms, wovon 1-2ms high sind. Also musst du nicht 20mal warten, sondern 20ms voll werden lassen, und dann die nächste Flanke senden. Musst du jetz nicht berücksichtigen, bei einem kleinen Testprojekt spielt das nicht die Rolle, einfach nur im Hinterkopf behalten, falls ein anderer Servo damit ein Problem hat.
Danke für den tipp mit volatile Auch dir danke für die hinweise brezel Hab versucht es so weit es geht umzusetzen Jetzt leuft er zwar hin und her aber leider zittert er jetzt auch wieder, zwar nur leicht aber er zittert halt^^ Hier ist mal mein aktueller Stand, hoffe ihr könnt mir nochmal helfen und mir sagen wieso der auf einmal wieder zittert. Mit freundlichen Grüßen Windhund
Hi, Das sieht doch schon mal viel ordentlicher aus :) "switch" braucht nicht für jeden Fall einen "case". Du kannst also getrost wie vorher nur auf 0 und 1 darin reagieren. Das, und dass du als Variablentyp "int" statt "uint8_t" benutzt, könnte die Verarbeitungszeiten in der ISR etwas hochtreiben, wodurch eine leichte Schwankung in die Länge der Pulse geraten kann. Wenn das alles nichts hilft, ändere den Systemtakt doch mal auf 8Mhz (den Prescaler natürlich mit), und prüfe ob sich ein Nachlassen des Zitterns bemerken lässt. Oh, da seh ich noch einen kleinen Flüchtigkeitsfehler ... Du darfst natürlich nur Werte zwischen 6 und 131 in den Vorlader packen, sonst sind die Pulse außerhalb der Grenze von 1-2ms! mfg brezel
Wahnsinn, uint8_t ist die Lösung, jetzt leufts komplett zitterfrei :-) Danke dir Hab das mit dem Werten was du grade erwähntest mal ausprobiert, also mein Servo hier macht Werte zwichen 0 und 175 so mit. Bei 0 ist der sogar noch nicht an seine untergrenze, schätze ich könnte den sogar auf -25 setzen aber das kann ja das Register nicht. Bei 175 ist das Servo aber wirklich an seiner Hardware Grenze, weiter geht nicht. Falls das Jemand interessiert ich habe zum testen ein HS-82MG von HITEC benutzt. Jetzt muss ich mich nur mal mit dem unterschied zwichen uint8_t und int beschäftigen damit ich das auch komplett versteh^^ Danke nochmal für eure hilfe
int = vorzeichenbehafteter integer = 2 Byte bei 8bit AVRs Also -32.768 bis 32.767 uint8_t = 1 Byte Also 0 bis 255 Auf 8Bit RISCs ist natürlich uint8_t schneller und einfacher berechnet als int... mit Compileroptimierungen kommt bei int dann sogar manchmal recht wildes raus...
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.