PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Servo mit Geschwindigkeitsregelung?



JeyBee
01.01.2009, 18:00
Moinsen,

Ich bins mal wieder. Ich habe ein kleines Problem. Zwar habe ich einen Sharp IR-Sensor auf ein herkömliches Servo montiert. Das Servo befindet sich wiederum auf meinem Roboterchassi.
Das Servo soll den Sensor immer von links nach rechts drehen, damit dieses einen möglichst grossen Bereich absten kann.
Das alles funtzt bislang auch so wie es soll. Jedoch ist der Sensor nicht mehr genau. Erst ein paar Cm vor der Mauer reagiert er. Ich habe natürlich die Werte variieren lassen, trotzdem musste ich feststellen, dass das Servo sich wohl zu schnell dreht, und das Licht, welches sich eigentlich mit Lichtgeschwindigkeit bewegt, nicht genug Zeit hat zum Sensor zurückzukommen.

Nun meine Frage: Kann man mit Bascom das Servo verlangsamen?



Mfg JeyBee

Dirk
01.01.2009, 19:12
Kann man mit Bascom das Servo verlangsamen?
Ja, das kannst du selbst programmieren, indem du einfach eine kleine Pause einlegst, bevor das Servo auf die nächste Position gestellt wird.

Gruß Dirk

JeyBee
01.01.2009, 21:04
Hey Dirk,

Kannst du mir mal auf die Sprünge helfen? Ich habe jetzt einfach "Servo(1) = x" hingemacht, und lasse alle 10ms die variable auf 150 hochzählen. Doch wie kann ich sie nun wieder so runterzählen, dass es eine Endlosschleife wird?



$regfile "m16def.dat"
$crystal = 16000000
$baud = 9600
$swstack = 16
$hwstack = 16
$framesize = 16

Dim B As Word
Dim X As Byte
Dim Y As Byte

Config Portd.4 = Output
Config Portd.5 = Output
Config Porta.4 = Output
Config Porta.5 = Output
Config Porta.6 = Output
Config Portc.7 = Output
Config Portc.6 = Output
Config Portc.5 = Output

M1 Alias Porta.5
M2 Alias Porta.6
M3 Alias Portc.6
M4 Alias Portc.5

Config Portb.0 = Output
Config Servos = 1 , Servo1 = Portb.0 , Reload = 10

Enable Interrupts

X = 0
Y = 0

Do

Servo(1) = X

1:
Incr X
Waitms 10

While X = 150
Decr X
Waitms 10
Wend

While X = 50
Incr X
Waitms 10
Goto 1
Wend

Loop

Besserwessi
01.01.2009, 21:46
Das Licht sollte imme rgenu zeit haben zurückzukommen. Es ist schon schwer so kurze Zeiten überhaupt zu messen, so wie in den Laserentfernungsmessern. Eher sind das Störungen über die Versorgungsspannung.

Zum hoch / runter zählen wäre ein FOR schleife wohl das richtige. Jeweils eine Schleife für hoch und eine für runter. Die Endloschleife dann ganz außen herum.

JeyBee
01.01.2009, 22:25
Kannst du mir dazu den Beispielcode schreiben? Ich habe gegoogelt und auch den Bascom Index benutzt, trotzdem verstehe ich diese For--Next Schleife nicht. Sorry


Mfg JeyBee

Dirk
01.01.2009, 22:35
Z.B.:

For X = 150 to 0 Step -1
Servo(1) = X
Waitms 10
Next X
For X = 0 to 150
Servo(1) = X
Waitms 10
Next X

JeyBee
01.01.2009, 23:52
Erst mal danke!
Ich habe den Code etwas modifiziert:


For X = 150 To 0 Step -1
Servo(1) = X
Waitms 10
Next X
For X = 0 To 150 Step 1
Servo(1) = X
Waitms 10
Next X


Jedoch bewegt sich das servo jetzt von links nach rechts, und legt dort eine 1 Sekunden Pause ein, nachher bewegt es sich wieder nach links, wovon es direkt nach rechts geht, um wieder eine Pause zu machen.

Ich konnte den Fehler bislang nicht finden.


Mfg JeyBee

Che Guevara
02.01.2009, 12:23
Hallo JeyBee,

x darf in diesem fall nicht null werden, da der bereich eines servos (UNGEFÄHR!!!) zwischen 50 und 150 liegt (die genauen werte sind immer verschieden und du solltest sie durch probieren herausfinden).

gruß
chris

oberallgeier
02.01.2009, 12:54
Hi JeyBee


