Need infinite loop in method while ina[leftstop]==1
I want to turn a motor, used for steering, left until the left limit switch is pressed (left LS is NC(1) so it is open(0) when pressed).
When the left LS is pressed (ina[noparse][[/noparse]leftstop]==0) I then want to slowly turn right until the left LS is not pressed (ina[noparse][[/noparse]leftstop]==1) and then stop the motor.
Then I want to read the value from a potentiometer and then turn fast right until the right LS is pressed (ina[noparse][[/noparse]rightstop]==0)
My code is not working.
("turnmotor" is a PUB with (Pin, Speed) controlling HB-25 which drives the motor and that code works so I left it out of the below sample code)
[/code][/size]
when I run this code, I expect that when the leftstop LS is pressed (ina[noparse][[/noparse]leftstop]==0):
the motor will stop
PUB leftcalibrate is called:
the motor will turn slowly to the right until the leftstop LS is no longer pressed (ina[noparse][[/noparse]leftstop]==1)
the motor will stop
The pot value will be stored
the motor will turn full speed right.
PUB leftcalibrate is done and processing continues in PUB calibrate after the line that called PUB leftcalibrate.
My observation is that when the leftstop LS is pressed, the motor stops and turns right and stops and turns right rapidly and repeatedly until the leftstop LS is no longer pressed and then turns fast right.
It appears to me that the 'repeat while' code
is being ignored.
Which means that PUB leftcalibrate keeps getting called and completed rapidly and repeatedly while the leftstop LS == 0 as if there were no 'repeat while leftstop==0' condition.
Shouldn't the 'repeat while ina[noparse][[/noparse]leftstop] == 0' keep the cog stuck looping 'turnmotor(steering, sright)' until 'ina[noparse][[/noparse]leftstop]==1' and then process the rest of the PUB leftcalibrate?
c
Post Edited (cnelson700) : 6/14/2010 8:20:31 PM GMT
When the left LS is pressed (ina[noparse][[/noparse]leftstop]==0) I then want to slowly turn right until the left LS is not pressed (ina[noparse][[/noparse]leftstop]==1) and then stop the motor.
Then I want to read the value from a potentiometer and then turn fast right until the right LS is pressed (ina[noparse][[/noparse]rightstop]==0)
My code is not working.
("turnmotor" is a PUB with (Pin, Speed) controlling HB-25 which drives the motor and that code works so I left it out of the below sample code)
[size=2][code]
PUB main
calibrate
PUB calibrate
repeat
case ina[noparse][[/noparse]leftstop]
0 : turnmotor(steering, steerstop)
leftcalibrate
case ina[noparse][[/noparse]rightstop]
0 : turnmotor(steering, steerstop)
rightcalibrate
PUB leftcalibrate
repeat while ina[noparse][[/noparse]leftstop] == 0
turnmotor(steering, sright)
turnmotor(steering, steerstop)
<here is where I put code to read pot value>
turnmotor(steering, fright)
PUB rightcalibrate
repeat while ina[noparse][[/noparse]rightstop] == 0
turnmotor(steering, sleft)
turnmotor(steering, steerstop)
<here is where I put code to read pot value>
turnmotor(steering, fleft)
[/code][/size]
when I run this code, I expect that when the leftstop LS is pressed (ina[noparse][[/noparse]leftstop]==0):
the motor will stop
PUB leftcalibrate is called:
the motor will turn slowly to the right until the leftstop LS is no longer pressed (ina[noparse][[/noparse]leftstop]==1)
the motor will stop
The pot value will be stored
the motor will turn full speed right.
PUB leftcalibrate is done and processing continues in PUB calibrate after the line that called PUB leftcalibrate.
My observation is that when the leftstop LS is pressed, the motor stops and turns right and stops and turns right rapidly and repeatedly until the leftstop LS is no longer pressed and then turns fast right.
It appears to me that the 'repeat while' code
repeat while ina[noparse][[/noparse]leftstop] == 0
turnmotor(steering, sright)
is being ignored.
Which means that PUB leftcalibrate keeps getting called and completed rapidly and repeatedly while the leftstop LS == 0 as if there were no 'repeat while leftstop==0' condition.
Shouldn't the 'repeat while ina[noparse][[/noparse]leftstop] == 0' keep the cog stuck looping 'turnmotor(steering, sright)' until 'ina[noparse][[/noparse]leftstop]==1' and then process the rest of the PUB leftcalibrate?
c
Post Edited (cnelson700) : 6/14/2010 8:20:31 PM GMT

