Archiv verlassen und diese Seite im Standarddesign anzeigen : For-Next-Schleife läuft nicht so wie gewollt :(
jagdfalke
02.07.2005, 01:25
Hi,
ich habe meinen Roboterarm jetzt schon fast fertig aufgebaut. Es fehlt nur noch der Greifer. Ich wollte jetzt ein bischen mit der Positionierung herumexperimentieren und bin auf ein sicherlich sehr einfach zu lösendes Problem gestoßen, nur komm ich nicht drauf.
Hier mal der Code:
$crystal = 8000000
$baud = 9600
Declare Sub Shoulder_move(byval Shoulder_goto_pos As Byte)
Dim Shoulder_curr_pos As Byte
Shoulder_curr_pos = 127
Hauptschleife:
Wait 2
Call Shoulder_move(255)
Goto Hauptschleife
Sub Shoulder_move(byval Shoulder_goto_pos As Byte)
Local Schritt As Integer
If Shoulder_curr_pos < Shoulder_goto_pos Then
Schritt = 1
Elseif Shoulder_curr_pos > Shoulder_goto_pos Then
Schritt = -1
End If
Open "comd.7:9600,8,n,1" For Output As #2
For Shoulder_curr_pos = Shoulder_curr_pos To Shoulder_goto_pos Step Schritt
Print #2 , "#s" ; Chr(1) ; Chr(shoulder_curr_pos)
Print #2 , "#s" ; Chr(2) ; Chr(shoulder_curr_pos)
Waitms 30
Print " SCHRITT: " ; Schritt ; " CURR_POS: " ; Shoulder_curr_pos ; " GOTO_POS: " ; Shoulder_goto_pos
Next Shoulder_curr_pos
Close #2
Shoulder_curr_pos = Shoulder_goto_pos
End Sub
End
Der kommt gar nicht aus der For-Schleife raus. Die Variable Shoulder_curr_pos geht immer auf 255 und springt dann auf 0. Damit bewegt er sich plötzlich auch 0 und dann gehts wieder weiter zu 255, usw.
Habs mit 255 und 0 für Shoulder_goto_pos probiert. In beiden Fällen passiert das gleiche. An der Variable Schritt liegts nicht. Die ist immer richtig.
Oh man, das ist bestimmt total einfach und ich checks wieder nicht. Naja hoffentlich eine von euch.
mfg
jagdfalke[/code]
Wenn du dir dein Programm mal in den Bascom-Simulator läst und laufen lässt, wirst du sehen, dass deine Variable "Shoulder_curr_pos" kurz überläuft, dadurch auf 0 zurückspringt und die For-Schleife von vorne losgeht.
Wenn du "Shoulder_curr_pos" als Word anstatt als Byte deklarierst bleibt die For-Schleife bei 255 hängen.
Woher hast du die Syntax für deine For-Schleife?
For Shoulder_curr_pos = Shoulder_curr_pos To Shoulder_goto_pos Step Schritt
For Shoulder_curr_pos = Shoulder_curr_pos macht irgendwie wenig Sinn, da die Bedingung immer erfüllt ist.
For Shoulder_curr_pos = Shoulder_curr_pos macht irgendwie wenig Sinn, da die Bedingung immer erfüllt ist.
Um diese Uhrzeit muß man aufpassen, da schreibt man manches Unüberlegtes. Was du bemäkelst ist ja nicht die Bedingung, sondern der Anfangswert.
Bedingung ist "TO"
@Jadfalke: du bringst den BasCom ins Schleudern mit den Vorzeichen und Umwandlungen.
Du mußt .._curr_pos und .. goto_pos auch als integer definieren
Die For Schleife ist sonst genau richtig.
Um diese Uhrzeit muß man aufpassen, da schreibt man manches Unüberlegtes.
Stimmt ;-) In dem Fall waren es aber mehr Probleme auszudrücken was ich meine.
Mir kommt es etwas seltsam vor die Variable die hochgezählt wird gleich dem Anfangswert zu setzen und den Anfangswert bei jedem Schleifendurchlauf hochzuzählen.
Mag ja sein, dass es funktioniert, aber übersichtlicher macht das die Geschichte irgendwie nicht.
jagdfalke
02.07.2005, 11:51
Hi Jungs,
ich hab die Variablentypen angeglichen und jetzt läufts. Nur leider erschien ein neues Problem:
$crystal = 8000000
$baud = 9600
Declare Sub Servo_move(byval Servo As Integer , Byval Servo_goto_pos As Integer)
$crystal = 8000000 'Quarzfrequenz
Dim Shoulder_curr_pos As Integer
Shoulder_curr_pos = 127
Dim Elbow_curr_pos As Integer
Elbow_curr_pos = 127
Hauptschleife:
Wait 2
Call Servo_move(1 , 255)
Wait 2
Call Servo_move(1 , 0)
Goto Hauptschleife
Sub Servo_move(byval Servo As Integer , Byval Servo_goto_pos As Integer)
Local Schritt As Integer
If Servo = 0 Then 'Schulter bewegen
If Shoulder_curr_pos < Servo_goto_pos Then
Schritt = 1
Elseif Shoulder_curr_pos > Servo_goto_pos Then
Schritt = -1
Elseif Shoulder_curr_pos = Servo_goto_pos Then
Exit Sub
End If
Open "comd.7:9600,8,n,1" For Output As #2
For Shoulder_curr_pos = Shoulder_curr_pos To Servo_goto_pos Step Schritt
Print #2 , "#s" ; Chr(1) ; Chr(shoulder_curr_pos)
Print #2 , "#s" ; Chr(2) ; Chr(shoulder_curr_pos)
Next Shoulder_curr_pos
Close #2
Shoulder_curr_pos = Servo_goto_pos
End If
If Servo = 1 Then 'Ellbogen bewegen
If Elbow_curr_pos < Servo_goto_pos Then
Schritt = 1
Elseif Elbow_curr_pos > Servo_goto_pos Then
Schritt = -1
Elseif Elbow_curr_pos = Servo_goto_pos Then
Exit Sub
End If
Open "comd.7:9600,8,n,1" For Output As #2
For Elbow_curr_pos = Elbow_curr_pos To Servo_goto_pos Step Schritt
Print #2 , "#s" ; Chr(3) ; Chr(elbow_curr_pos)
Print "CURR: " ; Elbow_curr_pos ; " GOTO: " ; Servo_goto_pos
Next Elbow_curr_pos
Close #2
Elbow_curr_pos = Servo_goto_pos
End If
End Sub
End
Der Code für Servo = 1 ist eigenlich 1:1 kopiert aus dem Servo=0-Teil aber er funktionert nicht. Ich hab per Terminal überprüft ob er wirklich in die For-Schleife rein geht und er tut es. Elbow_curr_pos wird vergrößert, definitiv. Anscheinend passiert dann bei
Print #2 , "#s" ; Chr(3) ; Chr(elbow_curr_pos)
gar nichts. Ich hab den Servo 100%ig am 3. Servoanschluss angeschlossen !!! Das komische ist, wenn ich das hier
Open "comd.7:9600,8,n,1" For Output As #2
For I = 127 To 255 Step 1
Print #2 , "#s" ; Chr(3) ; Chr(i)
Next I
Close #2
direkt in die Haupschleife einbaue, dann bewegt er sich wie er soll. Ich bin ratlos.
EDIT: "funktioniert nicht" bedeutet er bewegt sich keinen Millimeter.
mfg
jagdfalke [/shadow]
sehe ich direkt keinen Fehler:
Aber falls ihn das chr(xx) von einem Integer stören sollte, probier das mal, um zu sehen
Dim Temp As byte
....
....
Open "comd.7:9600,8,n,1" For Output As #2
For Shoulder_curr_pos = Shoulder_curr_pos To Servo_goto_pos Step Schritt
TEMP = shoulder_curr_pos
Print #2 , "#s" ; Chr(1) ; Chr(TEMP)
Der BasCom hat's nicht so mit verdeckten Typenänderungen
Is'n Versuch, du kannst für alle Servos das gleiche TEMP nehmen.
jagdfalke
02.07.2005, 13:46
Aber komischerweise funktionierts ja auch mit Servo = 0 also der Schulter vom Arm. Hab Temp mal eingeführt und es so gemacht wie oben. Geht aber immernoch nicht. Die Ausgaben für Temp, Goto_pos und Schritt im passen alle (überprüft im Terminal).
Wenn ich aber dern Servo 3 in der schleife von Servo = 0 laufen lass, dann geht er einwandfrei. Ich werd nicht schlau daraus.
mmmm.
Ganz was blödes: Wie schaut's mit den Größen von Soft-Stack und Frame aus ?
Ich verwend HW 128 /SW 256 /Fram 32
Auch da kann er spinnen
so , bis morgen !
jagdfalke
02.07.2005, 13:59
was zu geier bedeutet das?
HW 128 /SW 256 /Fram 32
was zu geier bedeutet das?
Zitat:
HW 128 /SW 256 /Fram 32
Das sind Einstellungen, wie der Bascom-Compiler die internen Resourcen des Controllers nutzt (oder so ähnlich)
Guck in Bascom mal durch die Menüs, dann findest du Dialoge, in denen du das Vorgeben kannst. Vermutlich kann man es auch im Quellcode angeben.
jagdfalke
02.07.2005, 14:19
habs gefunden unter Options->Compiler->Chip
Die Werte sind jetzt:
HW Stack = 128
Soft Stack = 256
Framesize = 32
Dennoch keine Änderung :(
jagdfalke
02.07.2005, 15:33
Ich hab 2 247Ncm Servos direkt angeschlossen um's zu testen. Kann es sein, dass irgendwie durch Überbelastung was kaputt gegangen ist? Obwohl es ja eigentlich nicht so sein dürfte, da wie oben schon gesagt der Servo 3 in der ersten For-Schleife funktioniert. Nur in der 2. nicht.
hier nochmal der komplette Code:
$crystal = 8000000
$baud = 9600
Declare Sub Stepper_move(byval Stepper_goto_pos As Word)
Declare Sub Elbow_move(byval Servo_goto_pos As Integer)
Declare Sub Shoulder_move(byval Servo_goto_pos As Integer)
Const Writepowerport_adr = &H72 'I2C Adr PCF 2
Const Readpowerport_adr = &H73 'I2C Adr PCF 2
Dim I2cdaten As Byte 'Datenbyte aus PCF8574
Dim I As Integer
$crystal = 8000000 'Quarzfrequenz
Config Scl = Portc.0 'Ports fuer IIC-Bus
Config Sda = Portc.1
I2cinit
Config Pind.6 = Output 'Schrittmotoren Ein/Aus
Config Pinc.5 = Output 'Schrittmotor Links Richtung
Config Pinc.3 = Output 'Schrittmotor Links Step
Config Pinc.4 = Output 'Schrittmotor Rechts Richtung
Config Pinc.2 = Output 'Schrittmotor Rechts Step
Portd.6 = 0 'Schrittmotoren einschalten
Dim Stepper_curr_pos As Integer
Stepper_curr_pos = 0
Dim Shoulder_curr_pos As Integer
Shoulder_curr_pos = 127
Dim Elbow_curr_pos As Integer
Elbow_curr_pos = 127
Dim Temp as Byte
Hauptschleife:
'Call Stepper_move(100)
'Wait 2
'Call Stepper_move(0)
'Wait 2
Wait 2
Call Elbow_move(255)
Wait 2
Call Elbow_move(0)
Goto Hauptschleife
Sub Shoulder_move(byval Servo_goto_pos As Integer)
Local Schritt As Integer
If Shoulder_curr_pos < Servo_goto_pos Then
Schritt = 1
Elseif Shoulder_curr_pos > Servo_goto_pos Then
Schritt = -1
Elseif Shoulder_curr_pos = Servo_goto_pos Then
Exit Sub
End If
Open "comd.7:9600,8,n,1" For Output As #2
For Shoulder_curr_pos = Shoulder_curr_pos To Servo_goto_pos Step Schritt
Print #2 , "#s" ; Chr(1) ; Chr(shoulder_curr_pos)
Print #2 , "#s" ; Chr(2) ; Chr(shoulder_curr_pos)
Next Shoulder_curr_pos
Close #2
Shoulder_curr_pos = Servo_goto_pos
End Sub
Sub Elbow_move(byval Servo_goto_pos As Integer)
Local Schritt As Integer
Print "elbow_move called"
If Elbow_curr_pos < Servo_goto_pos Then
Schritt = 1
Elseif Elbow_curr_pos > Servo_goto_pos Then
Schritt = -1
Elseif Shoulder_curr_pos = Servo_goto_pos Then
Exit Sub
End If
Open "comd.7:9600,8,n,1" For Output As #2
For Elbow_curr_pos = Elbow_curr_pos To Servo_goto_pos Step Schritt
Temp = Elbow_curr_pos
Print #2 , "#s" ; Chr(3) ; Chr(temp)
Print "Schritt: " ; Schritt ; " CURR: " ; Temp ; " GOTO: " ; Servo_goto_pos
Next Elbow_curr_pos
Close #2
Elbow_curr_pos = Servo_goto_pos
End Sub
Sub Stepper_move(byval Stepper_goto_pos As Intgeger)
Local Betrag As Integer
If Stepper_goto_pos > Stepper_curr_pos Then
Betrag = Stepper_goto_pos - Stepper_curr_pos
Portc.5 = 0 'Richtung
Portc.3 = 0
For I = 0 To Betrag Step 1
Portc.3 = 0
Waitms 5
Portc.3 = 1
Waitms 20
Next I
Stepper_curr_pos = Stepper_goto_pos
Print Stepper_curr_pos
Elseif Stepper_goto_pos < Stepper_curr_pos Then
Betrag = Stepper_curr_pos - Stepper_goto_pos
Portc.5 = 1 'Richtung
Portc.3 = 0
For I = 0 To Betrag Step 1
Portc.3 = 0
Waitms 5
Portc.3 = 1
Waitms 20
Next I
Stepper_curr_pos = Stepper_goto_pos
Print Stepper_curr_pos
End If
End Sub
End
mfg
jagdfalke
jagdfalke
02.07.2005, 16:00
hab was neues rausgefunden:
wenn ich diesen code als hauptschleife benutze:
Hauptschleife:
Wait 2
Call Elbow_move(255)
Wait 2
Call Shoulder_move(0)
Wait 2
Call Shoulder_move(255)
Wait 2
Call Elbow_move(0)
Goto Hauptschleife
dann macht er die erste Bewegung, also Call Elbow_move(255) NICHT !!!! Call Elbow_move(0) macht er allerdings dann, und wenn er einmal soweit war macht er auch Call Elbow_move(255).
Er macht also alles, lässt aber Call Elbow_move(255) im allerersten Durchlauf aus (eigenlich lässt er ihn nicht aus, es bewegt sich einfach nichts, obwohl das Sub ausgeführt wird).
Vielleicht hilf das !?
mfg
jagdfalke
Ich muß erst noch Gartenarbeit machen, dann schau ich mir das gaaanz genau an.
Inzwischen mach auf jeden Fall eins:
Den Open COm#2 EINMAL vor die Hauptschleife und raus aus den Subs, den Close brauchst du garnicht, der nutzt eh nix.
Weil ich es genau testen will: Verwendest du RNS1 oder den RNKC10 vom Kjion ?
jagdfalke
03.07.2005, 17:30
ich benutze den rns1
*hmm* Verwend' ich auch, nie was derartiges erlebt. *grmpf*
Mystisch.
Kannst du mal dein .Bas in der letztversion rein posten ?
ich muß das einfach sehen und 1:1 meinen BasCom rein pusten.
*zumeierlegenseheinfachnix"
Ich glaub ja nicht, daß es daran liegt, aber ich steuere den RNS1 mit der HW-UART. Vielleicht können wir so den Hund einkreisen, das ist ja lächerlich
Da hat mich doch das Ferkel unter dem H... ausgeloggt.
Ich bin's, der PicNick !
jagdfalke
03.07.2005, 20:12
Hier mal der Code, der nicht funktioniert:
$crystal = 8000000
$baud = 9600
Declare Sub Stepper_move(byval Stepper_goto_pos As Word)
Declare Sub Shoulder_move(byval Shoulder_goto_pos As Integer)
Declare Sub Elbow_move(byval Elbow_goto_pos As Integer)
Const Writepowerport_adr = &H72 'I2C Adr PCF 2
Const Readpowerport_adr = &H73 'I2C Adr PCF 2
Dim I2cdaten As Byte 'Datenbyte aus PCF8574
Dim I As Integer
$crystal = 8000000 'Quarzfrequenz
Config Scl = Portc.0 'Ports fuer IIC-Bus
Config Sda = Portc.1
I2cinit
Config Pind.6 = Output 'Schrittmotoren Ein/Aus
Config Pinc.5 = Output 'Schrittmotor Links Richtung
Config Pinc.3 = Output 'Schrittmotor Links Step
Config Pinc.4 = Output 'Schrittmotor Rechts Richtung
Config Pinc.2 = Output 'Schrittmotor Rechts Step
Portd.6 = 0 'Schrittmotoren ausschalten
Dim Stepper_curr_pos As Integer
Stepper_curr_pos = 0
Dim Shoulder_curr_pos As Integer
Shoulder_curr_pos = 127
Dim Elbow_curr_pos As Integer
Elbow_curr_pos = 127
Dim Temp As Byte
Hauptschleife:
Call Elbow_move(0)
Wait 1
Call Shoulder_move(255)
Wait 1
Goto Hauptschleife
Sub Shoulder_move(byval Shoulder_goto_pos As Integer)
Local Schritt As Integer
If Shoulder_curr_pos < Shoulder_goto_pos Then
Schritt = 1
Elseif Shoulder_curr_pos > Shoulder_goto_pos Then
Schritt = -1
Elseif Shoulder_curr_pos = Shoulder_goto_pos Then
Exit Sub
End If
Open "comd.7:9600,8,n,1" For Output As #2
For Shoulder_curr_pos = Shoulder_curr_pos To Shoulder_goto_pos Step Schritt
Temp = Shoulder_curr_pos
Print #2 , "#s" ; Chr(1) ; Chr(temp)
Print #2 , "#s" ; Chr(2) ; Chr(temp)
Print "SHOULDER: " ; "Schritt: " ; Schritt ; " CURR: " ; Temp ; " GOTO: " ; Shoulder_goto_pos
Next Shoulder_curr_pos
Close #2
Shoulder_curr_pos = Shoulder_goto_pos
End Sub
Sub Elbow_move(byval Elbow_goto_pos As Integer)
Local Schritt As Integer
If Elbow_curr_pos < Elbow_goto_pos Then
Schritt = 1
Elseif Elbow_curr_pos > Elbow_goto_pos Then
Schritt = -1
Elseif Elbow_curr_pos = Elbow_goto_pos Then
Exit Sub
End If
Print "elbow"
Open "comd.7:9600,8,n,1" For Output As #2
For Elbow_curr_pos = Elbow_curr_pos To Elbow_goto_pos Step Schritt
Temp = Elbow_curr_pos
Print #2 , "#s" ; Chr(3) ; Chr(temp)
Print "ELBOW: " ; "Schritt: " ; Schritt ; " CURR: " ; Temp ; " GOTO: " ; Elbow_goto_pos
Next Elbow_curr_pos
Close #2
Elbow_curr_pos = Elbow_goto_pos
End Sub
Sub Stepper_move(byval Stepper_goto_pos As Intgeger)
Local Betrag As Integer
If Stepper_goto_pos > Stepper_curr_pos Then
Betrag = Stepper_goto_pos - Stepper_curr_pos
Portc.5 = 0 'Richtung
Portc.3 = 0
For I = 0 To Betrag Step 1
Portc.3 = 0
Waitms 5
Portc.3 = 1
Waitms 30
Next I
Stepper_curr_pos = Stepper_goto_pos
Print Stepper_curr_pos
Elseif Stepper_goto_pos < Stepper_curr_pos Then
Betrag = Stepper_curr_pos - Stepper_goto_pos
Portc.5 = 1 'Richtung
Portc.3 = 0
For I = 0 To Betrag Step 1
Portc.3 = 0
Waitms 5
Portc.3 = 1
Waitms 30
Next I
Stepper_curr_pos = Stepper_goto_pos
Print Stepper_curr_pos
End If
End Sub
End
Das seltsame ist, dass diese Hauptschleife funktioniert:
Hauptschleife:
Call Shoulder_move(255)
Wait 1
Call Elbow_move(0)
Wait 1
Goto Hauptschleife
diese aber nicht:
Hauptschleife:
Call Elbow_move(0)
Wait 1
Call Shoulder_move(255)
Wait 1
Goto Hauptschleife
hier bewegt sich die Schulter nach ewiger Zeit auf 255, dannach passiert nichts mehr, egal wie lange ich warte.
mfg
jagdfalke
jagdfalke
03.07.2005, 21:56
Ich glaub ja nicht, daß es daran liegt, aber ich steuere den RNS1 mit der HW-UART.
Ok, und das ganze nochmal auf deutsch bitte !?
Morgen !
Ich hab das Zeugs auf meiner RNBFRA 1.2 getestet. Da ich die Sevos über die eingebaute UART bediene, hab ich die Open und Close natürlich auskommentieren müssen und die "Print #2" auf normale "print" umgebaut. klaro
Erwartungsgemäß geht das pipifein ohne Probleme.
D.h. Am Programm ist deswegen kein Fehler zu finden, weil keiner da ist.
Also irgendwas hats mit dem Open Com zu zun.
probier mal NUR EINEN Open VOR der Hauptschleife und sonst nix (close ist sowieso überflüssig)
jagdfalke
04.07.2005, 16:58
Cool, es funktioniert. Danke !
Kannst du dir das erklären?
Das freut mich, da es ja wirklich sehr seltsam war.
Begründung: Tscha, Ich muß erst in die disassembler- listen schauen (stinkt nach Arbeit).
Irgendwie mag er es nicht, mehrfach open/close zu machen.
Jetzt kommt's drauf an: Wenn irgendwo steht, man darf das nicht, sind wir die Dummen.
Wenn aber nicht, und ich komm ihm auf einen Fehler drauf, sind die BasCom-Leute die Dummen, dann gibt's eins auf die Glocke.
Schau'n wir halt.
jagdfalke
04.07.2005, 17:14
Ok, wegen meiner Frage nach dem Grund brauchst du dir die Arbeit aber nicht machne, gelle! Ich bin einfach nur froh dass es klappt.
Ich bin auch froh, als Fachmann steht man ja saublöd da, wenn man das Problem nicht irgendwie in den Griff kriegt.
Aber wenn im BasCom tatsächlich ein Unfug passiert, gehört das ausgebessert.
jagdfalke
04.07.2005, 17:20
Ja, das stimmt schon. Solche Fehler gehören ausgebessert. Wenn so Leute wie ich so ein Problem haben und kein Forum mit Profis auf dem Gebiet schauts natürlich schlecht aus !!! (Es soll ja noch Leute geben die kein Internet haben :D )
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.