Help Please: PICAXE and Robot Boat

Robin Lovelock

Senior Member
Thanks Martin and Hippy. Definitely making progress.

Hippy - could you clarify exactly what you think I need in that modified protol from AUTOP on PC or GPSSppc on iPAQ. Presently I'm only sending one extra blank byte before the sync. Latest version of program seems not always to catch the RS232 commands. I think that was why you thought something was needed - to program around timing problems related to IF PIN3 etc.

My latest version of the program is much smaller and based on your code, with minor typos corrected, etc. Let's see if I can insert it here....

Code:
'SC1.BAS servo controller for robot boat
'input is RS232 group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
 
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 PAUSE 3000

 'test pattern on startup
 for b0 = 0 to 126 step 63
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 3000
 next b0
 PAUSE 3000
   'remember servo positions and initiate
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3

'wait for 3 bytes from RS232,sync, servo N, position P  
Sync:
  If pin3 = 1 Then
    SetFreq M8
    Low 1 : Low 2 : Low 4
    SerIn 3, N4800_8, (127), b12, b13
    b13 = b13 * 91 / 126 + 100
    Select Case b12
      Case 0 : b1 = b13
      Case 1 : b2 = b13
      Case 2 : b3 = b13
    End Select
    SetFreq M4
    Servo 1, b1 ' *
    Servo 2, b2 ' *
    Servo 4, b3 ' *
  End If
  Goto Sync 'back to serial input
You see I've removed the PAUSE allowing the servos to move
because this should not be needed. I can obviously put it back.
However, I'm guessing you may suggest more blank bytes before sync output from AUTOP and GPSSppc.

Martin: I did not miss your polite and subtle hint about doing my own experiments. But as you know, that could be a very slow process when trying to programme around the sort of limitations uncovered on this thread. That's why your picaxe experience is so valuable on this forum. I'm sure I must be telling grandma how to suck eggs :)

Robin
1550 Wed
www.gpss.co.uk/autop.htm

>>>>>>

You can use [code]...[/code] tags which will keep your code formatted correctly.

You need to keep the right frequency at the right time, so I would recommend trying this. I used b0, b1, b2 as the previous servo positions as easy to remeber.

Code:
b0 = 150 : Servo 1, b0
b1 = 150 : Servo 2, b1
b2 = 150 : Servo 4, b2

Sync:
  If pin3 = 1 Then
    Low 1 : Low 2 : Low 4
    SetFreq M8
    SerIn 3, N4800_8, (127), b12, b13
    b13 = b13 * 91 / 126 + 100
    Select Case b12
      Case 0 : b0 = b13
      Case 1 : b1 = b13
      Case 2 : b2 = b13
    End Select
    SetFreq M4
    Servo 1, b0 ' *
    Servo 2, b1 ' *
    Servo 4, b2 ' *
    Pause 3000
  End If
  Goto Sync
You may be able to change all the SERVO commands marked * to SERVOPOS and the first as SERVO and next two as SERVOPOS would be the next best thing if it works. I haven't used servos enough nor have any to test to see if that will work in practice.
 

Robin Lovelock

Senior Member
Hi Folks. Just to say that the latest version of the SC1.BAS
seems to work reliably with GPSSppc on the iPAQ.
That was after what must have been an hours testing
and several hundred RS232 servo commands.

This was with NO CHANGES to that iPAQ RS232 protocol.
Maybe the iPAQ software has delays that already avoid
any timing problems. I'll still be very pleased to hear any
further suggestions, including clarification of that mod.
I assume an extra byte was intended to let IF PIN3
detect the condition and not miss the next sync byte.

Earlier today I ordered some more picaxe bits so I will
soon be building several spare servo controllers.
This version of SC1.BAS should do what we need for now.

Meanwhile work can proceed on other things.
Many Thanks again for your expert and rapid responses
to my dumb questions: very much appreciated.

Robin
1700 Wed
www.gpss.co.uk/autop.htm - robot boat hobby project
www.gpss.co.uk - business and family
www.nhscare.info - charity
 

hippy

Technical Support
Staff member
Added : Seems you solved it while I was responding but, here it is anyway ...

Catching a serial transmission is always a tough call. You probably are catching every other message. A transmission of $00 will put a long high on the output which the "If pin3=1" should always catch, so that should be at the start of the transmission.

You then need to ensure the 127 isn't sent before the PICAXE is ready to receive with its SERIN, but that's likely to be the case with $00 at 4800 baud.

There's a poential possibility that the $00 'pulse' is too long and confusing the SERIN, so $00 may need to become $80, $C0, $E0, $F0, $F8, $FC or $FE ( more likely to be the earlier ones in the list ).

That's the part which needs some experimenting with. With two PICAXE's communicating one can add delays and sort it out that way - Is there a function on the iPAQ which can send the $00, then delay say 5ms ( or longer ) before sending the 126 ?

An alternative may be to send "$00 $FF 127 nn ss" and replace SERIN with

Do : Loop Until pin3 = 0 ' Wait for $00 to clear
Input 3 ' Waste some time to skip start bit of $FF
SerIn 3, N4800_8, (126), b12, b13

Another hint : You don't have to always quote previous replies. If you click on the downwards triangle that takes you to the Quick Reply entry.
 

Robin Lovelock

Senior Member
Thanks Hippy. I'm guessing $00 is hex for binary zero,
and maybe the extra byte that I now have before sync
in AUTOP on the desktop PC is causing the confusion
as you suggest. The iPAQ probably has inbuilt delays.

But no problem: I can continue with reliability testing
on iPAQ and maybe also AUTOP on the PC - and armed
with this knowledge hopefully fix any unreliabity.

I'll leave the quote in below - I already use that quick reply
icon and it stuffs the quoted text in to the box.
I know I could delete it if I wanted to :)

Many Thanks
Robin
www.gpss.co.uk

>>>>


Added : Seems you solved it while I was responding but, here it is anyway ...

Catching a serial transmission is always a tough call. You probably are catching every other message. A transmission of $00 will put a long high on the output which the "If pin3=1" should always catch, so that should be at the start of the transmission.

You then need to ensure the 127 isn't sent before the PICAXE is ready to receive with its SERIN, but that's likely to be the case with $00 at 4800 baud.

There's a poential possibility that the $00 'pulse' is too long and confusing the SERIN, so $00 may need to become $80, $C0, $E0, $F0, $F8, $FC or $FE ( more likely to be the earlier ones in the list ).

That's the part which needs some experimenting with. With two PICAXE's communicating one can add delays and sort it out that way - Is there a function on the iPAQ which can send the $00, then delay say 5ms ( or longer ) before sending the 126 ?

An alternative may be to send "$00 $FF 127 nn ss" and replace SERIN with

Do : Loop Until pin3 = 0 ' Wait for $00 to clear
Input 3 ' Waste some time to skip start bit of $FF
SerIn 3, N4800_8, (126), b12, b13

Another hint : You don't have to always quote previous replies. If you click on the downwards triangle that takes you to the Quick Reply entry.
 

Robin Lovelock

Senior Member
Good Afternoon Gentlemen ! :)

Thanks mostly to Hippy, my little SC1.BAS program (below) does pretty well what is needed to control up to three servos from the RS232 from GPSSppc on the iPAQ, or the AUTOP test program on the desktop PC.

Today Mr Postman brought more goodies, so I've been able to make up more spares of the AXE024 servo controller complete with the extra diode and resistor for the serial input. I also have the USB/RS232 adapter, so I can use the Terminal monitor as well as the RS232 input, to see what is going on, aided by SERTXD Terminal output traces.

