Turning Servos OFF until inputs change

neiltechspec

Senior Member
My points controller does 5 servos activating sets of points on my N Guage Railway.

Inputs are switches and can be left in either position (on / off), when a switch changes I want to
move the appropriate servo & then turn the servo off after about 200ms (should give enough time for servo to move).

Current code is below, but can't seem to get my head around the best way to achieve what I need.

Any ideas welcome.

Code:
#rem
Servo based independant five points controller
for changing loop & siding servos.

V1 30th Dec 2019

Servo 1 & 2 for changing between loops
Servo 3 for siding 1
Servo 4 for siding 2
Servo 5 for siding 3

min position is 100
centre is 150
max position is 200

Servo 1 on B.1
Servo 2 on B.2
Servo 3 on B.3
Servo 4 on B.4
Servo 5 on B.5
Switch for servo 1&2 on C.0
Switch for servo 3 on C.1
Switch for servo 4 on C.2
Switch for servo 5 on C.3
Led on C.4
#endrem

#picaxe 14m2
#no_data
#terminal 19200

symbol s1 = B.1
symbol s2 = B.2
symbol s3 = B.3
symbol s4 = B.4
symbol s5 = B.5

init:
    setfreq m16
    low C.4        'led off
    sertxd("Reset",cr,lf)
    pullup 3840        'pullup on C.0 to C.3 (%0000111100000000)
    servo s1,135    'start servo 1 in inactive position
    servo s2,170    'start servo 2 in inactive position
    servo s3,120    'start servo 3 in inactive position
    servo s4,155    'start servo 4 in inactive position
    servo s5,145    'start servo 5 in inactive position
    pause 2000
    sertxd("Servo's started in inactive postion",cr,lf)
    pause 1000
    high C.4        'led on
    sertxd("Run",cr,lf,cr,lf)
   
main:
    do
    if pinC.0 = 0 then gosub s1_2l
    if pinC.0 = 1 then gosub s1_2r
    if pinC.1 = 0 then gosub s3l
    if pinC.1 = 1 then gosub s3r
    if pinC.2 = 0 then gosub s4l
    if pinC.2 = 1 then gosub s4r
    if pinC.3 = 0 then gosub s5l
    if pinC.3 = 1 then gosub s5r
    pause 400
    loop

s1_2l:
    servopos s1,135     'servo 1 clockwise
    servopos s2,170     'servo 2 anti-clock
    pause 800
    'servopos s1,OFF
    'servopos s2,OFF
    return
s1_2r:
    servopos s1,175     'servo 1 anti-clock
    servopos s2,140     'servo 2 clockwise
    pause 800
    'servopos s1,OFF
    'servopos s2,OFF
    return
   
s3l:
    servopos s3,120     'servo 3 clockwise
    pause 800
    'servopos s3,OFF
    return
s3r:
    servopos s3,148     'servo 3 anti-clock
    pause 800
    'servopos s3,OFF
    return

s4l:
    servopos s4,155    'servo 4 anti-clock
    pause 800
    'servopos s4,OFF
    return
s4r:
    servopos s4,121    'servo 4 clockwise
    pause 800
    'servopos s4,OFF
    return
   
s5l:
    servopos s5,145    'servo 5 anti-clock
    pause 800
    'servopos s5,OFF
    return
s5r:
    servopos s5,176    'servo 5 clockwise
    pause 800
    'servopos s5,OFF
    return
 

hippy

Technical Support
Staff member
My take on it ...
Code:
#Picaxe 14M2
#No_Data
#Terminal 19200

Symbol MOVE_TIME = 200
Symbol LOOP_TIME = 10

Symbol SW1 = pinC.0
Symbol SW3 = pinC.1
Symbol SW4 = pinC.2
Symbol SW5 = pinC.3

Symbol S1  = B.1
Symbol S2  = B.2
Symbol S3  = B.3
Symbol S4  = B.4
Symbol S5  = B.5

Symbol t1  = w1 : t1 = $FFFF
Symbol t3  = w3 : t3 = $FFFF
Symbol t4  = w4 : t4 = $FFFF
Symbol t5  = w5 : t5 = $FFFF

#Macro Handle(txt,swX,bitX,tX,CloseX,OpenX,ReleaseX)
  If swX <> bitX Or tX = $FFFF Then
    bitX = swX
    If bitX = 1 Then
      SerTxd("Close ", txt, CR, LF)
      Gosub CloseX
    Else
      SerTxd("Open ", txt, CR, LF)
      Gosub OpenX
    End If
    tX = MOVE_TIME
  Else If tX > 0 Then
    tX = tX Min LOOP_TIME - LOOP_TIME
    If tX = 0 Then
      SerTxd("Release ", txt, CR, LF)
      Gosub ReleaseX
    End If
  End If
#EndMacro

Init:
  SetFreq M16
  Low C.4        ; led off
  SerTxd( "Reset", CR, LF)
  PullUp 3840    ; pullup on C.0 to C.3 (%0000111100000000)

MainLoop:
  Do
    Handle("1&2",SW1,bit1,t1,Close1,Open1,Release1)
    Handle("3"  ,SW3,bit3,t3,Close3,Open3,Release3)
    Handle("4"  ,SW4,bit4,t4,Close4,Open4,Release4)
    Handle("5"  ,SW5,bit5,t5,Close5,Open5,Release5)
    Pause LOOP_TIME
  Loop

Open1:    Servo S1,135          ; servo 1 clockwise
Open2:    Servo S2,170 : Return ; servo 2 anti-clock
Open3:    Servo S3,120 : Return ; servo 3 clockwise
Open4:    Servo S4,155 : Return ; servo 4 anti-clock
Open5:    Servo S5,145 : Return ; servo 5 anti-clock

Close1:   Servo S1,175          ; servo 1 anti-clock
Close2:   Servo S2,140 : Return ; servo 2 clockwise
Close3:   Servo S3,148 : Return ; servo 3 anti-clock
Close4:   Servo S4,121 : Return ; servo 4 clockwise
Close5:   Servo S5,176 : Return ; servo 5 clockwise

Release1: Servo S1,OFF
Release2: Servo S2,OFF : Return
Release3: Servo S3,OFF : Return
Release4: Servo S4,OFF : Return
Release5: Servo S5,OFF : Return
 

neiltechspec

Senior Member
I'm afraid you lost me completely when the #macro appeared.

Also I guess macros are a PE6 thing, which I do not use.

I'll probably end up using a 20m2 for more I/O and change the switches to centre off toggles - which
I was thinking of changing to, then it's fairly easy for me to understand what I need to do.

But thanks for your efforts anyway.
 

erco

Senior Member
Nice solution, neiltechspec. Sometimes a quick & easy hardware change simplifies the software, just as you proved.
 
Top