... einen Sharp IR-Sensor auf ein ... Servo montiert ... drehen ... absten ...
... lasse alle 10ms ...Du brauchst genug Messezeit um ein gutes Resultat zu bekommen. Leider schreibst Du nicht, welchen Sharpsensor Du hast. WENN Du einen von der Familie GP2Dxxx hast, dann musst Du berücksichtigen, dass der 40ms für eine Messung benötigt - maximal also 25 Messwerte pro Sekunde. Das alte Lied: Datenblatt lesen. Da Dir aber mit Sicherheit (erstmal) nicht klar ist, wann der Servo die neue Position erreicht hat, musst Du etwa 80 ms auf das neue Ziel halten.


... das Servo sich wohl zu schnell dreht, und das Licht, welches sich eigentlich mit Lichtgeschwindigkeit bewegt, nicht genug Zeit hat zum Sensor zurückzukommen ...Der Sharp ist KEIN optisches Echolot!

Wieso 80 ms!?!? Nehmen wir an, Du verfährst gerade den Sensor und kommst an der neuen Position an, etwa 1..2 ms NACHDEM die aktuelle Messung gestartet wurde. Nun hatte also die laufende Messung noch die Verstellung mitbekommen und wird dadurch verfälscht. Du musst also (das ist die "schlimmste" Annahme) warten, bis eine neue Messung angefangen ist und abgeschlossen wurde - also 39 ms warten wegen der verfälschten Messung und danach noch mal 40 ms für eine komplette Messung bis der neue Wert da ist. Danach Wert auslesen und weiter gehts. Bei Deiner Methode sind 10 saubere Messwerte pro Sekunde ein guter Wert. Wenn Du mehr Verstellungen machst, sind einige Messungen nur . . . . . . Schrott.

Ähnliches hatte ich an meinem Dottie (https://www.roboternetz.de/phpBB2/viewtopic.php?p=390196#390196)gemacht (siehe Strohhalmsensorindikator), um meine irDME´s zu justieren und zu kontrollieren.

JeyBee
02.01.2009, 16:39
Moin,

Ahso, danke Oberallgeier. Also soll ich einfach nur drei Positionen messen? Links, etwas warten zum messen, mitte, etwas warten zum messen, rechts, etwas warten zum messen....?
Weil bisslang habe ich andauert gemessen, und das servo einfach durchdrehen lassen, ganz unabhängig.

P.S. ja, ich verwende den GP2D120J00F Sensor.
P.P.S. Das Programm funktioniert soweit. Danke.


Mfg JeyBee

oberallgeier
02.01.2009, 17:38
Hallo JeyBee,


... Also soll ich einfach nur drei Positionen messen ...Das musst Du schon selbst entscheiden. Ich weiß nicht, mit welcher Auflösung Du die Umgebung absuchen willst. Diese drei Positionen waren eigentlich nicht die message.

Du sollst, egal wieviel Positionen Du anfährst, eben die erforderliche Zeit warten - sonst misst Du Mist *ggggg*. Möglicherweise kennst Du (auch) die Störempfindlichkeit der Sharpfamilie noch nicht - aber es gibt Möglichkeiten zum Entstören. (https://www.roboternetz.de/phpBB2/viewtopic.php?t=37624)

Im Übrigen gibt die Suchfunktion (obere Statuszeile, dritter Link : •Suchen• ) ne ganze Menge her, hier drei Beispiele, die sich mit dem Sharp, dem Scannen der Umgebung und entsprechenden Landkarten beschäftigen:
https://www.roboternetz.de/phpBB2/viewtopic.php?t=36647
https://www.roboternetz.de/phpBB2/viewtopic.php?t=11848
https://www.roboternetz.de/phpBB2/viewtopic.php?p=15756#15756

Du musst halt selber mal intensiv suchen. Im Übrigen: viel Erfolg

JeyBee
02.01.2009, 18:13
Danke für die Links, oberallgeier.

Ich habe mich jetzt dazu entschieden, den Sensor auf dem Servo immer auf 0 (100) zu stellen. Sobald der Sensor aber etwas "sieht", soll der Roboter stehen bleiben, auf beide seiten den Servo schwenken (50-150), zwei messerte nehmen, und beide vergleichen, bei dem der weniger hoch ist, soll der Roboter hinfahren. Also quazi soll der Roboter den "Besten Weg" finden. Ich weiss, die Sensoren sind nur auf 30cm ausgelegt, trotzdem soll es dem Roboter helfen, sich nicht in eine Ecke zu verfahren.

Ich habe das Programm geschriben 8). Jedoch funktioniert das mit dem Servo noch nicht so ganz. Es schlägt nur auf eine Seite aus.

Der Sensor ist bei der Servoposition "100" nach gerade aus gerichtet.

Könntest du mal bitte kruz drüber schauen? *Keks gib* ;)



$regfile "m16def.dat"
$crystal = 16000000
$baud = 9600
$swstack = 16
$hwstack = 16
$framesize = 16