I'm now following Hippy's suggestions of investigating unreliabilty of IF PIN3 and SERIN catching all the 3 byte servo commands. Then I can do as he suggests, after proving a modified protocol on AUTOP then GPSSppc on the iPAQ.

Today's tests showed it to be as Hippy thought: it is possible for the SERIN to only pickup the command every other burst of 3 bytes. A single blank byte at the front is not enough.

I've not tried those other byte values he suggested, but I have done tests which may be useful. Precxceding the 3 character burst by up to 11 blank bytes have no effect. 12 or more, including 20,40 and 100 make it work reliably, catching every command. So for the moment, a pudent value seems to be 20. As a matter of interest, 12 bytes at 4800 is about 24 msec.

Sending out a preceeding train of blank bytes is very easy delay solution.

So if Hippy could confirm this makes sense, it could save considerable time testing those alternative byte values. I guess they are not needed now.

Another minor thing: for no apparent reason, other than maybe what servo command was last sent (but I don't see a pattern), we sometimes get the condition of one or more of the three servos doing a regular "twitch". It seems to be roughly every second. I cannot think of a likely reason, other than PIN3 occasionaly answering 1 without incoming serial data. I've yet to investigate this further, with tests on the iPAQ.

Many Thanks for your help in getting us to where we are now.
Robin
www.gpss.co.uk/autop.htm

Code:
'SC1.BAS servo controller for robot boat
'input is RS232 group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre
'v1a 5 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
 
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 PAUSE 3000

 'test pattern on startup
 for b0 = 0 to 126 step 63
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 3000
 next b0
 PAUSE 3000
   'remember servo positions and initiate
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3

'wait for 3 bytes from RS232,sync, servo N, position P  
Sync:
  If pin3 = 1 Then
    SetFreq M8
    Low 1 : Low 2 : Low 4
    SerIn 3, N4800_8, (127), b12, b13
    b13 = b13 * 91 / 126 + 100
    Select Case b12
      Case 0 : b1 = b13
      Case 1 : b2 = b13
      Case 2 : b3 = b13
    End Select
    SetFreq M4
    Servo 1, b1 ' *
    Servo 2, b2 ' *
    Servo 4, b3 ' *
  End If
  Goto Sync 'back to serial input


Added : Seems you solved it while I was responding but, here it is anyway ...

Catching a serial transmission is always a tough call. You probably are catching every other message. A transmission of $00 will put a long high on the output which the "If pin3=1" should always catch, so that should be at the start of the transmission.

You then need to ensure the 127 isn't sent before the PICAXE is ready to receive with its SERIN, but that's likely to be the case with $00 at 4800 baud.

There's a poential possibility that the $00 'pulse' is too long and confusing the SERIN, so $00 may need to become $80, $C0, $E0, $F0, $F8, $FC or $FE ( more likely to be the earlier ones in the list ).

That's the part which needs some experimenting with. With two PICAXE's communicating one can add delays and sort it out that way - Is there a function on the iPAQ which can send the $00, then delay say 5ms ( or longer ) before sending the 126 ?

An alternative may be to send "$00 $FF 127 nn ss" and replace SERIN with

Do : Loop Until pin3 = 0 ' Wait for $00 to clear
Input 3 ' Waste some time to skip start bit of $FF
SerIn 3, N4800_8, (126), b12, b13

Another hint : You don't have to always quote previous replies. If you click on the downwards triangle that takes you to the Quick Reply entry.
 

hippy

Technical Support
Staff member
There's a slight bug in the code which I corrected but you probably saw the original ...

- SetFreq M8
- Low 1 : Low 2 : Low 4

Should be

- Low 1 : Low 2 : Low 4
- SetFreq M8

One should stop the servos which need 4MHz before switching to 8MHz.

As to the padding bytes, the PICAXE executes roughly at 250us per command, so 24ms is much longer than it should need between seeing pin3=1 and SERIN. Don't know what's going on there ( nor what a 'blank byte' is ... $00 ? Try $FF ).

Not sure about the twitching. Make the above SETFREQ change and test again. Does it still twitch when not sending serial data ? If not, it's probably related to receiving serial in some way. If so, it's something else.
 

Robin Lovelock

Senior Member
Well spotted Hippy - I understand and I have swapped the two lines.
Does not stop the servo twitching, but I found that the twitch
is some kind of side-effect of the IF PIN3=1

If I just have the same start of the program,
using SERVO and SERVOPOS to put them to initial positions,
then just have this loop:

Code:
Sync:  
  If pin3 = 1 Then
  end if
  goto sync
- the result is that I get this same twitching effect.

On that "blank byte" - yes $00 (picaxe term for Hex 00)
= 0 decimal, etc, etc :)

Prior to your reply I've built up and tested two extra AXE024 servo controllers and modified the iPAQ protocol to preceed the 3 bytes with 20 $00. Works with both PICAXE and my old KlausCard-Pololu SSCII. But leaving it all running as a reliability test.

Before noticing that IF PIN3 causing the twitch, I tried your earlier suggestions of replacing the SERVO by SERVOPOS inside the sync loop. It needs to be SERVO - but that's just fine since it works, and it looks as if it is not the cause of the twitch.

Robin
1705 Thursday
www.gpss.co.uk/autop.htm

P.S. sorry - should have said - the twitching happens even if no serial input.



There's a slight bug in the code which I corrected but you probably saw the original ...

- SetFreq M8
- Low 1 : Low 2 : Low 4

Should be

- Low 1 : Low 2 : Low 4
- SetFreq M8

One should stop the servos which need 4MHz before switching to 8MHz.

As to the padding bytes, the PICAXE executes roughly at 250us per command, so 24ms is much longer than it should need between seeing pin3=1 and SERIN. Don't know what's going on there ( nor what a 'blank byte' is ... $00 ? Try $FF ).

Not sure about the twitching. Make the above SETFREQ change and test again. Does it still twitch when not sending serial data ? If not, it's probably related to receiving serial in some way. If so, it's something else.
 
Last edited:

hippy

Technical Support
Staff member
If ...

- Sync:
- If pin3 = 1 Then
- end if
- goto sync

Causes twitching it would be interesting to see happens with ...

- Sync:
- goto sync

I cannot see why the IF PIN3 should make any difference and I'm not an expert on servos or what causes such twitching.
 

Robin Lovelock

Senior Member
Hi Hippy. I tried that first of course :)
Did not do anything - as to be expected.
Only with the IF PIN3 did it start twitching.
Robin


If ...

- Sync:
- If pin3 = 1 Then
- end if
- goto sync

Causes twitching it would be interesting to see happens with ...

- Sync:
- goto sync

I cannot see why the IF PIN3 should make any difference and I'm not an expert on servos or what causes such twitching.
 

Robin Lovelock

Senior Member
Hi Hippy. Think I may have programmed around the "twitchy servos". Latest version of the SC1.BAS program is below.

I'm guessing that the twitch has something to do with some background timer process in the picaxe environment. But anyway, my fix, which seems to work, is to switch to 8MHz BEFORE the IF PIN3. After the IF statement, I then switch back to 4MHz and make sure the servos are in correct positions.

Of course, maybe it will work if I just put them to correct positions without that speed change before the IF PIN3 :) So I'll try a few simpler options.

Robin
1745 - soon time to stop work :)
www.gpss.co.uk/autop.htm

Code:
'SC1.BAS servo controller for robot boat
'input is RS232 group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre
'v1b 6 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
  
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 PAUSE 3000

 'test pattern on startup
 for b0 = 0 to 126 step 63
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 3000
 next b0
 PAUSE 3000
   'remember servo positions and initiate
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3

