Strange servo issue

The circuits/diagrams i posted in this thread a while back have now been fabricated and I'm experiencing a strange problem whereby the PICAXE (a 14m) seems to 'hang' whenever it executes a servo command.
The problem was not observed when the circuit was on a breadboard, and the code has not changed since then. Also, when I wire separate sections of code, eg. a small routine that just moves the servo left-right-left-right etc. works fine. So the problem is only present when running my full program:

Code:
init: 'more symbols
    symbol servo_state_pending = b0 'variables again; how I'll determine what needs doing, quickly
    symbol servo_state_current = b1'
    symbol thrust_state_pending = b2'
    symbol thrust_state_current = b3'
    symbol lift_state_pending = b4'
    symbol lift_state_current = b5'
    symbol servo_pin = 1 'pin number for servo
    symbol servo_middle_pos = 150 'rotation amounts for three servo positions
    symbol servo_left_pos = 140'
    symbol servo_right_pos = 160'
    symbol rfrx_pin = 0 'pin number for incoming serial data from rf receiver
    symbol baudrate = T2400_4 'rf link/serial data rate
    symbol fwd_pin = 4 'pin numbers for power FETs to switch motors on and off
    symbol bkwd_pin = 3'
    symbol lift_pin = 2'
    symbol rxled_pin = 5 'pin number for flashy light

startup: 'set some stuff up
    servo_state_current = "M" 'servo should be in middle...
    thrust_state_current = "O" '...thrust should be off...
    lift_state_current = "O" '...and so should lift
    high rxled_pin '"I've turned on!" again
    pause 1000
    low rxled_pin
    servo servo_pin, servo_middle_pos 'actually move servo incase someone has fiddled while it was off
    pause 100

listen: 'wait for transmission from controller
    serin rfrx_pin, baudrate, ("data"), servo_state_pending,thrust_state_pending, lift_state_pending 'read requests from transmitter into these variables
    high rxled_pin 'show something is happening
    goto receive

receive: 'so what now?
    if servo_state_pending != servo_state_current then 'requested servo position different from current
        gosub srvo 'go and do it
    endif
    if thrust_state_pending != thrust_state_current then 'requested thrust different form current
        gosub thrust 'go and do it
    endif
    if lift_state_pending != lift_state_current then 'requested lift different from current
        gosub lift 'go and do it
    endif
    low rxled_pin 'receive done so turn light off...
    goto listen 'and do it again

srvo: 'move servo around
   if servo_state_pending = "L" then 'want to move to left
        servo servo_pin, servo_left_pos
        pause 100 'give servo a chance to move
    elseif servo_state_pending = "R" then
        servo servo_pin, servo_right_pos 'want to move to right
        pause 100 'give servo a chance to move
    elseif servo_state_pending = "M" then 'want to move to middle
        servo servo_pin, servo_middle_pos
        pause 100 'give servo a chance to move
    endif
    let servo_state_current = servo_state_pending 'update servo state memory
    return 'go back to where we came from

thrust: 'alter thrust fan configuration 
      if thrust_state_pending = "F" then 'want to go forwards
        low bkwd_pin
        high fwd_pin
    elseif thrust_state_pending = "R" then 'want to go backwards
        low fwd_pin
        high bkwd_pin
    elseif thrust_state_pending = "O" then 'All stop, Cap'n
        low fwd_pin
        low bkwd_pin
    endif
    let thrust_state_current = thrust_state_pending 'update thrust state memory
    return 'go back to where we came from

lift: 'alter lift fan configuration
   if lift_state_pending = "I" then 'want to turn it on
        high lift_pin
    elseif lift_state_pending = "O" then 'want to turn it off
        low lift_pin
    endif
    let lift_state_current = lift_state_pending 'update lift state memory
    return 'go back to where we came from
This 'hangs' as soon as it reaches the servo command in the startup section. If that line is commented out, the program operates correctly until it receives a command from the remote control to turn left or right, at which point it hangs again. But this, for example:

Code:
main: serin 0, T2400_4, ("data"), b0
	if b0 = "L" then
		servo 1, 120
		pause 100
	
	else if b0 = "R" then
		servo 1, 180
	else 
		servo 1, 150
	endif
works fine. Until I copy it into the main program, when it then causes hangs. I'm guessing there's some incompatability that I am introducing, but I'll be buggered if i can work out what it is :D
 
Last edited:

Jamster

Senior Member
Might it have somthing to do with the pause 75??;)

