PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servo mit Pulseout steuern



BlaueLed
30.06.2008, 19:46
Hallo,

ich habe ein Servo mit dem Servo befehl angesteuert. Klappt soweit, aber ich verbrauche dadurch ja einen Timer. Jetzt habe ich versucht das Servo mit dem Pulseout befehl zu steuern. Aber das klappt nicht. Ich kann das Servo nur in 1 Richtung fahren.



Pulseout Portc, 4, 30
waitms 20


Egal welchen wert ich einsetze komme ich nicht in die andere Richtung. Könnte mir das mal bitte jemand erklären. Stehe da voll auf dem Schlauch.
Danke

mfg Kay

Michael
30.06.2008, 22:24
Hallo BlaueLed,


Egal welchen wert ich einsetze komme ich nicht in die andere Richtung. Könnte mir das mal bitte jemand erklären. Stehe da voll auf dem Schlauch.
Danke
welche Werte hast du denn bisher ausprobiert?

Vielleicht kannst du noch den Rest des Programms posten?
Manchmal steckt der Fehler ganz woanders.

Gruß, Michael

BlaueLed
01.07.2008, 11:15
Hallo Michael,

ich habe werte von 10 - 1000 ausprobiert, aber der Servo dreht sich immer nur in die selbe richtung. Der Rest vom Programm läuft ja, ist ja nur die Chip und Portdefinition drin. Mehr habe ich im Programm nicht stehen.

edit :

habe im internet schon ein paar beispiele gefunden. Die habe ich gleich ausprobiert. Sieht folgendermaßen aus:



for i = 1 to 30
pulseout Portc,4,i
waitms 20
next i

for i = 30 to 1 step -1
pulseout Portc,4,i
waitms 20
next i




bei der ersten schleife läuft er in eine Richtung. Bei der zweiten aber in die gleiche. Also entweder ich verstehe den Pulseout befehl nicht richtig oder ich versteh mein servo nicht.

mfg Kay

MeckPommER
01.07.2008, 11:39
Laut Hilfe von Bascom liefert pulseout einen Puls der Länge i=1µs wenn der Controller auf 4 MHz läuft.

Wenn dein Comtroller also mti 4MHz läuft und du den Wert 1000 nutzt, dann ist der Puls grade mal eine Millisekunde lang. Die Pulsdauer sollte zwischen einer und zweil Millisekunden lang sein, also musst du Werte zwischen 1000 und 2000 benutzen (sofern dein µC auf 4MHz läuft, ansonsten natürlich anzupassen)

Ausserdem liefert Pulseout nicht eine logische 1 und geht dann wiederauf 0, sondern toggelt den betreffenden Portpin. Ist also der Port vor dem Befehl auf logisch 1, dann liefert Pulseout einen 0-Impuls und geht danach wieder auf logisch 1.

Einfach mal das ganze Programm posten, dann bekommen wir das schon hin :-)

Gruß MeckPommER

P.S.: wenn es um exakte Servoansteuerungen geht, wirst du um die Verwendung eines Timers nicht herumkommen.

Michael
01.07.2008, 12:08
Hallo BlaueLED,

ja, Meck hat es ja geschrieben, das mit den Mikrosekunden, also einfach mal rechnen.
Ich hatte dich aber nach dem Rest des Programmes gefragt, um z.B. zu sehen, mit welcher Quarzfrequenz du arbeitest.

Gruß, Michael

BlaueLed
01.07.2008, 16:04
Hi,

vielen Dank für eure Hilfe. Ich benutze einen 16 Mhz Quarz. Werde das gleich ausprobieren.

mfg Kay

BlaueLed
01.07.2008, 20:05
Hi,

habe es probiert und es klappt. Mit den Werten 900 für den linken Anschlag und 4500 für den rechten Anschlag. Wenn ich die werte einzeln aufrufe, dann gehts. Wenn ich in einer Schleife die werte aufrufe dann nicht. Hier mal mein Code :



'--- Chip ---
$regfile = "m8def.dat"
$crystal = 16000000

'--- Ports ---
Config Portc.5 = Output
Config Pinc.4 = Output
Config Pinb.1 = Input

Portc.4 = 0

'--- Alias ---
Led Alias Portc.5

'--- Werte ---
Const Maxi = 4500
Const Mini = 900

'--- Dim ---
Dim I As Word

'--- Main ---

Do

Wait 1

Portc.4 = 0
Pulseout Portc , 4 , Mini
Portc.4 = 0

Wait 1

Portc.4 = 0
Pulseout Portc , 4 , Maxi
Portc.4 = 0

Loop

da zuckt das servo nur rechts und links. Liegt es daran, das die Pulseout routine fertig ist, bevor das servo am Anschlag ist und dann wait 1 das servo unterbricht ?

mfg Kay

MeckPommER
01.07.2008, 20:33
Du erzeugst nur einen puls und wartest dann eine sekunde, das geht nicht. die pulse müssen alle 20ms kommen.

ändere das programm dahingehend, das die pulse jeweils 50 mal mit einer 18ms-pause dazwischen kommen, das dürfte klappen.

BlaueLed
02.07.2008, 06:25
Hi MeckPommER,

vielen Dank für die Antwort. So klappts nun :