'wait for 3 bytes from RS232,sync, servo N, position P  
Sync:
  SetFreq M8 '1b now before IF PIN3 
  If pin3 = 1 Then  
    sertxd (CR,LF,"Pin3=1")
    Low 1 : Low 2 : Low 4
    SetFreq M8 '1b now after Lows above.
    SerIn 3, N4800_8, (127), b12, b13
    b13 = b13 * 91 / 126 + 100
    Select Case b12
      Case 0 : b1 = b13
      Case 1 : b2 = b13
      Case 2 : b3 = b13
    End Select
    SetFreq M4
    Servo 1, b1 
    Servo 2, b2 
    Servo 4, b3
    pause 3000 '1b give time to travel
  End If
  SetFreq M4 '1b ensure is 4MHz 
  SERVO 1, b1 'and servos correct
  SERVO 2, b2
  SERVO 4, b3
  Goto Sync 'back to serial input
 

hippy

Technical Support
Staff member
In theory that should not work ( or not work reliably ); the repeated SERVO commands would reset the 20ms servo timing frame before any frame ever gets a chance to complete, but if it's working ... what's there to complain about :)
 

Robin Lovelock

Senior Member
Well it's very close to working, but servos twitching every few seconds will soon fail after a few weeks or months at sea :)

Anway, I've got some more useful info: as I anticipated, I did not need to switch speeds - just the three SERVOPOS at the bottom of the loop. Latest version is below your words.

Problem is that SERVOPOS stops the twitching, but the servos are left free - not held in place. If I make these SERVO then power is kept to hold the servos, but I get the regular twitching.

This is a good time to "sleep on it". Maybe I'll come up with a solution that avoids the twitch, or makes it far less frequent, by using both SERVO and SERVOPOS.

I don't want to fall back on my "plan B" - just using those AXE024 as RS232 protocol convertors between the iPAQ and the Pololu SSCII. i.e. just use the RS232 input and output. But I think we are very close - it just needs to be reliable to work without attention for several months at sea :)

Robin
1805
www.gpss.co.uk/autop.htm

P.S. MMMmmmm - saw that "sertxd (CR,LF,"Pin3=1")" inside the loop - I bet that was it - tomorrow :)
P.P.S. no it didn't :) Updated code below to make it clearer at end.

In theory that should not work ( or not work reliably ); the repeated SERVO commands would reset the 20ms servo timing frame before any frame ever gets a chance to complete, but if it's working ... what's there to complain about :)
Code:
'SC1.BAS servo controller for robot boat
'input is RS232 group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre
'v1b 6 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
  
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 PAUSE 3000

 'test pattern on startup
 for b0 = 0 to 126 step 63
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 3000
 next b0
 PAUSE 3000
   'remember servo positions and initiate
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3

'wait for 3 bytes from RS232,sync, servo N, position P  
Sync:
  If pin3 = 1 Then  
    Low 1 : Low 2 : Low 4
    SetFreq M8 '1b now after Lows above.
    SerIn 3, N4800_8, (127), b12, b13
    b13 = b13 * 91 / 126 + 100
    Select Case b12
      Case 0 : b1 = b13
      Case 1 : b2 = b13
      Case 2 : b3 = b13
    End Select
    SetFreq M4
    Servo 1, b1 
    Servo 2, b2 
    Servo 4, b3
    pause 3000 '1b give time to travel
  End If
  'SERVO here avoids twitch but leaves servos limp
  'SERVOPOS holds the servos but gives a regular twitch
  SERVOPOS 1, b1 'ensure servos correct
  SERVOPOS 2, b2
  SERVOPOS 4, b3
  Goto Sync 'back to serial input
 
Last edited:

BeanieBots

Moderator
You don't actually need those servopos commands at all.
The servo command has done it's job and the servo will keep trying to go they have been told to until told otherwise.

You don't need the pause 3000 either for the same reason.
It might be a good idea to seperate the servo commands with a pause 30 though to avoid counter resets between each command.

try this
Code:
'SC1.BAS servo controller for robot boat
'input is RS232 group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre
'v1b 6 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
  
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 PAUSE 3000

 'test pattern on startup
 for b0 = 0 to 126 step 63
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 3000
 next b0
 PAUSE 3000
   'remember servo positions and initiate
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3

'wait for 3 bytes from RS232,sync, servo N, position P  
Sync:
  If pin3 = 1 Then  
    Low 1 : Low 2 : Low 4
    SetFreq M8 '1b now after Lows above.
    SerIn 3, N4800_8, (127), b12, b13
    b13 = b13 * 91 / 126 + 100
    Select Case b12
      Case 0 : b1 = b13
      Case 1 : b2 = b13
      Case 2 : b3 = b13
    End Select
    SetFreq M4
    Servo 1, b1 
   pause 30
    Servo 2, b2 
  pause 30
    Servo 4, b3
  pause 30
  End If
Goto Sync 'back to serial input
 

Robin Lovelock

Senior Member
Thanks Beanibots. Do you know why servo twitches are caused by the simple loop......

sync:
IF PIN3=1 THEN
ENDIF
GOTO sync

?

Robin
1900 Thursday

You don't actually need those servopos commands at all.
The servo command has done it's job and the servo will keep trying to go they have been told to until told otherwise.

You don't need the pause 3000 either for the same reason.
It might be a good idea to seperate the servo commands with a pause 30 though to avoid counter resets between each command.

try this
Code:
'SC1.BAS servo controller for robot boat
'input is RS232 group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre
'v1b 6 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
  
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 PAUSE 3000

 'test pattern on startup
 for b0 = 0 to 126 step 63
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 3000
 next b0
 PAUSE 3000
   'remember servo positions and initiate
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3

'wait for 3 bytes from RS232,sync, servo N, position P  
Sync:
  If pin3 = 1 Then  
    Low 1 : Low 2 : Low 4
    SetFreq M8 '1b now after Lows above.
    SerIn 3, N4800_8, (127), b12, b13
    b13 = b13 * 91 / 126 + 100
    Select Case b12
      Case 0 : b1 = b13
      Case 1 : b2 = b13
      Case 2 : b3 = b13
    End Select
    SetFreq M4
    Servo 1, b1 
   pause 30
    Servo 2, b2 
  pause 30
    Servo 4, b3
  pause 30
  End If
Goto Sync 'back to serial input
 

BeanieBots

Moderator
It shouldn't:confused:
Maybe poor layout and/or inadequate decoupling.

BTW, no need to quote with every reply, just reply. Makes it easier to read.
 

Robin Lovelock

Senior Member
Good Morning Gentlemen. The latest version of SC1.BAS is below, with comments which explain how we are attempting to program around known restrictions in the picaxe system. e.g. need to switch between 4MHz (for SERVO/SERVOPOS) and 8MHz (for SERIN at 4800 baud).

Let me summarize where we are: earlier in the week we reached the stage where the program could perform it's function, of taking RS232 commands from the robot boat iPAQ computer and controlling up to 3 servos. However, the servos were allowed to be "limp" and not held in position. This may be OK for use with highly geared servos which can mechanically hold position.

Yesterday we succeeded in using Hippy's idea of using IF PIN3 so that the swiching to 8MHz was brief - to read the RS232 with SERIN - before switching back to 4MHz. This enabled SERVO/SERVOPOS to hold the servos at their required position. i.e. not be limp. Unfortunately, use of IF PIN3 causes twitching of the servos - a potential source of long term unreliabilty.