Also you mention that it hangs every time it reaches a servo command then go on to say it hangs only at startup.
 
Last edited:

hippy

Ex-Staff (retired)
Is it hanging on the SERVO command or the SERIN ? My guess would be the later.

Replace the SERIN with "Let b0 = 0" and see if it runs then ( accepting the servo will alwys go to position 150 ).
 
Jamster - the pause 75 is just there to give the servo a bit of time to move, as it will be stopped as soon as the PICAXE reaches the serin. And when I said startup, I was referring to the startup: label in the program, which contaisn a servo command.

Hippy - That's what I though, but if I replace the servo commands to just turn on an LED, it works fine, so the serin appears to be functioning.
 

Technical

Technical Support
Staff member
Does the program work if you leave in the servo commnds but replace the real life servo with an LED (do you see it change in brightness)?
 
Does the program work if you leave in the servo commnds but replace the real life servo with an LED (do you see it change in brightness)?
No; the same behaviour is seen. The LED will light, with the brightness depending on the value of the servo command, but will then 'hang' there. The LED will stay on (ie the servo command is continuing to run) but the program does not continue running.

However, this:

Code:
main: serin 0, T2400_4, ("data"), b0
	if b0 = "L" then
	   servo 1, 75
	   pause 200
	else if b0 = "R" then
	   servo 1, 225
	   pause 200
	else
	   servo 1, 150
	endif
	goto main
works correctly, with both servo and LED. :confused:
 

hippy

Ex-Staff (retired)
It does seem some compatability issue with what the codes's integrated with. Perhaps post the full code then we might be able to see what that is. Or comment the rest of the code out, start adding things back until it stops working.
 

hippy

Ex-Staff (retired)
Ah, right. The code in post #1 is subtly different to the code which does work until pasted into that. I can't see any obvious reason it wouldn't work so would suggest commenting it all out except for the code as per post #6, add things in a bit at a time and check it's still working.

My suspicion is still on SERIN but that is only gut feeling. You can move the RXLED control so it lights before SERIN, goes off immediately after which might help identify if it is hanging there. You could also add SERTXD to show where it's getting to.
 
Ah, right. The code in post #1 is subtly different to the code which does work until pasted into that. I can't see any obvious reason it wouldn't work so would suggest commenting it all out except for the code as per post #6, add things in a bit at a time and check it's still working.

My suspicion is still on SERIN but that is only gut feeling. You can move the RXLED control so it lights before SERIN, goes off immediately after which might help identify if it is hanging there. You could also add SERTXD to show where it's getting to.
As ever, your gut feeling proves to be right :) Servo is working now, but the problem seems to be that the receiver is unable to receive more than one byte at a time (I send three bytes: one for the servo and two for controlling two motors). So:

Code:
serin rfrx_pin, baudrate, ("data"), servo_state_pending
is working, but

Code:
serin rfrx_pin, baudrate, ("data"), servo_state_pending ',thrust_state_pending, lift_state_pending
isn't.
 

hippy

Ex-Staff (retired)
In the "isn't working" is the comment starting single-quote just a copy and paste factor or is that really there ? It shouldn't be to read the additional variables.

If the command is correct, reading three bytes, and it's hanging then that suggests three bytes aren't turning up. Perhaps write some shorter test code to see if three bytes are turning up.

I note the "rfrx_pin" which suggests this is from an RF receiver so maybe test with a wired connection to see if it's an issue with RF.
 
In the "isn't working" is the comment starting single-quote just a copy and paste factor or is that really there ? It shouldn't be to read the additional variables.

If the command is correct, reading three bytes, and it's hanging then that suggests three bytes aren't turning up. Perhaps write some shorter test code to see if three bytes are turning up.

I note the "rfrx_pin" which suggests this is from an RF receiver so maybe test with a wired connection to see if it's an issue with RF.
The quote was indeed a mistake, and no matter what I do I can't get it to see more than one byte. Test for one byte (at Rx), get one byte, perfect, every time. Test for 3 bytes, get nothing. They are communicating by radio, but were doing so perfectly (with all three bytes) on a breadboard a few days ago. As I can send one byte fine, I'm inclined to just redesign the code to include all the commands in one byte, using bit variables.
 

hippy

Ex-Staff (retired)
I'd be tempted to do the same but it would nag at me as to why it hadn't worked so it would be worth investigating as you may run into the problem again in the future.

While you have something which works / doesn't work you can fully investigate while you have that opportunity as it may not be so clear cut next time. Or soon if things deteriorate and everything stops working :)
 
Top