Comments
(the leftstop LS is on pin 14)
PUB calibrate repeat case ina[noparse][[/noparse]leftstop] 0 : turnmotor(steering, steerstop) leftcalibrate case ina[noparse][[/noparse]rightstop] '<<<<<<<<<<<<<<<<<<<< indented 1 space 0 : turnmotor(steering, steerstop) rightcalibrateWhen you have code spread out like that with all the spaces between, it is hard to keep track of your indention.
A suggestion might be to implement some type of visual or audible feedback to help diagnose the issue. When I am trying to track things down, I either use an LCD to pop up a visual que or a piezo speaker. This way you can place feedback at different sections of code to see where things are getting to or not getting to. With the piezo or other speaker off a Prop pin, you can set the frequency to different values that let you know where you are in the loop. ie, 500 hz for the first pub, 1000 hz for 2nd, 1500 for 3rd etc.
Post Edited (Todd Chapman) : 6/14/2010 8:32:42 PM GMT
Good eye!
I typed it here. My code has more components to it that are not relevant to my question so I just typed up the stuff that would help clarify my question.
It is a bit messy, I'll clean it up after I get it to work the way I want it to.
Thanks,
c
I have run this code and I get the same undesirable result.
I get:
Slow turn left until left LS pressed
Stop
slow turn right, stop, slow turn right, stop, slow turn right, stop, slow turn right, stop, slow turn right, stop......
until the left LS is not pressed and then fast turn right.
I want:
slow turn left until left LS pressed
stop
slow turn right until left LS is not pressed
1 second pause
fast turn right
Why is the repeat while ina[noparse][[/noparse]leftstop] == 0 not repeating while ina[noparse][[/noparse]leftstop] == 0?
{{hb-25 test turn until switch input is low pause 1 second then turn the other way until other switch input is low pause 1 second repeat }} CON _xinfreq=5_000_000 _clkmode=xtal1+pll16x 'The system clock is set at 80MHz (this is recommended for optimal resolution) rightstop = 13 'input pin for right LS leftstop = 14 'input pin for left LS steerstop = 1500 ssleft = 1550 sleft = 1700 fleft = 2000 ssright = 1450 sright = 1300 fright = 1000 steering = 16 'output pin for HB-25 PUB steercalstart dira[noparse][[/noparse]rightstop]~ 'make right LS pin an input dira[noparse][[/noparse]leftstop]~ 'make left LS pin an input dira[noparse][[/noparse]steering]~~ 'make pin for HB-25 an output outa[noparse][[/noparse]steering]~ 'hold pin for HB-25 low waitcnt((clkfreq*3)+cnt) 'for 3 seconds if ina[noparse][[/noparse]leftstop] == 1 'if leftLS is 1 (not tripped) steermotor(steering, sleft) 'start slow left turn of steering wheels repeat while ina[noparse][[/noparse]leftstop] == 1 'turn slowly left until hit left LS steermotor(steering,sleft) steercalLR PUB steercalLR repeat case ina[noparse][[/noparse]leftstop] + ina[noparse][[/noparse]rightstop] 'If both left and right LS are low 0 : steermotor(steering, steerstop) 'Stop steering motor WAITPEQ(%000000000, %100000000, 0) 'Wait for reset pin to go low case ina[noparse][[/noparse]rightstop] 'If Right LS is pressed (0) 0 : steermotor(steering, steerstop) 'stop motor rightcal 'goto rightcal case ina[noparse][[/noparse]leftstop] 'If Left LS is pressed (0) 0 : steermotor(steering, steerstop) 'stop motor leftcal 'goto leftcal PUB rightcal if ina[noparse][[/noparse]rightstop] == 0 'If right LS is pressed (0) repeat while ina[noparse][[/noparse]rightstop] == 0 'while Right LS is pressed steermotor(steering, sleft) 'keep turning slow left steermotor(steering, steerstop) 'then stop motor waitcnt (clkfreq+cnt) 'wait 1 second steermotor(steering, fleft) 'go fast left PUB leftcal if ina[noparse][[/noparse]leftstop] == 0 'If Left LS is pressed (0) repeat while ina[noparse][[/noparse]leftstop] == 0 'while Left LS is pressed steermotor(steering, sright) 'keep turning slow right steermotor(steering, steerstop) 'then stop motor waitcnt (clkfreq+cnt) 'wait 1 second steermotor(steering, fright) 'go fast right PUB steermotor(motor, speed) outa[noparse][[/noparse]steering]~~ 'pulse high waitcnt((speed * (clkfreq / 1_000_000))+cnt) 'keep pulse high for 1.5ms for stop outa[noparse][[/noparse]steering]~ 'pulse low waitcnt (clkfreq/1000_000*6500+cnt) 'min hold-off time between pulses is 5.25msI have also attached the object for review.
PUB steermotor(motor, speed) '<<<<<<< MOTOR is never used after this line outa[noparse][[/noparse]steering]~~ 'pulse high waitcnt((speed * (clkfreq / 1_000_000))+cnt) 'keep pulse high for 1.5ms for stop outa[noparse][[/noparse]steering]~ 'pulse low waitcnt (clkfreq/1000_000*6500+cnt) 'min hold-off time between pulses is 5.25msIt looks like you have extra pins to spare, I would at a minimum put an LED on a spare output pin, and turn the LED ON when ina[noparse][[/noparse]left] == 0 so you can start seeing in real time whatever the code is seeing to better analyze things. In a case like yours, you have to implement diagnostics when things don't make sense to track down where it is off.
Also, the way you are trying to pulse the line is not going to be precisely how you intend, since you are introducing extra code in the loop that takes time. If you have cogs to spare, you should park the pulse management code in a cog by itself, which updates from the master, then the pulses can be more precise.
Post Edited (Todd Chapman) : 6/15/2010 2:58:09 PM GMT
I have been using a voltmeter to watch the input and also using the ina[noparse][[/noparse]leftstop]+ina[noparse][[/noparse]rightstop] fault detection by pressing both LS's to make the motor stop.· In my more complex version of this code, I have the fault displayed in serial terminal.
I am not sure what you mean regarding extra code or how to get more precise pulses.
Thanks for looking and replying.
Post Edited (cnelson700) : 6/15/2010 3:05:25 PM GMT
PUB leftcal if ina[noparse][[/noparse]leftstop] == 0 'If Left LS is pressed (0) repeat while ina[noparse][[/noparse]leftstop] == 0 'while Left LS is pressed steermotor(steering, sright) 'keep turning slow right steermotor(steering, steerstop) 'then stop motor waitcnt (clkfreq+cnt) 'wait 1 second steermotor(steering, fright) 'go fast rightPost Edited (Todd Chapman) : 6/15/2010 3:06:19 PM GMT
But when leftcal is called, the motor stops, waits 1 sec, pulses right, stops, waits 1 sec, pulses right, stops, waits 1 sec...... until the leftstop LS is not pressed and then goes fast right.
It is not doing the 'slowly turn right until the left stop is not pressed' part.
But it does not continue looping in the repeat while loop.
Try turning off all the case statements except LEFT to isolate the left case as the problem.
Put a short delay after the repeat while line before it hits the last three lines.
Look at the left stop pin with a scope to see what kind of noise is on it that might be causing the repeat to jump out and start all over again. Put a .1 cap from the pins to GND near the 2 stop inputs and see if that helps. There is no obvious reason in the code why it would stop repeating until the switch is released.
Check if the Prop is resetting between each 'pulse' (add some indication to the steercalstart init to inidicate that it had restarted)
Which propeller board do you use? Maybe you can disconnect the buttons and simulate the user input with another COG which uses the input pins of your code as output. As this will create clear signals you can test the code this way.
If you can't disconnect the buttons you can maybe use other pins.
case ina[noparse][[/noparse]leftstop] 'If Left LS is pressed (0) 0 : if ina[noparse][[/noparse]leftstop] == 0 'make sure it is really a 0 waitcnt(10_000 + cnt) ' lets wait to be sure if ina[noparse][[/noparse]leftstop] == 0 'check again steermotor(steering, steerstop) 'stop motor leftcal 'goto leftcal PUB leftcal if ina[noparse][[/noparse]leftstop] == 0 waitcnt(10_000 + cnt) ' lets wait to be sure if ina[noparse][[/noparse]leftstop] == 0 'If Left LS is pressed (0) repeat while ina[noparse][[/noparse]leftstop] == 0 'while Left LS is pressed steermotor(steering, sright) 'keep turning slow right steermotor(steering, steerstop) 'then stop motor waitcnt(clkfreq+cnt) 'wait 1 second steermotor(steering, fright) 'go fast rightI did the tests Todd suggested at 8:25 AM (GMT -7) except for checking to see if the prop is resetting.· Good troubleshooting points, unfortunately none of those checks found the problem - but I added
waitcnt(clkfreq+cnt)
after the last line of PUB leftcal
steermotor(steering, fright) - and after the steermotor(steering, fleft) in the PUB rightcal
and it worked as desired.
PUB leftcal if ina[noparse][[/noparse]leftstop] == 0 'If Left LS is pressed (0) repeat while ina[noparse][[/noparse]leftstop] == 0 'while Left LS is pressed steermotor(steering, sright) 'keep turning slow right steermotor(steering, steerstop) 'then stop motor waitcnt (clkfreq+cnt) 'wait 1 second steermotor(steering, fright) 'go fast right waitcnt(clkfreq+cnt)I don't understand why this worked.· I didn't touch the repeat while.
I just added a 1 sec pause after the return from the call to the PUB steermotor.
The end of the PUB steermotor has a 6.5ms delay when only 5.25ms delay is required (for the HB-25).
The addition of the waitcnt(clkfreq+cnt) did not fix the issue.
I·thought the issue was fixed·...· and it was... Until I pulled the scope leads off of the LS input.· Then it did not work properly, again.
So I·tried to mimic the load of the Oscope:
Capacitive load?· I tried a few values of cap's - nogo
Resistive load?· I tried a 2.2k ohm resistor from the input to gnd... and it worked.· Yes it did!
Is a 2.2k pull down resistor on the switch input gonna be OK on the Prop Pro Development board?
c
If you leave an input-pin free floating the detected state will flip around from 0 to 1 and back in an unpredictable way
even if you only have connected a wire only one inch long.
2.2k is Ok. Everything between 1k and 10k is OK
maximum current: 3.3V / 1k = 3.3 mA 3.3V / 10k = 0.33mA
best regards
Stefan
I didn't need to add a resistor for any of my other I/O devices (even the PB's on the prop pro development board have built in pull up resistors) so I completely overlooked that part of the design.
Ouch!