Nobody seems to know why the simple use of IF PIN3 in a loop causes the twitching. We must assume it is interference with the backround picaxe software that holds the servos in position. There may be work-arounds, and that is what I'm seeking now. I've obviously tried a few experiments, using SERVO and SERVOPOS, resulting in the version of SC1.BAS below.

This morning's version of the program reduces the twitching as much as I have been able. Sometimes there is no twitch after startup or a particular RS232 command to move a servo. Sometimes there are a few twitches that then stop. Sometimes the twitch is regular - at perhaps 2Hz. Sometimes less frequent.

I am hoping for suggestions based on knowledge, even if there appears to be no experience on the Forum of actually using servos with serial input. It seems the key knowledge right now relates to what is going on in the background, and how IF PIN3 might affect the servo positioning.

Let me repeat my thanks to BEANIEBOTS and HIPPY for their valuable input. Future suggestions will be most welcome.

Robin
1140 Friday
www.gpss.co.uk/autop.htm

Code:
'SC1.BAS servo controller for robot boat
'v1b 7 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 
'input is serial RS232 input group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre

'switching between 4MHz and 8MHz is done to program
'around the restriction in the PICAXE system that
'SERVO/SERVOPOS only works at 4MHz whereas
'SERIN at 4800 baud only works at 8MHz
'The use of IF PIN3 THEN allows the switch
'to 8MHz to be brief, allowing the servos to be held
'in position rather than allowed to go limp.
'However use of IF PIN3 causes occasional twitching
'of servos for an unkown reason.- maybe in the PICAXE system.
'We hope to program around this in a future version
'since unwanted twitching of servos may decrease their life.

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
  
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 'test pattern: fully clockwise, middle, anti-clockwise..
 for b0 = 0 to 126 step 63 
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 2000
 next b0

 'remember servo positions and start at centre positions.
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3
 
'wait for 3 bytes from RS232,sync, servo N, position P  
Sync:
  If pin3 = 1 Then 
    Low 1 : Low 2 : Low 4 'switch off servos
    SetFreq M8 '8MHz so SERIN RS232 input works
    SerIn 3, N4800_8, (127), b12, b13 'Sync,Servo,Position
    SetFreq M4 'back to 4MHz so servos work
    b13 = b13 * 91 / 126 + 100 'scale position 100 to 191
    Select Case b12 'remember positions of each servo
      Case 0 : b1 = b13
      Case 1 : b2 = b13
      Case 2 : b3 = b13
    End Select
    Servo 1, b1 'switch servos back on to latest positions
    Servo 2, b2 
    Servo 4, b3 
    Servopos 1, b1 
    Servopos 2, b2 
    Servopos 4, b3
  End If
  Goto Sync 'back to serial input
 
Last edited:

hippy

Technical Support
Staff member
Your program seem to randomly change. I can appreciate you are trying to make it work and clutching a straws but it's hard to nail down an issue when the goal posts keep moving.

You have now moved the SETFREQ M4 to before doing the math; why ? All that does is slow down the time to restarting the servos.

You now have SERVO followed by SERVOPOS; why ? That will achieve nothing extra.

If the problem is with ...

Sync:
If pin3 = 1 Then
End If
Goto Sync

Nothing altering within the IF/END IF will fix that. Did you do the test earlier ? What happens with

Sync:
Goto Sync

Does that cause any twitching ?

Is twitching on one specific servo ? Different servos ? All servos twitch together ? Seperately ? Does it depend on position of servo ?
 

Robin Lovelock

Senior Member
Thanks Hippy. The versions of SC1.BAS that I publish here are after quite a few experimental tests - with real servos of course. Sorry if some of these tests resulted in changes that seemed random.

I thought I answered some of your questions earlier, but no problem:

A loop with just "sync: goto sync" does not cause servo twitching.
This satisfied me that the twitch is not simply due to a background process.

Just adding the test on PIN3 is sufficient to cause the twitching.
i.e. it is not something we were doing in the block.
This may be a clue on the source of twitching - in the picaxe background.
Do you or others know in depth what this software is doing ?
What effect IF PIN3 would have on it ?

You are right, without knowledge of why we get the twitch, it is difficult to fix. But I did reduce it considerably by my addition of those SERVOPOS statements.

The twitching tends to be quite random, including it not happening at all.
The twitching process is triggered by startup, or by another RS232 command.
Then we might get no twitching at all, or a brief period of twitching, or
a regular twitch which could be as fast as 2Hz but might be less frequent.
The servo that twitches may not be the one that the RS232 command changed.
I've not seen more than one servo repeatedly twitch for a long time.
They all may twitch at the instant the command is given, even though only one is to change position.

You are of course absolutely right that it does not make sense just to keep experimenting without at least some knowledge of the cause.

In an ideal World someone would have done this RS232 control of servos with the PICAXE controller with success, and we could be confident that our efforts are not being wasted. It is possible that the PICAXE hardware and software is not capable of doing the job. However, we are so close, I am hopeful it can be done.

I really appreciate your feedback - particularly where you declare your doubts or limitations. That shows your maturity and experience - and avoids me wasting time here :)

Robin
www.gpss.co.uk/autop.htm
1240 Friday
 

hippy

Technical Support
Staff member
Okay ... I connected a servo to an 08M and can see some twitching which seems to vary on position and a number of other things. No idea why IF PIN3 should affect things. Using PULSOUT instead of SERVO seems to be twitch-free and that may be the best solution.

This seems rock-solid but I only have one servo and cannot test any SERIN. By altering the timing it is possible to run everything at 8MHz so no need to change back and forth to 4MHz. Note the use of word variables and interrupts ...

Code:
#Picaxe 08M

SetFreq M8

w1 = 320 ' 160 @ 4MHz
w2 = 320 ' 160 @ 4MHz
w3 = 320 ' 160 @ 4MHz

SetInt %01000, %01000

w0 = 4000 - w1 - w2 - w3 / 100
Do
  Pause      w0
  Pulsout 1, w1 
  Pulsout 2, w2 
  Pulsout 4, w3 
Loop

Interrupt:
  b12 = 0  ' *** SERIN 3, N4800_8, (127), b12, b13
  w0 = 300 ' *** w0 = b13 ???
  Select case b12
    Case 0 : w1 = w0
    Case 1 : w2 = w0
    Case 2 : w3 = w0
  End Select
  w0 = 4000 - w1 - w2 - w3 / 100
  Pause w0
  SetInt %01000, %01000
  Return
 

hippy

Technical Support
Staff member
Also, add these at the top of the program ...

- Symbol MIN_INPUT = 0
- Symbol MAX_INPUT = 126
- Symbol GAP_INPUT = MAX_INPUT - MIN_INPUT

- Symbol MIN_SERVO = 200
- Symbol MAX_SERVO = 400
- Symbol GAP_SERVO = MAX_SERVO - MIN_SERVO

And add this where you need to calculate w0 from b13 ...

- w0 = b13 Min MIN_INPUT Max MAX_INPUT - MIN_INPUT * GAP_SERVO / GAP_INPUT + MIN_SERVO


You'll need to adjust MIN_SERVO and MAX_SERVO as appropriate to the limits of travel and then b0 as 0 to 126 should move the entire range. Not tested though but confident the theory is right.
 
Last edited:

hippy

Technical Support
Staff member
A thought ... The PICAXE 08M uses an internal oscillator which can drift with temperature and voltage and that affects timing, including any pulse lengths put out which therefore will affect where a servo points to. It could potentially affect the reliability of comms if the baud rate drifts.

Not sure if any of that will affect things in reality but thought I'd mention it. It's not something I'd particularly worry about at this stage.
 

