Archiv verlassen und diese Seite im Standarddesign anzeigen : Servoposition herausfinden?
jagdfalke
16.06.2005, 21:47
Hallo,
das Ziel für mein Programm sieht so aus:
Ich will ein Sub programmieren, dem ich die Servonummer und die Endposition geben kann und es dann den Servo in die Position bringt. Allerdings soll das langsam und nicht so ruckartig passieren wie wenn ich
Print #2 , "#s" ; Chr(1) ; Chr(100)
schreiben würde. Ich will also die For-Next-Schleife nur so oft durchlaufen wie die Differenz zwischen Sollposition und Istposition beträgt. Also muss ich zum einen die Istposition irgendwie auslesen und dann noch den Betrag der Differenz ausrechnen.
Und hier fehlts mir an Kenntnis über sowohl AVR als auch die Sprache Bascom. Kann jemand helfen?
mfg
jagdfalke
Ein Servo ist kein Schrittmotor der Schritte verlieren kann.
Deswegen kannst du bei einem Servo eigentlich davon ausgehen, dass er sich genau in der Position befindet die du angesteuert hast (natürlich mit ein paar ms Zeitverzögerung) und brauchst normalerweise keine Rückmeldung.
Ausnahme ist, wenn der Servo irgendwie mechanisch dran gehindert wird die Position die du ansteuerst einzunehmen. Davon gehen normale Servos aber ziemlich schnell kaputt, deshalb solltest du das besser vermeiden.
jagdfalke
16.06.2005, 22:18
Ja schon klar, aber ich will ja nicht dass sie sich so schnell bewegen wie sie können sondern langsamer. Dafür brauche ich eine For-Next-Schleife.
Bsp:
LOOP:
Call Rnb_servo(1, 100)
wait 2
Call Rnb_servo(1, 150)
Goto LOOP
Sub Rnb_servo(byval Servonummer As Byte , Byval Position As Byte)
Print "#s" ; Chr(servonummer) ; Chr(position)
End Sub
In diesem Beispiel würder er sich so schnell wie möglich zu 100 dann nach 2 Sekunden zu 150 bewegen.
Nächstes Beispiel:
LOOP:
Call Rnb_servo(1, 100)
wait 2
Call Rnb_servo(1, 150)
Goto LOOP
Sub Rnb_servo(byval Servonummer As Byte , Byval Position As Byte)
For I = 0 to Position
Print "#s" ; Chr(servonummer) ; Chr(position)
waitms 10
Next I
End Sub
Nach dem ersten Call-Befehl würde alles so klappen wie es soll, vorrausgesetzt der Servo befindet sich auf Position 0. Danach ist er auf Position 100. Beim zweiten Call-Befehl würde er plötzlich auf Position 0 springen und von da aus langsam auf 150.
Was ich will ist den plötzlichen Sprung auf 0 zu vermeiden.
mfg
jagdfalke
du müsstest dir imemr merken auf welche position du debn servo beim lezten mal gestzt hast und dann dort weitermachen...
jagdfalke
16.06.2005, 22:39
man kann die position also nicht irgendwie vom servo auslesen. also isses ein Programmierproblem.
wenn ich jetzt ein sub schreibe sind da variablen die im Main-Teil deklariert wurden nicht verfügbar. Kann man in Bascom so eine Art Globale Variable deklarieren?
Alle Variablen sind in Bascom global. Aber vielleicht solltets du erst mal etwas mehr in einem Bascom Buch blättern, erspart die viele Fragen
jagdfalke
16.06.2005, 23:21
wo finde ich das denn?
man kann die position also nicht irgendwie vom servo auslesen. also isses ein Programmierproblem.
Ja. Aber ich würde es nicht unbedingt als Problem, sondern eher als grosse Vereinfachung ansehen
wenn ich jetzt ein sub schreibe sind da variablen die im Main-Teil deklariert wurden nicht verfügbar.
Bei allen Programmiersprachen die ich kenne sind Variablen die ausserhalb irgendwelcher Routinen direkt im Hauptblock des Programms definiert werden innerhalb aller Subroutinen und Funktionen verfügbar.
Kann man in Bascom so eine Art Globale Variable deklarieren?
Braucht man nicht. Man kann aber umgekehrt eine Variable innerhalb einer Funktion oder Routine als "local" deklarieren.
wo finde ich das denn?
Mit ein bischen suchen sicherlich irgendwo in der Online-Hilfe. Einfach mal ausprobieren, kann aber eigentlich auch nicht länger als 3 Minuten dauern, wenn er eine Variable nicht kennt wird der Compiler es dir schon sagen.
Ich finde es schon gut, wenn ein Servokontroller ein bißchen Feedback liefert. Aber die effektive Position des Servos kennt der ohne Zugriff auf das Poti ja schließlich auch nicht. Was soll er mir also erzählen ? Die Position, wo ich das Servo gern hätte, hat er ja eh von mir, und das eine Byte bring' ich allemal unter, oft brauch ich es ja ohnehin für andere Entscheidungen. da werd' ich es mir nicht immer extra holen.
Wenn ich eine SPeed-parameter mitgeben kann, DANN ist es schon praktisch, wenn ich eine (aktive) Meldung bekomme, daß das Servo nun tatsächlich dort ist. Aber das erfordert ein Kommunikations-Protokoll.
BasCom:
definierst du mit
DIM Name as Type
dann ist das global
in einer SUb oder Function kannst du nach dem function-header genauso schreiben
LOCAL Name as Type
Dann gilt das nur in der Sub (Function), braucht also nicht unique zu sein.
"Help"-->Index--> LOCAL
jagdfalke
17.06.2005, 14:13
Also erstmal danke für eure Antworten. Ich hab jetzt schon einen Teil des Programs geschrieben, komm aber nicht weiter (wieder durch unzulängliche Kenntnis der Sprache Bascom):
Im folgenden Quellcode wird ein Servo (Servotreiber im Copozessor) von verschiedenen Positionen zu nächsten in langsamen Schritten bewegt:
$regfile = "m32def.dat"
Declare Sub Rnb_servo(byval Servonummer As Byte , Byval Go_to_pos As Byte)
$crystal = 8000000 'Quarzfrequenz
$baud = 9600
Dim Curr_pos As Byte
Dim Go_to_pos As Byte
Dim Servo_counter As Byte
Dim Steps_to_go As Byte
Call Rnb_servo(1 , 0)
Curr_pos = 0
Wait 5
'################################################# ##############################
Hauptschleife:
Call Rnb_servo(1 , 100)
Wait 3
Call Rnb_servo(1 , 150)
Wait 3
Call Rnb_servo(1 , 50)
Wait 3
Goto Hauptschleife
Sub Rnb_servo(byval Servonummer As Byte , Byval Go_to_pos As Byte)
If Go_to_pos > Curr_pos Then
For Servo_counter = Curr_pos To Go_to_pos
Print "#s" ; Chr(servonummer) ; Chr(servo_counter)
Waitms 10
Next Servo_counter
Elseif Go_to_pos < Curr_pos Then
Steps_to_go = Abs(curr_pos - Go_to_pos)
For Servo_counter = 0 To Steps_to_go
Print "#s" ; Chr(servonummer) ; Chr(curr_pos - Servo_counter)
Waitms 10
Next Servo_counter
End If
Curr_pos = Go_to_pos
End Sub
End
Die Bewegung von 0 nach 100, als auch die von 100 nach 150 funktionieren, weil jeweils die momentane Position kleiner als die zu erreichende Position ist (curr_pos < go_to_pos).
Beim Schritte von Position 150 nach 50 sollte also der zweite Teil der If-Abfrage in der Subroutine ausgeführt werden. Das Problem liegt jetzt in der Zeile "Print "#s" ; Chr(servonummer) ; Chr(curr_pos - Servo_counter)". Als Fehler wird "Error 31 : Invalid Data Type" angezeigt.
Ich kapier nicht, wie der Fehler zustande kommt. Kann jemand helfen?
mfg
jagdfalke
Diese Rechnungen in der Klammer chr(curr_pos - servo_counter) mag er nicht. das mußt du vorher in einer Variablen ausrechnen.
ABER
mach es nicht so kompliziert:
dim curr_pos as byte
curr_pos = 127 ' mittelposition am anfang
hauptschleife
...
Sub Rnb_servo(byval Servonummer As Byte , Byval Go_to_pos As Byte)
local schritt as integer
if curr_pos < go_to_pos then
schritt = 1
else
schritt = -1
end if
For curr_pos = Curr_pos To Go_to_pos step schritt
Print "#s" ; Chr(servonummer) ; Chr(curr_pos)
Waitms 10
Next
Je nachdem schritt + oder - ist, geht's rauf oder runter
jagdfalke
17.06.2005, 15:22
ahhhh !! cool !
Ich hab mich schon gewundert, dass man die for schleife nicht rückwärts zählen lassen kann. anscheinend ist er automatisch auf STEP 1 gestellt. lol
naja danke jedenfalls
Fein, wenn ich dir helfen konnte.
ABER
Man sollte keine Statements hinschreiben, bevor man den "help" -text dazu nicht auswendig singen kann. :D
jagdfalke
19.06.2005, 21:12
Hi hab scho wieder a Problem mit dem Code:
Sub Rnb_servo(byval Servonummer As Byte , Byval Go_to_pos As Byte)
Local Schritt As Integer
Local Repeat_counter As Integer
If Curr_pos < Go_to_pos Then
Schritt = 1
Else
Schritt = -1
End If
For Curr_pos = Curr_pos To Go_to_pos Step Schritt
Open "comd.7:9600,8,n,1" For Output As #2
Print #2 , "#s" ; Chr(servonummer) ; Chr(curr_pos)
Close #2
Print Curr_pos
Waitms 10
Next
End Sub
Ich kann für die Variable Go_to_pos nur werte zwischen 1 und 254 eingeben. Is da irgendwo a Denkfehler drin, den ich net find? Man, ich auch gar nix richtig :(
Hallo,
ja da ist ein Denkfehler drin:
du hast deine Variable Go_to_pos als Byte definiert, ein Byte hat nur 8 bit, also kann es 2^8=256 verschiedene Zahlen darstellen. Schau mal in der Bascom Hilfe unter "Language Fundamentals", dort steht wie groß die einzelnen Variablen sind.
Gruß
Florian
jagdfalke
19.06.2005, 22:55
Was? Go_to_pos soll doch auch nur von 0 bis 255 gehen. Sie gibt die gewünschte Position des Servos an und die kann ja auch nur zwischen 0 und 255 sein. Kapier ich net.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.