Dim A As Word
Dim B As Word
Dim C As Word
Dim X As Word
Dim Y As Word
Dim Z As Word

Config Portd.4 = Output
Config Portd.5 = Output
Config Porta.4 = Output
Config Porta.5 = Output
Config Porta.6 = Output
Config Portc.7 = Output
Config Portc.6 = Output
Config Portc.5 = Output
Config Portb.2 = Output

M1 Alias Porta.5
M2 Alias Porta.6
M3 Alias Portc.6
M4 Alias Portc.5

Config Servos = 1 , Servo1 = Portb.2 , Reload = 10
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1

Enable Interrupts

Servo(1) = 100
Wait 1

Do

Pwm1a = 64
Pwm1b = 64

A = Getadc(1)
B = Getadc(2)
C = Getadc(3)

If A > 250 Then
Gosub Brems
Waitms 500
Gosub Rueck
Waitms 200
Gosub Rueckr
Waitms 400
Else
Gosub Vor
End If

If B > 250 Then
Gosub Brems
Waitms 500
Gosub Way
Gosub Rueck
Waitms 200
Gosub Rueckl
Waitms 400
Else
Gosub Vor
End If


If C > 250 Then
Gosub Brems
Waitms 500
Gosub Rueck
Waitms 200
Gosub Rueckr
Waitms 400
Else
Gosub Vor
End If

Waitms 40


Vor:
M1 = 0
M2 = 1
M3 = 0
M4 = 1
Return

Rueck:
M1 = 1
M2 = 0
M3 = 1
M4 = 0
Return

Brems:
M1 = 1
M2 = 1
M3 = 1
M4 = 1
Return

Rueckr:
M1 = 1
M2 = 0
M3 = 0
M4 = 0
Return

Rueckl:
M1 = 0
M2 = 0
M3 = 1
M4 = 0
Return

Vorr:
M1 = 0
M2 = 1
M3 = 0
M4 = 0
Return

Vorl:
M1 = 0
M2 = 0
M3 = 0
M4 = 1
Return

Way:
Servo(1) = 100
Waitms 100
X = Getadc(2)
Waitms 100
Servo(1) = 150
Y = Getadc(2)
Waitms 100
Servo(1) = 50
Waitms 300
Z = Getadc(2)
Waitms 100

If Y > Z Then
Gosub Rueckr
Waitms 500
Gosub Brems
Waitms 300
Gosub Vor
End If

If Y < Z Then
Gosub Rueckl
Waitms 500
Gosub Brems
Waitms 300
Gosub Vor
End If

Loop




Mfg JeyBee

oberallgeier
02.01.2009, 18:36
Ach JeyBee,

das mit dem Keks ist nett gedacht, ich würde das sogar ohne Keks machen. Blos sprech ich kein Bascom - da bin ich leider keine Hilfe. Selbst mein C ist eher Cäh.

