Forum: Mikrocontroller und Digitale Elektronik AVR Servo zittert extrem


von Windhund (Gast)


Angehängte Dateien:

Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@  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

von Windhund (Gast)


Angehängte Dateien:

Lesenswert?

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

von Uwe .. (uwegw)


Lesenswert?

volatile

von Zaphod B. (brezel) Benutzerseite


Lesenswert?

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.

von Windhund (Gast)


Angehängte Dateien:

Lesenswert?

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

von Zaphod B. (brezel) Benutzerseite


Lesenswert?

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

von Windhund (Gast)


Lesenswert?

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

von Müller-Lüdenscheid (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.