HSERVO problems within functionss

Hey again everyone. I am working on a project controlling a sabertooth motor controller (and therefore a dc motor) using a pwm signal generated by a BOT board II. That part is all figured out, however, along with starting the motor controller, a servo needs to move forward and backward at a specified rate until the motor has stopped. The motor starts when a button is pressed and stops when a second button is pressed.

So… the problem is that the HSERVO command does not work at all when in the loops for controlling the speed of the motor (or possibly some containing IF Then statements). I have tested the HSERVO code I wrote in its own little program and it worked flawlessly, but once I input that block of code into the motor controlling program, the servo just sits there… mocking me. I have run through debug and found that the If Then statements are tripping correctly. In desparation, I made a manual counter that was much more “brute force” then intelligence that manually counted a specified time and then switched the servo position. This also did not work, so I went back the the original code which checks to see if the servo is idle and the last direction it ran, and then tells it to change position and updates the last direction variable.

I will post the code I have written below. Hopefully someone here might be able to help.

I have read up on the posts including the sticky post on the HSERVO command. If it did answer my questions, I was too dense to see it. Perhaps there is a timing issue?

Thanks for your help.
bigben

[code];The program initializes setting a DC motor and a servo at a zero position and speed.
;The program loops until a button is pressed.
;Once the button is pressed, the board ramps up the speed of a DC motor and then holds the speed until a second button is pressed
;A servo also begins moving along with the DC motor when the first button is pressed and stops moving when the second button is pressed

ENABLEHSERVO ;Enable the hservo command
workspace1 var byte ;provide holding variable for button press timeout
workspace2 var byte ;provide holding variable for button press timeout
valuespeed var long ;current speed of the DC motor
direction var long ;current direction of the servo rotation… either 1 or 0
initialize var long ;create a variable that says whether the program has been initialized… if 0 then run first set of code; if 1 then ignore first set of code
valuespeed = 1020 ;set the intial speed of the DC motor at 0… value of 0 is full reverse; value of 2000 is full forward; value of 1020 is speed 0
onvar var long ;Create a timer that acts as a safety if the operator forgets to press the second button
onvar = 0 ;Set the intitial timer at 0
initialize = 0 ;Set the intial variable to 0 when program begins
hservo [p13\1000\255] ;Set the starting position of the first servo
pause 500 ;give the servo time to respond
hpwm p11, 2000, 1020 ; Set the intial motor speed at 0
sleep 1000 ;Give the motor time to stabilize

Main ; begin button searching loop
if initialize = 0 then ;If the program is running for the first time, make sure the motor is at 0
hpwm p11, 2000, 1020 ;Set the motor at speed 0
initialize = 1 ;remove the intialize flag
sleep 1000 ;give the motor time to adjust
endif
button P14,0,80,40,workspace1,1,pressedon ;waiting for button press. Once button is pressed go to function pressedon
goto main

pressedon ;Function to handle when button on pin 14 is pressed. This funtion starts the motor and servo sequence
valuespeed = 1020 ;Sets the starting speed of the motor speed variable to the current speed of the motor which should be 0
for valuespeed = 1020 to 2000 step 15 ;Create a loop to handle the increasing speed of the motor
hpwm p11, 2000, valuespeed ;set the speed of the motor which increases each step of the loop
sleep 50 ;give the motor some slight wiggle room so code does not skip

	;HERE IS WHERE I AM ENCOUNTERING PROBLEMS
	if (hservoidle p13) then ;if the servo on pin 13 is idle then move the servo
	if direction = 0 then ;check to see if last direction was clockwise or counterclockwise
		hservo [13\0\1000] ;change the position of the servo
		direction = 1 ;update the servo direction variable
	else ;check to see if last direction was clockwise or counterclockwise
		hservo [13\10000\1000] ;change the position of the servo
		direction = 0 ;update the servo direction variable
	endif
	endif
next ;End of speed ramping loop
onvar = 1 ;set the intial variable of the fail safe if the operator forgets to press the second button
for onvar = 1 to 100000 step 1 ;start the fail safe loop with a nice large quantity
	button P15,0,80,40,workspace2,1,counteroff ;check for the button 2 press; if pressed, go to the function counteroff SEE BELOW
	if (hservoidle p13) then ;if the servo on pin 13 is idle then move the servo
	if direction = 0 then ;check to see if last direction was clockwise or counterclockwise
		hservo [13\0\1000] ;change the position of the servo
		direction = 1 ;update the servo direction variable
	else ;check to see if last direction was clockwise or counterclockwise
		hservo [13\10000\1000] ;change the position of the servo
		direction = 0 ;update the servo direction variable
	endif
	endif
	sleep 50