BeanieBots

Moderator
The bulk of my work with servos was some ago and before the introduction of 'servopos'. Hence, I have had considerable experience of using pulsout in preference to servo. It is begining to look like this might be a serious option for your project.

I have NEVER experienced any interaction between basic 'if pin' type commands and servo but I've not done exhaustive tests with 08M and servo.

If there is some sort of interaction (which I totally fail to understand any reason for), then it possible that it might relate to a specific firmware version.

Can you please indicate which firmware version you have and just for completeness, which PE version?

I have an assortment of servos to hand and will try to replicate your issue.
(excluding the serin part).
I will also put a 'scope on the OPs and see if there really is any interaction on the signal.

Many servos have a defined deadband and/or hysterisis in their control circuit. Depending on the internal servo gain and gear backlash between drive and feedback pot, this can on occaisions manifest as 'twitching' even when driven with a rock solid control signal.
Can you please give make and model of the servos you are using?

If there does prove to be an interaction between the pin reading and servo, I am quite confident we can work around it by use of pulsout. I am not convinced that there is any interaction and your observations may just be coincidental but the proof either way will only be found by controlled testing.

I will be unable to dedicate any time to this until Mon/Tue so meanwhile, please try these three short test programs on your equipment and comment on any observations.

Code:
servo 1,150
do
do:loop while pin3=0
do:loop while pin3=1
loop
Code:
servo 1,150
do
do:pause 30:loop while pin3=0
do:pause 30:loop while pin3=1
loop
Code:
do
do:pulsout 1,150:pause 30:loop while pin3=0
do:pulsout 1,150:pause 30:loop while pin3=1
loop
EDIT:
Can you also please give details of your power supply?
 
Last edited:

Robin Lovelock

Senior Member
Well Done Hippy ! :)

I'm sure you will be as amazed as myself to see that your code, plugged into v1c of SC1.BAS below seems to work absolutely perfectly ! :)

This includes handling of the RS232 commands with SERIN, scaling of the servo position, and control of the servos without twitching. They are held under power and not limp. All as it should be, and now ready for reliability tests.

You may be amused by my quick changes to the code, including thanks to yourself, and the fact that I've left the start of the program unchanged, with the test pattern using SERVO/SERVOPOS. I obviously then switched it off.

Many Thanks for your good work.
It seems we have what we need.
Have a Great Weekend :)

Robin
www.gpss.co.uk/autop.htm

P.S. Thanks Beaniebots: your posting above came in as I was typing this one.
Let me know if you need any more info, for your own purposes.
I'm using two GWS25 S125 1T/2BB servos and an old Futaba one.
i.e. effects did not relate to type of servo.
The 08M chips were purchased from PICAXE in the past week.
Robin
1420


Code:
'SC1.BAS servo controller for robot boat
'v1c 7 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 
' - with a great deal of help from HIPPY on Picaxeforum.co.uk :-)
'input is serial RS232 input group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre

'switching between 4MHz and 8MHz was done to program
'around the restriction in the PICAXE system that
'SERVO/SERVOPOS only works at 4MHz whereas
'SERIN at 4800 baud only works at 8MHz
'The use of IF PIN3 THEN allows the switch
'to 8MHz to be brief, allowing the servos to be held
'in position rather than allowed to go limp.
'However use of IF PIN3 causes occasional twitching
'of servos for an unkown reason.- maybe in the PICAXE system.
'We hope to program around this in a future version
'since unwanted twitching of servos may decrease their life.

'latest version does not need to switch speed or use IF PIN3 
'because it uses PULSOUT instead of SERVO/SERVOPOS
'However, SERVO/SERVOPOS are used at the start for the test pattern.

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
  
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 'test pattern: fully clockwise, middle, anti-clockwise..
 for b0 = 0 to 126 step 63 
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 2000
 next b0

 'remember servo positions and start at centre positions.
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3
 PAUSE 3000 'allow servos time to travel
 Low 1 : Low 2 : Low 4 'switch off SERVO background

 
'this is the new experimental code from Hippy
SetFreq M8
Symbol MIN_INPUT = 0
Symbol MAX_INPUT = 126
Symbol GAP_INPUT = MAX_INPUT - MIN_INPUT

Symbol MIN_SERVO = 200
Symbol MAX_SERVO = 400
Symbol GAP_SERVO = MAX_SERVO - MIN_SERVO

w1 = 320 ' 160 @ 4MHz
w2 = 320 ' 160 @ 4MHz
w3 = 320 ' 160 @ 4MHz

SetInt %01000, %01000

w0 = 4000 - w1 - w2 - w3 / 100
Do
  Pause      w0
  Pulsout 1, w1 
  Pulsout 2, w2 
  Pulsout 4, w3 
Loop

Interrupt:
  SERIN 3, N4800_8, (127), b12, b13
  w0 = b13 Min MIN_INPUT Max MAX_INPUT - MIN_INPUT * GAP_SERVO / GAP_INPUT + MIN_SERVO
  'w0 = b13 * 91 / 126 + 100 'scale position 100 to 191

  Select case b12
    Case 0 : w1 = w0
    Case 1 : w2 = w0
    Case 2 : w3 = w0
  End Select
  w0 = 4000 - w1 - w2 - w3 / 100
  Pause w0
  SetInt %01000, %01000
  Return


 
'old v1b stuff below not being used - will soon be removed.
  
 
'wait for 3 bytes from RS232,sync, servo N, position P  
'Sync:
'  If pin3 = 1 Then 
'    Low 1 : Low 2 : Low 4 'switch off servos
'    SetFreq M8 '8MHz so SERIN RS232 input works
'    SerIn 3, N4800_8, (127), b12, b13 'Sync,Servo,Position
'    SetFreq M4 'back to 4MHz so servos work
'    b13 = b13 * 91 / 126 + 100 'scale position 100 to 191
'    Select Case b12 'remember positions of each servo
'      Case 0 : b1 = b13
'      Case 1 : b2 = b13
'      Case 2 : b3 = b13
'    End Select
'    Servo 1, b1 'switch servos back on to latest positions
'    Servo 2, b2 
'    Servo 4, b3 
'    Servopos 1, b1 
'    Servopos 2, b2 
'    Servopos 4, b3
'  End If
'  Goto Sync 'back to serial input
 
Last edited:

BeanieBots

Moderator
Well it's great you've got a fix and as Hippy has proved, a pulsout solution did the job.
Nonetheless, tests still need to be done to get to the roots of this issue.
Unfortunatley I don't have any sail winch type servos to do like for like testing but I'll concentrate on analysis of the control pulses.

It would be useful to know your supply type.
Is it 4X 1.2v NiMh cells direct to both 08M and servos or do you some other arrangement?
 

Robin Lovelock

Senior Member
Recent tests to investigate the servo twitching were here on the desktop PC with just one supply of 4 x 1.5v Duracell. Obviously not following advice on keeping servo power seperate, but symptoms indicate it's not an interference problem. On the robot boat we use a common supply of 4 x 1.2 NiMh.
But LOTS in parallel to give about 12AH topped up by solar panels.

I'm a happy bunny today - not only did that code from Hippy fix the problem, but another Forum suggested I remove the internal battery from the iPAQ - result was halving of our power consumption. The boat needs to survive several days of dull weather if on a mission taking many months.

Robin
www.gpss.co.uk/autop.htm
 

Robin Lovelock

Senior Member
Hi Folks. I'm hoping you can give me a lead on how best to inlcude a timer mechanism into the program that you so kindly helped me with for our prototype small robot boat to sail the Atlantic, and maybe other places.

