PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Tiny45 8-Zeiler und Servozittern



msocito
02.09.2009, 21:02
Moin zusammen,

ich mach's kurz: Ich möchte mir aus einem Tiny45 einen 180° Servostretcher schnitzen. Das Teil soll also statt den üblichen +- 60° eben +- 90° aus dem Servo holen. RC Puls Eingang am PinB4, Ausgang Servo am PinB3.
So weit so gut. Habe also diverse Tests mit Bascom durchgeführt und das hat eigentlich alles funktioniert, aber ich bekomme einfach das Servozittern nicht weg. Da das Servo unter einer Kamera hängt ist das Zittern sehr lästig. Habe dann also meinen gesamten Code zusammengeschrumpft, so daß nur noch eine ganz banale Abfrage über Timer und eine Ausgabe über Pulseout stattfindet. Und ... es zittert immer noch.
Werde den Verdacht nicht los, daß mir die Interruptroutine hier reinspuckt.

Vielleicht hat ja jemand eine gute Idee (bitte kein Assembler oder C oder Hinweise auf fertige Teile - will es selbst bauen).

Vielen Dank schonmal im voraus

Hier das Cödchen:



$regfile = "ATtiny45.DAT"
$crystal = 8000000

$hwstack = 32
$swstack = 10
$framesize = 40

Dim Scalefactor As Integer
Scalefactor = 33
Dim Timercount As Integer

Config Portb.3 = Output
Config Portb.4 = Input
Portb.4 = 1 ' Pullup aktiv
Gimsk.5 = 1 ' PinChange enable
Pcmsk = &B00010000 ' PB4 change aktiv
Tccr1 = &B00001000 ' Prescale 128

On Pcint0 Readrctime

Portb.3 = 0

Enable Interrupts


Do

Loop

'-----------------------------------------------------------------------
Readrctime:
If Pinb.4 = 1 Then
Tcnt1 = 0
Else
Timercount = Tcnt1
Timercount = Timercount * Scalefactor
Portb.3 = 0
Pulseout Portb , 3 , Timercount
End If
Return
'------------------------------------------------------------------------

End

Michael
02.09.2009, 22:14
Hallo msocito,

dein Programm mißt die Pulszeit über einen externen Interrupt mit Timer1.
Der Vorteiler beträgt 128.
kommt jetzt ein Puls von 1,5ms Länge herein, dann macht das (8000000/128=) 62500*0,0015 = 93 Takte.
Diesen Wert mal 33 = 3093.
Das ist der Wert für Pulsout.
In der Hilfe steht bei Pulsout, daß der Wert für 4MHz mit 10µs zu multiplizieren sei, für 8MHz gilt also die Hälfte, 5µs.
also 3093 * 5 µs = gut 15ms!

Miß doch mal mit dem Oszi nach.

Btw:Servozittern kommt auch manchmal durch unstabile Versorgung.

Gruß, Michael

msocito
02.09.2009, 23:09
Hallo Michael,

danke erst mal für Deine Antwort.
Hab mal eben das Oszi drangehängt:
Es gehen bombenstabile 1,5 ms rein und 1,5 ms + Zittern gehen raus.
Das Zittern ist auf dem Oszi eher klein, aber das Servo merkt es dennoch.
Meine Stromversorgung ist ein 6A Statron Labornetzteil - also was Gutes.
Habe mal spaßeshalber das Servo an eine zweite 5V Quelle gehängt - leider dasselbe Ergebnis.

Hatte gestern noch ein paar Tests nur mit Pulseout gemacht.
Dabei habe ich diverse Servopositionen angefahren und gehalten.
Dabei war kein Zittern zu erkennen.

Es scheint also irgendwie mit der Timerabfrage zusammenzuhängen.

Das ganze Spiel habe ich auch schon mit Pulsein/Pulseout probiert.
Da zitterte das Servo ebenfalls.


Das Servo direkt am Empfänger ist außerdem stabil.


Mir gehen echt die Ideen aus ...

Gruß Msocito


P.S. Ich benutze Bascom Version 1.11.9.5

Michael
02.09.2009, 23:34
Hallo msocito,

hmm, dann stimmt meine Rechnung (oder die Bascom Hilfe) nicht.

Ich habe das Gefühl, der Fehler steckt in der zu niedrigen Timerfrequenz.
Bei 62500 kHz dauert ein Tick 16µs. Für 1,5 ms Pulsdauer bekommst du also einen Rückgabewert von 1,488 oder 1,504 ms.
Über den ganzen Bereich von 1-2ms hast du nur 64 Schritte.
Den Pulsout-Befehl im Interrupt würde ich auch nicht machen.

Warum erfaßt du den Puls nicht mit voller Timergeschwindigkeit?
Ich würde über den externen Interrupt die Pulse mit maximaler Genauigkeit holen, im Hauptprogramm berechnen und über Timer1 Interrupt rausschicken.

Gruß, Michael

Bammel
03.09.2009, 16:15
hier im wiki gibt es nen super bespiel für 4 servos. der funktioniert astrein. mit ein wenig anpassen geht das auch mit dem -/+ 90° dabei hatte ich nie ein zittern außer das was von meinen billigservos kam.

msocito
03.09.2009, 22:59
Hi Michael,

in meiner Bascom Hilfe steht 1ms für das Pulseout. Also ist die Welt wieder heile :-)

Interessanter Ansatz mit dem Prescaler.
Hab mal ein wenig rumexperimentiert:
Bei größerem Prescaler wird das Zittern heftiger, bei kleinerem besser.
Das stützt Deine Theorie.
Jedoch wird unter 64 der Arbeitsbereich vom Servo eingeschränkt.

In meinem ursprünglichen Code war die Pulseout Routine auch im Main Progammteil und nicht in der Interruptroutine - hatte aber keinen Unterschied gemacht.

Hab dann mit dem aktuellen Code noch einen Test gemacht und immer den gleichen Wert (3050) über Pulseout rausgeschickt, während der Interrupt die Daten nur nutzlos sammelte.
Da stand das Servo still. Offenbar ist es wirklich die Pulslängenmessung über T1, welche variable Werte abliefert ...

@Bammel:
Das Beispiel im WIKI kenne ich. Ist allerdings für den M32 geschrieben und somit nicht einfach auf den Tiny 45 umzulegen. Andere Taktfrequenzen/Timer...

Bammel
04.09.2009, 08:28
ja das problem hatte ich auch aber durch herumprobieren hab ich das auch auf meine atmega8 mit ebenfalls 8mhz zum laufen gebracht.