Vielleicht könnte Dir mein Lösungsansatz etwas helfen (ja, ich weiß, man lobt immer die eigenen Ideen/Kinder/Töchter), der auf dem Dottie zu sehen ist: einfache, nicht sehr genaue Sensoren geben "erste" Hinweise, (https://www.roboternetz.de/phpBB2/viewtopic.php?p=363793#363793) der Sharp macht die Feinarbeit. Dabei müssen die Sensoren natürlich nicht "von oben herab" schauen - einfach nach vorne geht auch. Diese Blindenstockphilosophie ist eben (m)eine etwas spezielle Geschichte. Die ganze Geschichte fängt ungefähr hier (https://www.roboternetz.de/phpBB2/viewtopic.php?t=40507) an.

ikarus_177
02.01.2009, 20:10
Hi,

hab mir dein Programm auch mal angesehen.

Mir ist aufgefallen, dass die Endlosschleife (Do...Loop) über den ganzen Programmcode geht auch über die Unterfunktionen, die mit "gosub" angesprochen werden. Ich würde die Schleife nur über die "Aufrufe" der Unterfunktionen stellen, also in etwa so:


$regfile "m16def.dat"
$crystal = 16000000
$baud = 9600
$swstack = 16
$hwstack = 16
$framesize = 16

Dim A As Word
Dim B As Word
Dim C As Word
Dim X As Word
Dim Y As Word
Dim Z As Word

Config Portd.4 = Output
Config Portd.5 = Output
Config Porta.4 = Output
Config Porta.5 = Output
Config Porta.6 = Output
Config Portc.7 = Output
Config Portc.6 = Output
Config Portc.5 = Output
Config Portb.2 = Output

M1 Alias Porta.5
M2 Alias Porta.6
M3 Alias Portc.6
M4 Alias Portc.5

Config Servos = 1 , Servo1 = Portb.2 , Reload = 10
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1

Enable Interrupts

Servo(1) = 100
Wait 1

Do

Pwm1a = 64
Pwm1b = 64

A = Getadc(1)
B = Getadc(2)
C = Getadc(3)

If A > 250 Then
Gosub Brems
Waitms 500
Gosub Rueck
Waitms 200
Gosub Rueckr
Waitms 400
Else
Gosub Vor
End If

If B > 250 Then
Gosub Brems
Waitms 500
Gosub Way
Gosub Rueck
Waitms 200
Gosub Rueckl
Waitms 400
Else
Gosub Vor
End If


If C > 250 Then
Gosub Brems
Waitms 500
Gosub Rueck
Waitms 200
Gosub Rueckr
Waitms 400
Else
Gosub Vor
End If

Waitms 40


Loop


Vor:
M1 = 0
M2 = 1
M3 = 0
M4 = 1
Return

Rueck:
M1 = 1
M2 = 0
M3 = 1
M4 = 0
Return

Brems:
M1 = 1
M2 = 1
M3 = 1
M4 = 1
Return

Rueckr:
M1 = 1
M2 = 0
M3 = 0
M4 = 0
Return

Rueckl:
M1 = 0
M2 = 0
M3 = 1
M4 = 0
Return

Vorr:
M1 = 0
M2 = 1
M3 = 0
M4 = 0
Return

Vorl:
M1 = 0
M2 = 0
M3 = 0
M4 = 1
Return

Way:
Servo(1) = 100
Waitms 100
X = Getadc(2)
Waitms 100
Servo(1) = 150
Y = Getadc(2)
Waitms 100
Servo(1) = 50
Waitms 300
Z = Getadc(2)
Waitms 100

If Y > Z Then
Gosub Rueckr
Waitms 500
Gosub Brems
Waitms 300
Gosub Vor
End If

If Y < Z Then
Gosub Rueckl
Waitms 500
Gosub Brems
Waitms 300
Gosub Vor
End If

Return


Keine Ahnung, ob das zur Lösung des "Ausschlagproblems" beiträgt, mir ist es nur ins Auge gestochen ;-)


Viele Grüße

JeyBee
02.01.2009, 21:48
So, jetzt funktioniert soweit alles. Ich brauche jetzt nur noch eine Richtige Spannungsversorgung etc.

Wenn's interessiert, hier der Code:

$regfile "m16def.dat"
$crystal = 16000000
$baud = 9600
$swstack = 16
$hwstack = 16
$framesize = 16

Dim A As Word
Dim B As Word
Dim C As Word
Dim X As Word
Dim Y As Word
Dim Z As Word

Config Porta.4 = Output
Config Porta.5 = Output
Config Porta.6 = Output
Config Portc.7 = Output
Config Portc.6 = Output
Config Portc.5 = Output
Config Portb.2 = Output

M1 Alias Porta.5
M2 Alias Porta.6
M3 Alias Portc.6
M4 Alias Portc.5

Config Servos = 1 , Servo1 = Portb.2 , Reload = 10
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
Config Timer1 = Pwm , Pwm = 10 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1

Enable Interrupts

Servo(1) = 100
Wait 1

Do

Pwm1a = 64
Pwm1b = 64

A = Getadc(1)
B = Getadc(2)
C = Getadc(3)

If A > 200 Then
Gosub Brems
Waitms 500
Gosub Way
Waitms 100
Else
Gosub Vor
End If

If B > 200 Then
Gosub Brems
Waitms 500
Gosub Way
Waitms 100
Else
Gosub Vor
End If

If C > 200 Then
Gosub Brems
Waitms 500
Gosub Way
Waitms 100
Else
Gosub Vor
End If

Loop

Vor:
M1 = 0
M2 = 1
M3 = 0
M4 = 1
Return

Rueck:
M1 = 1
M2 = 0
M3 = 1
M4 = 0
Return

Brems:
M1 = 1
M2 = 1
M3 = 1
M4 = 1
Return

Rueckr:
M1 = 1
M2 = 0
M3 = 0
M4 = 0
Return

Rueckl:
M1 = 0
M2 = 0
M3 = 1
M4 = 0
Return

Vorr:
M1 = 0
M2 = 1
M3 = 0
M4 = 0
Return

Vorl:
M1 = 0
M2 = 0
M3 = 0
M4 = 1
Return

Way:
Servo(1) = 150
Waitms 300
Y = Getadc(2)
Waitms 300
Servo(1) = 50
Waitms 300
Z = Getadc(2)
Waitms 300

If Y > Z Then
Gosub Vorl
Waitms 500
Gosub Brems
Waitms 300
Gosub Vor
End If

If Y < Z Then
Gosub Vorr
Waitms 500
Gosub Brems
Waitms 300
Gosub Vor
End If
Servo(1) = 100
Return

End


Danke an Alle.


Mfg JeyBee