The details of our iPAQ computer/GPS Autopilot are on www.gpss.co.uk/autop.htm including the amusing "Snoopy Sails!" video.

On my last posting on this thread I was a very happy bunny because we had managed a neater PICAXE based solution for the servo controller that takes RS232 commands from the iPAQ computer, doing the navigation and steering the boat.

We have been working on reducing the power consumption of the system - mostly the 120mA+ consumed by the iPAQ computer, GPS and servos. This power must be maintained by charging the 5v batteries from solar panels, and this will be a problem when there are several cludy days.

Our latest idea is to use the PICAXE as a power timer, in addition to controlling the one or two servos. The GPS and computer will only be switched on for a small proportion of the time, to check where the boat is going and re-adjust the steering - which uses a vane-rudder.

The PICAXE only consumes perhaps 1mA, so, even with servos left on, this will make a huge difference to average power consumption and the number of solar panels we need. Also, to how many days without sun it will work.

The iPAQ program can be modified to send an instruction to the PICAXE to say how long to switch off the power. This might be many tens of minutes or hours, if it's a long way to the next destination waypoint. Or it might be just a minute or two when within a few hundred yards.

It could be done with a completely seperate PICAXE, doing the timer function, and sharing the same RS232 input from the iPAQ. However, the neater solution would be a change to our existing board and PICAXE program.

I've put in comments and very minor changes, to illustrate my thoughts in the source code below. I could not hope for Hippy to tell me the actual code changes as he did last time - thanks Hippy - but maybe you can point me at the most relevant feature compatible with the existing program which exploits the interrupt mechanism.

Many Thanks in advance.
Robin
www.gpss.co.uk

Code:
'SC1.BAS servo controller for robot boat
'v1e 27 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 
' - with a great deal of help from HIPPY on Picaxeforum.co.uk :-)
'input is serial RS232 input group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre

'switching between 4MHz and 8MHz was done to program
'around the restriction in the PICAXE system that
'SERVO/SERVOPOS only works at 4MHz whereas
'SERIN at 4800 baud only works at 8MHz
'The use of IF PIN3 THEN allows the switch
'to 8MHz to be brief, allowing the servos to be held
'in position rather than allowed to go limp.
'However use of IF PIN3 causes occasional twitching
'of servos for an unkown reason.- maybe in the PICAXE system.
'We hope to program around this in a future version
'since unwanted twitching of servos may decrease their life.

'Version 1d did not need to switch speed or use IF PIN3 
'because it uses PULSOUT instead of SERVO/SERVOPOS
'However, SERVO/SERVOPOS are used at the start for the test pattern.

'Version 1d uses Pin4 (originally 3rd servo) as a timed switch
'to permit the computer to switch off power for a time
'for this the instruction is sync,9,time
'e.g. 127,9,15 = switch off for 15 minutes
'code below is unfinished. i.e. need timing in loop ?

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
  
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 'test pattern: fully clockwise, middle, anti-clockwise..
 for b0 = 0 to 126 step 63 
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   '1d SERVOPOS 4, b3 'move servo 2
   PAUSE 2000
 next b0

 'remember servo positions and start at centre positions.
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 '1d b3 = 146 : SERVOPOS 4, b3
 PAUSE 3000 'allow servos time to travel
 Low 1 : Low 2 : '1d Low 4 'switch off SERVO background

 
'this is the code from Hippy
SetFreq M8
Symbol MIN_INPUT = 0
Symbol MAX_INPUT = 126
Symbol GAP_INPUT = MAX_INPUT - MIN_INPUT

Symbol MIN_SERVO = 200
Symbol MAX_SERVO = 400
Symbol GAP_SERVO = MAX_SERVO - MIN_SERVO

w1 = 320 ' 160 @ 4MHz
w2 = 320 ' 160 @ 4MHz
w3 = 320 ' 160 @ 4MHz

SetInt %01000, %01000

w0 = 4000 - w1 - w2 - w3 / 100
Do
  Pause      w0
  Pulsout 1, w1 
  Pulsout 2, w2 
  'extra timing logic needed here ? 
  'e.g. use of PIN4 HIGH or PIN4 LOW ?
  '1d Pulsout 4, w3 
Loop

Interrupt:
  SERIN 3, N4800_8, (127), b12, b13
  w0 = b13 Min MIN_INPUT Max MAX_INPUT - MIN_INPUT * GAP_SERVO / GAP_INPUT + MIN_SERVO
  'w0 = b13 * 91 / 126 + 100 'scale position 100 to 191

  Select case b12
    Case 0 : w1 = w0 'vane rudder
    Case 3 : w2 = w0 '1d Wing-Sail was Case 1
    Case 2 : w3 = w0 'or sail winch
    case 9 : 'PIN4 LOW and set timer ?
  End Select
  w0 = 4000 - w1 - w2 - w3 / 100
  Pause w0
  SetInt %01000, %01000
  Return


 
'old v1b stuff below not being used - will soon be removed.
  
 
'wait for 3 bytes from RS232,sync, servo N, position P  
'Sync:
'  If pin3 = 1 Then 
'    Low 1 : Low 2 : Low 4 'switch off servos
'    SetFreq M8 '8MHz so SERIN RS232 input works
'    SerIn 3, N4800_8, (127), b12, b13 'Sync,Servo,Position
'    SetFreq M4 'back to 4MHz so servos work
'    b13 = b13 * 91 / 126 + 100 'scale position 100 to 191
'    Select Case b12 'remember positions of each servo
'      Case 0 : b1 = b13
'      Case 1 : b2 = b13
'      Case 2 : b3 = b13
'    End Select
'    Servo 1, b1 'switch servos back on to latest positions
'    Servo 2, b2 
'    Servo 4, b3 
'    Servopos 1, b1 
'    Servopos 2, b2 
'    Servopos 4, b3
'  End If
'  Goto Sync 'back to serial input
 

hippy

Technical Support
Staff member
Should be a fairly simple couple of changes ....

Code:
Do
  Pause      w0
  Pulsout 1, w1 
  Pulsout 2, w2 
  Pulsout 4, w3
  If w4 = 0 Then
    High 0
  Else
    w4 = w4 - 1
  End If
Loop
Code:
Case 9: w4 = b13 * 3000 ' w4 = b13 * 60 * 1000 / 20
        Low 0
Pin 0 is used as the power out pin, high is on, low is off. w4 is the timer which counts down in 20ms intervals until power-up.

Your "127,9,minutes" command will be limited to 21 minutes maximum. You can test operation using a LED+R on pin 0.
 
Last edited:

Robin Lovelock

Senior Member
Brilliant ! Many Thanks yet again Hippy. Not just for the software notes but that lead on Pin 0 - maybe I won't need to add a power switching chip, since the rest of the system may draw several hundred milliamps. I'll look at the documentation and get myself up to speed on this pin 0, and then try those software changes.
 

hippy

Technical Support
Staff member
The PICAXE can only deliver 25mA power max through an I/O pin so if you need more than that you need some external hardware.

If you want to replace the servo on Pin 4 with the Power-On signal ( rather than use pin 0 ), you can do that, but update all the 'w0=' pause timing calculations to remove w3 ...

w0 = 4000 - w1 - w2 / 100
 

Robin Lovelock

Senior Member
I thought I better run this past you, to make sure I've used your good advice OK. My updated program is below - but not yet tested with the serial interface again.

Hardware: If I understood you correctly, it seems the neatest solution is for me to use Pin0 as the power switch, and keep my three servos as they are. This means that, after I've loaded the new program, I move the Pin0 jumper on the board, so it connects to a new lead, currently into a voltmeter, which will be going to the new power switch chip.

