Ringbalin PICAXE Point Control System
Overview
Each point is controlled by a small distributed system made up of three parts:
PICAXE 08M2 point board - the controller
Input conditioning board - cleans up the button and switch signals
Calibration box - a portable tool for setting the servo end positions
The system reads the physical point lever, moves a servo to throw the point, and reports the point's state to an ESP-01, which publishes it over MQTT.
The PICAXE 08M2 Point Controller Circuit
Each point has its own PICAXE 08M2 board, which does three jobs:
Reads the physical point lever switch
Drives the servo to move the point blades
Reports the point's state to the ESP-01 so it can be sent over the network
Pin connections
Pin 1 +5V supply
Pin 2 (C.5) Calibration Enable - held LOW by a 10K pulldown in normal use; +5V applied when the calibrator box is switched ON
Pin 3 (C.3) Point lever switch input
Pin 4 (C.2) Servo control signal
Pin 5 (C.1) Calibrator UP button input
Pin 6 (C.4) Calibrator DOWN button input
Pin 7 (C.0) Digital status output to ESP-01 (through a 12K/22K divider)
Pin 8 0V ground
Normal operation
The PICAXE constantly monitors the point lever on C.3.
When the lever changes, the PICAXE reads the stored servo positions from its EEPROM and drives the servo on C.2.
At the same time it sets C.0 HIGH (thrown) or LOW (normal).
This simple digital level is reduced from 5V to 3.3V by the R1/R2 divider and fed to the ESP-01 RX pin. The ESP-01 then publishes an MQTT message.
Power
The servo is powered separately at 5V (not through the PICAXE board).
The servo signal comes from C.2.
All grounds are common.
The Input Conditioning Board
The conditioning board sits between the PICAXE point board and the calibrator box. It has two jobs:
Cleaning up the point lever switch signal
Cleaning up the calibrator button signals
The calibrator box plugs into the conditioning board via a D9 socket, and the conditioning board is wired back to the PICAXE point board by a wire loom.
The conditioning board is a retrofit that was required because calibration of blade positions was originally done by potentiometers outputting a voltage that set the servo position. This proved to be unworkable as the voltage could not be adjusted to be accurate enough to perform the job. This led to servos over-driving risking damage and causing brown outs of their power supply.
Switch input (C.3)
A 10K pulldown resistor holds the input LOW until the point lever switch closes.
Button inputs (C.1 and C.4)
Each button channel has:
a 10K pull-up to 5V (input held HIGH when idle)
a 1K series resistor
a 47nF capacitor to ground (debounce)
When a button is pressed, the input is pulled LOW cleanly, and the PICAXE reads it without bounce or noise.
Connections
Calibrator box -> D9 socket on the conditioning board
Conditioning board -> PICAXE point board (via wire loom)
Loom carries: 5V, C.5 (enable), C.1 (UP), C.4 (DOWN), GND
The Calibration Box Operation
The calibrator is a small portable box used to set the servo end positions for each point. It plugs into the conditioning board.
What's in the box
Toggle switch - enables calibration mode
LED - lights when calibration mode is ON
UP momentary button
DOWN momentary button
D9 plug for connection to each point's conditioning board
Calibration sequence
Plug in the calibrator with the toggle switch OFF.
Turn toggle ON - the LED lights and +5V is applied to C.5, putting the PICAXE into calibration mode.
Set the point lever to NORMAL.
Trim with UP/DOWN until the blade sits correctly against the stock rail.
Turn toggle OFF - this automatically saves the NORMAL position to EEPROM.
Turn toggle ON again.
Set the point lever to THROWN.
Trim with UP/DOWN until that blade sits correctly.
Turn toggle OFF - this automatically saves the THROWN position to EEPROM.
Unplug the calibrator and move to the next point.
Key points
The point lever (C.3) selects which end (NORMAL or THROWN) is being calibrated.
The UP/DOWN buttons trim the servo position in small steps.
Turning the box OFF saves automatically - there is no separate SAVE button.
The ESP-01 status link is unchanged during calibration; it simply continues reporting the point's state.
Summary of the signal chain
Physical point lever -> PICAXE (C.3) -> servo moves the blades
Servo state -> PICAXE (C.0) -> R1/R2 divider -> ESP-01 RX -> MQTT -> Pi GUI
Calibration -> Calibrator box -> conditioning board -> PICAXE (C.1/C.4/C.5) -> EEPROM
The Picaxe Program Code
' Ringbalin Point Controller - Plug-in Calibrator
' PICAXE
08M2
'
' Normal operation:
' C.3 point lever
controls the servo.
'
' Calibration operation:
' C.5
HIGH = calibrator enabled.
' C.1 LOW = UP button pressed.
'
C.4 LOW = DOWN button pressed.
' Point lever selects NORMAL
or THROWN.
' Short button press = one fine adjustment.
'
Button held = repeated coarse adjustments.
' Turning
calibrator OFF saves the selected position.
'
'
Important:
' Calibrator must be OFF when the PICAXE is powered
up
' or reset. C.5 must be LOW during startup.
#picaxe
08m2
#no_data
setfreq m4
'
============================================================
'
PIN DEFINITIONS
'
============================================================
symbol
switchPin = pinC.3 ' Point lever switch
symbol upBtn =
pinC.1 ' Conditioned UP input
symbol downBtn = pinC.4
' Conditioned DOWN input
symbol calibEn = pinC.5 '
Calibrator enable; HIGH = ON
symbol servoPin = C.2
' Servo signal
symbol esp01Pin = C.0 ' Status output
to ESP-01
'
============================================================
'
VARIABLES
'
============================================================
symbol
servoPosition = b4
symbol normalPos = b5
symbol
thrownPos = b6
symbol calibrationTarget = b7
symbol
holdCount = b8
'
============================================================
'
EEPROM ADDRESSES
'
============================================================
symbol
EEPROM_NORMAL = 0
symbol EEPROM_THROWN = 1
'
============================================================
'
SERVO LIMITS
' PICAXE recommends approximately 75 to 225
'
============================================================
symbol
SERVO_MIN = 75
symbol SERVO_MAX = 225
'
============================================================
'
COARSE ADJUSTMENT SETTINGS
'
============================================================
symbol
COARSE_STEP = 5
' 15 x approximately 20 ms = approximately
300 ms
symbol HOLD_TICKS = 15
' Limits used to
prevent coarse steps exceeding the servo range
symbol
COARSE_UP_LIMIT = 220
symbol COARSE_DOWN_LIMIT = 80
'
============================================================
'
INITIALISATION
'
============================================================
init:
' C.5 must be LOW when the PICAXE starts.
' The
calibrator must be OFF during power-up or reset.
'
After this command C.5 can safely be used as an input.
disconnect
' Load saved servo positions from EEPROM
read EEPROM_NORMAL, normalPos
read EEPROM_THROWN,
thrownPos
'
--------------------------------------------------------
'
Check NORMAL position.
'
' This handles:
'
- an erased EEPROM value of 255
' - an EEPROM value of
0
' - any value outside the usable servo range
'
' Existing valid values between 75 and 225 are preserved.
' --------------------------------------------------------
if normalPos < SERVO_MIN then
normalPos = 75
write EEPROM_NORMAL, normalPos
endif
if normalPos > SERVO_MAX then
normalPos = 75
write EEPROM_NORMAL, normalPos
endif
'
--------------------------------------------------------
'
Check THROWN position.
'
--------------------------------------------------------
if thrownPos < SERVO_MIN then
thrownPos = 175
write EEPROM_THROWN, thrownPos
endif
if thrownPos > SERVO_MAX then
thrownPos = 175
write EEPROM_THROWN, thrownPos
endif
'
--------------------------------------------------------
'
Start the servo at the saved position selected by
' the
physical point lever.
'
--------------------------------------------------------
if switchPin = 1 then
servoPosition = thrownPos
high esp01Pin
else
servoPosition =
normalPos
low esp01Pin
endif
servo servoPin, servoPosition
pause 1000
'
============================================================
'
MAIN PROGRAM LOOP
'
============================================================
main:
' --------------------------------------------------------
' Check whether the calibrator has been enabled.
' Confirm
HIGH after 20 ms to reject switch bounce.
'
--------------------------------------------------------
if calibEn = 1 then
pause 20
if
calibEn = 1 then
gosub calibration
endif
endif
'
--------------------------------------------------------
'
NORMAL OPERATION
' The calibration buttons are ignored
here.
'
--------------------------------------------------------
if switchPin = 1 then
servoPosition = thrownPos
high esp01Pin
else
servoPosition =
normalPos
low esp01Pin
endif
servopos servoPin, servoPosition
pause 50
goto main
'
============================================================
'
CALIBRATION MODE
'
============================================================
calibration:
' Select the initial calibration position from the lever.
' The lever selects which value is being adjusted.
' It does
not directly control the servo while calibrating.
if
switchPin = 1 then
calibrationTarget = 1
servoPosition = thrownPos
else
calibrationTarget = 0
servoPosition = normalPos
endif
servopos servoPin, servoPosition
pause
100
calibration_loop:
'
--------------------------------------------------------
'
Check whether the calibrator has been switched OFF.
'
Confirm LOW after 20 ms.
'
--------------------------------------------------------
if calibEn = 0 then
pause 20
if
calibEn = 0 then
gosub save_current_position
pause 200
return
endif
endif
'
--------------------------------------------------------
'
Allow the lever to select NORMAL or THROWN while
'
calibration remains enabled.
'
' The previous
adjustment is saved before changing target.
'
--------------------------------------------------------
if calibrationTarget = 0 then
' Change from
NORMAL adjustment to THROWN adjustment
if switchPin = 1
then
normalPos = servoPosition
write EEPROM_NORMAL, normalPos
calibrationTarget = 1
servoPosition = thrownPos
servopos servoPin, servoPosition
pause
100
endif
else
'
Change from THROWN adjustment to NORMAL adjustment
if
switchPin = 0 then
thrownPos = servoPosition
write EEPROM_THROWN, thrownPos
calibrationTarget = 0
servoPosition = normalPos
servopos servoPin, servoPosition
pause
100
endif
endif
'
--------------------------------------------------------
'
Check the calibrator buttons.
' Both buttons are active
LOW.
'
--------------------------------------------------------
if upBtn = 0 then
gosub handle_up
endif
if downBtn = 0 then
gosub handle_down
endif
pause 10
goto calibration_loop
'
============================================================
'
SAVE CURRENT CALIBRATION POSITION
'
============================================================
save_current_position:
if calibrationTarget = 1 then
thrownPos =
servoPosition
write EEPROM_THROWN, thrownPos
else
normalPos = servoPosition
write
EEPROM_NORMAL, normalPos
endif
return
'
============================================================
'
UP BUTTON HANDLER
'
' Short press:
' One fine
step.
'
' Held button:
' After approximately 300 ms,
repeated coarse steps.
'
============================================================
handle_up:
' Initial software debounce
pause 20
'
Ignore a brief noise pulse
if upBtn = 1 then
return
endif
holdCount = 0
up_held:
' Check whether the button has been released
if upBtn = 1
then
pause 20
' Confirm release
if upBtn = 1 then
' Short press gives
one fine step
if holdCount < HOLD_TICKS then
gosub fine_up
endif
return
endif
endif
' Count
the duration of the button press
if holdCount <
HOLD_TICKS then
holdCount = holdCount + 1
pause 20
else
' Long press gives repeated
coarse steps
gosub coarse_up
pause 100
endif
goto up_held
'
============================================================
'
DOWN BUTTON HANDLER
'
' Short press:
' One fine
step.
'
' Held button:
' After approximately 300 ms,
repeated coarse steps.
'
============================================================
handle_down:
' Initial software debounce
pause 20
'
Ignore a brief noise pulse
if downBtn = 1 then
return
endif
holdCount = 0
down_held:
' Check whether the button has been released
if downBtn =
1 then
pause 20
' Confirm release
if downBtn = 1 then
' Short press gives
one fine step
if holdCount < HOLD_TICKS then
gosub fine_down
endif
return
endif
endif
'
Count the duration of the button press
if holdCount <
HOLD_TICKS then
holdCount = holdCount + 1
pause 20
else
' Long press gives repeated
coarse steps
gosub coarse_down
pause 100
endif
goto down_held
'
============================================================
'
FINE UP
' One PICAXE servo count
'
============================================================
fine_up:
if servoPosition < SERVO_MAX then
servoPosition =
servoPosition + 1
servopos servoPin, servoPosition
endif
return
'
============================================================
'
FINE DOWN
' One PICAXE servo count
'
============================================================
fine_down:
if servoPosition > SERVO_MIN then
servoPosition =
servoPosition - 1
servopos servoPin, servoPosition
endif
return
'
============================================================
'
COARSE UP
' Five PICAXE servo counts
'
============================================================
coarse_up:
if servoPosition < SERVO_MAX then
if
servoPosition > COARSE_UP_LIMIT then
servoPosition = SERVO_MAX
else
servoPosition = servoPosition + COARSE_STEP
endif
servopos servoPin, servoPosition
endif
return
'
============================================================
'
COARSE DOWN
' Five PICAXE servo counts
'
============================================================
coarse_down:
if servoPosition > SERVO_MIN then
if
servoPosition < COARSE_DOWN_LIMIT then
servoPosition = SERVO_MIN
else
servoPosition = servoPosition - COARSE_STEP
endif
servopos servoPin, servoPosition
endif
return
Diagrams
| Conditioning Board and Cal Box |
| Conditioning sub board |
| Picaxe with Conditioning and Cal |
No comments:
Post a Comment