'--- Chip ---
$regfile = "m8def.dat"
$crystal = 16000000

'--- Ports ---
Config Portc.5 = Output
Config Pinc.4 = Output
Config Pinb.1 = Input

Portc.4 = 0

'--- Alias ---
Led Alias Portc.5

'--- Werte ---
Const Maxi = 4550
Const Mini = 900

'--- Dim ---
Dim I As Word

'--- Main ---

Do


For I = 1 To 20

Portc.4 = 0
Pulseout Portc , 4 , Mini
Waitms 20
Portc.4 = 0

Next I

Wait 1

For I = 1 To 20

Portc.4 = 0
Pulseout Portc , 4 , Maxi
Waitms 20
Portc.4 = 0

Next I

Wait 1

Loop


mfg Kay

MeckPommER
02.07.2008, 07:59
Hi BlaueLed,

es mag auf den ersten Blick klappen, allerdings hat dein Programm noch 2 kleine Schönheitsfehler:

- Servos erwarten alle 20ms einen Impuls. Die meisten Servos können sehr gut mit kürzeren Abständen umgehen, einige mögen aber längere Abstände absolut nicht.
Wenn du nun einen Puls von 2ms sendest und nach jedem Puls 20ms wartest, kommen die Pulse eben nicht alle 20ms, sondern alle 22ms. Deshalb hatte ich auch vorgeschlagen, eine Pause von nur 18ms zu nehmen.

- momentan stellt sich dein Servo auf eine Position ein, nach 2 Sekunden gehts in die andere Position u.s.w.
Problem ist, das dein Servo in der "wait 1" Zeit absolut kraftlos wird, da keine Stellimpulse mehr eintreffen. Sollte der Servo also so verwendet werden, das er in seiner jeweiligen Position unter mechanischer Last ist, wird er diese nicht halten können.

Das ist just auch der Grund, warum häufig Timer verwendet werden und Servos über einen Interrupt gesteuert werden.

Gruß MeckPommER

BlaueLed
02.07.2008, 08:43
Hi,

ich verstehe was du meinst. Werde die 20ms durch die 18ms ersetzen. Das Servo steht unter keiner mechanischen last. Es wird auf dem Servo ein SRF05 installiert und dieser wird dann vom servo gedreht.

mfg Kay

Addyfly
04.07.2008, 09:20
mal ne kurze frage am rande:
es steht ja geschrieben, das bei 4 mhz ein pulseout befehl eine länge von 1 us
ausgibt also sind dann 1500us 1,5ms also die mitte des servos. wie rechnet man das dann eigentlich um wenn man z.b. 12 mhz hat und dann auch eine länge von 1500us erzeugen will?
Hier habe ich mal eben ein kleines programm geschrieben, mit dem ich ein servo mit hilfe von zwei tastern verstellen kann... kann man das so lassen? ich kann es leider erst morgen testen da mein atmega8 noch nicht da ist^^.
und noch ne kleine anfängerfrage: kann man für eine variable ein definitionsbereich einstellen?

vielen dank, mfg adrian


$regfile = "m8def.dat"
$crystal = 4000000

Config Portc.0 = Output
Config Pinc.1 = Input
Config Pinc.2 = Input
Dim I As Word
Up Alias Pinc.1
Down Alias Pinc.2
I = 1500

Portc.0 = 0

Wait 1

Pulse:
Pulseout Portc , 0 , I
Waitms 18
If Up = 1 Then
I = I + 50
End If
If Down = 1 Then
I = I - 50
End If

Goto Pulse

MeckPommER
04.07.2008, 09:44
Wenn du bei 4 MHz 1500 einstelle musst, um 1,5ms zu bekommen, dann musst du bei 12 MHz:

1500/4*12 einstellen.

Vorrausgesetzt das Pulseout absolut Taktabhängig ist, was ich vermute, da kein Timer verwendet wird.

Was dein Programm angeht, so müßte es funktionieren. Kommt aber auch darauf an, wie du die Taster beschaltet hast. Gehen die von den Input-Pins an +? Dann solltest du besser einen Pulldown-Widerstand einfügen. Du kannst die Taster natürlich auch an - gehen lassen und die internen Pullups verwenden. Dann müßten die if-abfragen allerdings lauten "if up=0 then".
Was den Definitionsbereich angeht ist dies nur über dim in gewissen Grenzen möglich (Byte, Integer, Word, etc.) du solltest daher noch ein dein Programm einbauen, das z.B. I nur dann erhöht wird, wenn der Wert von I nicht schon zu hoch ist und nur dann vermindert wird, wenn der Wert keinen kleineren Impuls als 1ms erzeugt.
Damit beugst du einem an seine Grenzen anschlagenden Servo vor.

Gruß MeckPommER

Addyfly
04.07.2008, 09:49
Hey super, vielen dank für die schnelle antwort. also das mit dem pullup/pulldown ist mir auch noch aufgefallen...das werde ich also noch ändern. Und vielen dank für den tipp mit dem, dass I einen bestimmten wert nicht über-/unterschreiten darf!

Viele Grüße.... Adrian


p.s: Ich werde das programm heut oder morgen mal testen und hier dann bericht erstatten.