I did this, and the simple Pin0 toggling code (now commented out) seemed to work as it should. i.e. OFF for 1 sec then ON for 2 secs, etc, etc.

I then put in my interpretation of your changes, the main difference being use of Pin0 and no changes to the other Pins used for the three servos. Nice that I can still have three servos if needed :)

I put in an extra IF for your W4 based power switch timer since I think it may have been needed - so the switch off only happens if the iPAQ requests it.

I did not understand your /20 in the :
Case 9 : w4 = b13 * 3000 ' w4 = b13 * 60 * 1000 / 20
Low 0 'switch OFF and start timer to switch ON.
- but that's probably me being thick.
Is it you are suggesting the delay be in 3 sec increments ?
If so, it might not be a bad idea for me to increase that a bit more,
to increase the maximum delay possible.

Many Thanks.
Robin
www.gpss.co.uk/autop.htm

Code:
'SC1.BAS servo controller for robot boat
'v1e 27 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 
' - with a great deal of help from HIPPY on Picaxeforum.co.uk :-)
'input is serial RS232 input group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre

'switching between 4MHz and 8MHz was done to program
'around the restriction in the PICAXE system that
'SERVO/SERVOPOS only works at 4MHz whereas
'SERIN at 4800 baud only works at 8MHz
'The use of IF PIN3 THEN allows the switch
'to 8MHz to be brief, allowing the servos to be held
'in position rather than allowed to go limp.
'However use of IF PIN3 causes occasional twitching
'of servos for an unkown reason.- maybe in the PICAXE system.
'We hope to program around this in a future version
'since unwanted twitching of servos may decrease their life.

'Version 1d did not need to switch speed or use IF PIN3 
'because it uses PULSOUT instead of SERVO/SERVOPOS
'However, SERVO/SERVOPOS are used at the start for the test pattern.

'Version 1e uses Pin0 as a timed switch
'to permit the computer to switch off power for a time
'for this the instruction is sync,9,time
'e.g. 127,9,15 = switch off for 15 minutes
'code below is unfinished. i.e. need timing in loop ?

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
  
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 'test pattern: fully clockwise, middle, anti-clockwise..
 for b0 = 0 to 126 step 63 
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 2000
 next b0

 'remember servo positions and start at centre positions.
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3
 PAUSE 3000 'allow servos time to travel
 Low 1 : Low 2 : Low 4 'switch off SERVO background
 
 '1e test toggling of pin0 - seems to work OK
 'do
 '  LOW 0  'switch off for 1 sec
 '  PAUSE 1000
 '  HIGH 0 'switch on for 2 secs
 '  PAUSE 2000
 'loop

 
'this is the code from Hippy
SetFreq M8
Symbol MIN_INPUT = 0
Symbol MAX_INPUT = 126
Symbol GAP_INPUT = MAX_INPUT - MIN_INPUT

Symbol MIN_SERVO = 200
Symbol MAX_SERVO = 400
Symbol GAP_SERVO = MAX_SERVO - MIN_SERVO

w1 = 320 ' 160 @ 4MHz
w2 = 320 ' 160 @ 4MHz
w3 = 320 ' 160 @ 4MHz
w4 = -1  '1e power switch timer. -1 = inactive.

SetInt %01000, %01000

w0 = 4000 - w1 - w2 - w3 / 100
Do
  Pause      w0
  Pulsout 1, w1 
  Pulsout 2, w2 
  Pulsout 4, w3
  if w4 >=0 then '1e if power switch timer is active
    If w4 = 0 Then 'pin0 used as power switch
      High 0 'switch ON
    Else
      w4 = w4 - 1 'count down before above switch ON
    End If
  endif 
Loop

Interrupt:
  SERIN 3, N4800_8, (127), b12, b13
  w0 = b13 Min MIN_INPUT Max MAX_INPUT - MIN_INPUT * GAP_SERVO / GAP_INPUT + MIN_SERVO
  'w0 = b13 * 91 / 126 + 100 'scale position 100 to 191

  Select case b12
    Case 0 : w1 = w0 'vane rudder
    Case 3 : w2 = w0 '1d Wing-Sail was Case 1
    Case 2 : w3 = w0 'or sail winch
    Case 9 : w4 = b13 * 3000 ' w4 = b13 * 60 * 1000 / 20
             Low 0 'switch OFF and start timer to switch ON.
  End Select
  w0 = 4000 - w1 - w2 - w3 / 100
  Pause w0
  SetInt %01000, %01000
  Return
 

hippy

Technical Support
Staff member
You don't need the extra IF ( and w4 will always be >= 0 anyway ).

The 'w4 = b13 * 3000" is because the "w4=w4-1" is in a 20ms loop, so it will only decrement once every 20ms. 1 minute = 60 x 1000ms, 1 minute is 60000 x 1ms ticks or 3000 x 20ms ticks.
 

Robin Lovelock

Senior Member
Sounds Good Hippy, and before I saw your last posting above I had started hardware testing with a voltmeter on Pin0, with the board jumper moved, and sending the new sync,9,delay command via RS232 in addition to servo commands - which still work.

It works ! Or very nearly - until I made a change which I assumed may have been a deliberate mistake by you to make me think :) The program below is very close to working, with the remaining issue being tweaking of that time delay.

I added the line on startup to initiate pin0 to ON.
When I sent sync,9,1 by RS232 it switched off as I expected
but stayed off - until I grew tired of waiting.

Then I saw what may have been your deliberate mistake:
w4 = w4 - 1 'count down before above switch ON
I changed this to:
w4 = w4 - w0 'count down before above switch ON
- and it's now close to giving the time delay I would expect.
I could obviously experiment, but it helps if I understand it.
Your latest posting will probably help me, but if that
-1 should have been -w0 it's best I know.

Anyway, once again I can see that it's very close to
what's needed, with far less time spent on it here,
due to your expert help. Many Thanks again.

Tomorrow I'll probably be buying those power control chips.
I think they may be called Darlington arrays.
In my Uni days, in the 1960s, I vaguely remember "Darlington Pairs".
That was still transistors - not quite thermionic valves :)

Robin
www.gpss.co.uk/autop.htm


Code:
'SC1.BAS servo controller for robot boat
'v1e 27 Aug 2009 (c) Robin Lovelock www.gpss.co.uk/autop.htm 
' - with a great deal of help from HIPPY on Picaxeforum.co.uk :-)
'input is serial RS232 input group of 3 bytes: 
'127=sync, 0,1 or 2=servo number, 0 to 126 servo position
'the input servo position from RS232 is 0 to 126, 64=centre
'position sent to servo system is 100 to 191, 146=centre

'switching between 4MHz and 8MHz was done to program
'around the restriction in the PICAXE system that
'SERVO/SERVOPOS only works at 4MHz whereas
'SERIN at 4800 baud only works at 8MHz
'The use of IF PIN3 THEN allows the switch
'to 8MHz to be brief, allowing the servos to be held
'in position rather than allowed to go limp.
'However use of IF PIN3 causes occasional twitching
'of servos for an unkown reason.- maybe in the PICAXE system.
'We hope to program around this in a future version
'since unwanted twitching of servos may decrease their life.

'Version 1d did not need to switch speed or use IF PIN3 
'because it uses PULSOUT instead of SERVO/SERVOPOS
'However, SERVO/SERVOPOS are used at the start for the test pattern.