next
sleep 100

goto main

counteroff ;This handles the second button press by ramping down the speed of the motor and eventually turning off the servo
valuespeed = 2000 ;Sets the starting speed of the motor speed variable to the current speed of the motor which should be Full Forward
for valuespeed = 2000 to 1020 step -50 ;Create a loop to change the speed every 50 steps downward
hpwm p11, 2000, valuespeed ;change the motor speed to a smaller value eventually reaching 0
sleep 50
next
sleep 1000
;ENDED HERE, BUT WILL NEED TO PUT IN CODE TO STOP THE SERVO. THEN THE PROGRAM GOES TO INITIAL LOOP UNTIL FIRST BUTTON IS PRESSED.

goto main[/code]

Sorry… the code came in slightly hideous. Any tips on how to quickly style it so its easier for you all to read?

You could put it into a code block…

Kurt

P.S. - I already did it.

This sounds more like a question for Nathan (Acidtech) of Basic Micro. But I believe the problem is that HSERVO and HPWM are not compatible with each other as both of these sub-systems are using the H8 Timer WTimer.

Kurt

That would make sense. Hopefully Nathan will check the post and confirm that this is the issue. Although its more of a hassle, I may proceed to manually operate the servos using some sort of pulse statements? I have not researched how to do this, but it is probably covered somewhere on the forum or the manual.

Thanks very much Kurte for your help. I beat my head against the wall for 3 hours trying different tweaks to the hservo code before I posted this. By the end I was suspecting a compatibility issue.

If anyone else can confirm that hpwm and hservo cannot operate together due to their use of the same Timer I would appreciate it.

There was an old thread up on the Basic Micro website about this: forums.basicmicro.net/post35705.html?hilit=HPWM HSERVO#p35705

Personally I can not imagine how they would work with each other. HPWM would be setting all of the TimerW IO registers to work. For example I think P11 would be using the register GRA to hold the period and GRD to hold the duty cycle… Which I am pretty sure HSERVO uses these to hold the interrupt timers for when it wishes to change the state of different IO pins and also HSERVO resets the timer counter (TCNT) as part of each 20ms cycle.

Good Luck
Kurt

Solution… Forget about the HPWM and control the Sabertooth with the servo control pulse method. Then you can use HSERVO for everything.

That sounds like a solution. I did not see anything about using HSERVO in the sabertooth documentation. Do you have links to how to use the hservo to control the sabertooth through pulsing? Is it just creating a pwm by pulsing the hservo command at a given frequency? Would I have to calculate out the time between and length of pulses? I am not afraid of reading, so I will also search for a similar post, but if you guys have a link that you know of, I would be grateful for it.

I really appreciate you guys for helping.

I’m not an HSERVO guru. But it essentially creates a pulse length of 500us to 2500us that repeats every 20mS. This is what servos need to receive in order to move or hold position. The sabertooth can respond to these same “servo” pulses. You simply connect ground, power, and signal from the Botbaord II to the Sabertooth. When the pulses are 1500uS the motor stopps, the farther from 1500uS the faster it moves. Above or below sets the direction.

Thanks for all your help guys. I tried out using the HSERVO pulses to control the sabertooth in RC mode, but I was getting mixed results. I am not entirely sure why… Originally I was trying to keep things simple with HPWM or HSERVO commands, but I just went ahead and converted to using the UART on pin 15 and sending packetized serial commands to the sabertooth. It ended up being a lot less painful then I anticipated.

I now have all the components working separately and just need to construct the code in finished form that will handle all the functions and subroutines.

Thanks again, I would probably still be bashing my head against the wall on the hpwm problem if you hadn’t steered me away from it.

PS I talked with Nathan and appreciate you guys sending me to him. He was the one who finally pushed me toward packetized serial to control speed, direction, and ramp all in one command.

Yes, the digital control (packets) should be an improvement over HSERVO. Possibly over PWM as well. More commands, and more work being done for you at a lower level.

Nathan’s great!

Alan KM6VV