'Version 1e uses Pin0 as a timed switch
'to permit the computer to switch off power for a time
'for this the instruction is sync,9,time
'e.g. 127,9,15 = switch off for 15 minutes
'code below is unfinished. i.e. need timing in loop ?

 #Picaxe 08M
 SETFREQ M4 'standard 4MHz
  
 SERVO 1,146: SERVO 2,146: SERVO 4,146 'middle positions
 'test pattern: fully clockwise, middle, anti-clockwise..
 for b0 = 0 to 126 step 63 
   b13 = b0 * 91 / 126 + 100
   b1=b13: b2=b13: b3=b13
   SERVOPOS 1, b1 'move servo 0
   PAUSE 1000
   SERVOPOS 2, b2 'move servo 1
   PAUSE 1000
   SERVOPOS 4, b3 'move servo 2
   PAUSE 2000
 next b0

 'remember servo positions and start at centre positions.
 b1 = 146 : SERVOPOS 1, b1
 b2 = 146 : SERVOPOS 2, b2
 b3 = 146 : SERVOPOS 4, b3
 PAUSE 3000 'allow servos time to travel
 Low 1 : Low 2 : Low 4 'switch off SERVO background
 
 
'this is the code from Hippy - with recent changes
SetFreq M8
Symbol MIN_INPUT = 0
Symbol MAX_INPUT = 126
Symbol GAP_INPUT = MAX_INPUT - MIN_INPUT

Symbol MIN_SERVO = 200
Symbol MAX_SERVO = 400
Symbol GAP_SERVO = MAX_SERVO - MIN_SERVO

w1 = 320 ' 160 @ 4MHz
w2 = 320 ' 160 @ 4MHz
w3 = 320 ' 160 @ 4MHz
w4 = -1  '1e power switch timer. -1 = inactive
HIGH 0 '1e power switch starts in ON state.

SetInt %01000, %01000

w0 = 4000 - w1 - w2 - w3 / 100
Do
  Pause      w0
  Pulsout 1, w1 
  Pulsout 2, w2 
  Pulsout 4, w3
  if w4 >= 0 then '1e if power switch timer is active
    If w4 = 0 Then 'pin0 used as power switch
      High 0 'switch ON
    Else
      w4 = w4 - w0 'count down before above switch ON
      if w4 < 0 then
        w4 = 0
      end if
    End If
  endif 
Loop

Interrupt:
  SERIN 3, N4800_8, (127), b12, b13
  w0 = b13 Min MIN_INPUT Max MAX_INPUT - MIN_INPUT * GAP_SERVO / GAP_INPUT + MIN_SERVO
  'w0 = b13 * 91 / 126 + 100 'scale position 100 to 191

  Select case b12
    Case 0 : w1 = w0 'vane rudder
    Case 3 : w2 = w0 '1d Wing-Sail was Case 1
    Case 2 : w3 = w0 'or sail winch
    Case 9 : w4 = b13 * 3000 ' w4 = b13 * 60 * 1000 / 20
             Low 0 'switch OFF and start timer to switch ON.
  End Select
  w0 = 4000 - w1 - w2 - w3 / 100
  Pause w0
  SetInt %01000, %01000
  Return
 

hippy

Technical Support
Staff member
It should definitely be "w4=w4-1" or "dec w4". PICAXE variables cannot go negative.

This works for me; LED on pin0 flickers during download, off for 2s, flash for half a second, then off until about a minute later ( 62s by my stopwatch )...

#Picaxe 08M

w1 = 320 ' 160 @ 4MHz
w2 = 320 ' 160 @ 4MHz
w3 = 320 ' 160 @ 4MHz

w4 = 1 * 3000

Pause 2000
PulsOut 0,50000

SetFreq M8

w0 = 4000 - w1 - w2 - w3 / 100
Do
Pause w0
Pulsout 1, w1
Pulsout 2, w2
Pulsout 4, w3
If w4 = 0 Then
High 0
Else
w4 = w4 - 1
End If
Loop
 

Robin Lovelock

Senior Member
Thanks Hippy - Sorry - it was me being stupid.
I should have read my own "specification" :)
'for this the instruction is sync,9,time
'e.g. 127,9,15 = switch off for 15 minutes

For some stupid reason I was thinking "seconds" not "minutes" :)
Minutes is just fine - I just need to be a bit more patient when testing.

So many thanks Hippy, and tomorrow I'll correct it, then add that power control chip so I can start testing changes in GPSSppc to exploit it.

Robin
www.gpss.co.uk/autop.htm
 

MartinM57

Moderator
So what "power chip" are you considering? A chip-full of "darlingtons" may not be what you need and have some unwanted side effects (they are not perfect switches). Cue the logic-level MOSFET brigade perhaps....
 

hippy

Technical Support
Staff member
Also, you will probably want a high-side switch, switching the +V rather than 0V.
 

Robin Lovelock

Senior Member
Good Morning Folks ! :) Thanks. The obvious chip seems to be:
http://www.maplin.co.uk/Module.aspx?moduleno=2395
Price is obviously not important at less than £1.
For me it's best if I can get it from a Maplins Store, a short drive away.
This chip seems to do what's needed, without other components.
May pop out later, but other things take priority.
e.g. a long awaited test sail of Snoopy Sloop 3 if rain showers pass.
Mr Postman delivering a 3rd iPAQ here.
Meanwhile, work on changes in GPSSppc to exploit the power switch.
Thanks for your good advice.
Robin
www.gpss.co.uk/autop.htm
 

MartinM57

Moderator
The ULN280x chip, as pointed out above, are low side switches, so all you can do is switch the earth points of your other equipment to open circuit (switch off) or to ground (switch on).

You may have earth points all over the place in your hardware design, and they would all have to be switched.

Also switching to ground will not be perfect due to the saturation voltage of the ULN - your "switched earths" will be at 0.8v-1.2v above real earth. This isn't a problem when the load is the normal relay, high powered LED, bulb etc, but may not work as you expect when you are trying to switch the power to another piece of equipment, especially if you are trying to connect to it electrically with data links, analogue voltages etc

There is a high-side darlington switch chip (can never remember the number) which might be better, but it will still have a saturation voltage which will reduce the power supply voltage to the equipment you're switching on and off.

I think there's also some relays which latch in the state last left without power having to be continuously supplied (relays, contacts, boat, sea water hmmm...)

Worth a go with the ULN, but it might not be as good as you want it to be and/or introduced unwanted electrical effects


EDIT: ..and that Maplin chip is "Web only" so may not be available in store - I'd give them a call first..
 
Last edited:

Robin Lovelock

Senior Member
Thanks Martin. That edit in the end about checking stock was done just after I did exactly that - none of my local stores stock it :-(

This use of the PICAXE to switch a small ammount of power, a small fraction of an amp (for me 100 to 200mA) must be something that lots of your users have experienced. My problem is one of needing high reliability.

I can always go back to basics, and buy some suitable discrete components, including resistors and transisters, and do my own thing, but I would prefer taking something off the shelf.

The electronics has to be protected from the salty elements anyway, and I had thought of a (sealed) reed relay - but I'm not sure of reliability. We are talking about many months if not years of uninterrupted automatic sailing, and that power switch may be operating every few minutes. e.g. maybe 100,000 operations.

Switching to 0v rather than 5v may not be such a problem, with our particular small electronic package. However, if I'm making the switch myself, or if there is something ready out there, I may as well do the logical thing and switch the 5v rail.

I've got plenty to get on with today, but if anyone has any ideas, leading to bits for me to buy, that'll be good. Maybe my weekend shopping trip with the wife can do a detour past Maplins ;-)

Robin
www.gpss.co.uk/autop.htm
 
Top