Sunday, June 3, 2012

Swim Heat Counter with PICAXE 08M2

A friend of mine had the exciting job of flipping cards to display heats at his daughter's swim tournament.  Not difficult to do, but it doesn't allow the much mobility for the person assigned to the job.  Wouldn't it be nice to modernize the task and make it wireless?
-----
With a PICAXE 08M2 microcontroller and a few servos the electrical part of the task is pretty simple.   Basically two buttons (a ONES place button and a TENS place button) pull an input to the PICAXE high, causing a subroutine to be called and the appropriate servo to move.  Adding wireless to the rig should be easy as well by re-purposing a cheap remote from a toy RC car to replace the two button/switches that cause the servos to move. 

Adding the mechanical digits will not be completely trivial, by my buddy says he is up to the challenge.
-----
 Short video of the rig in action.
-----
Schematic drawing of the build (click to increase size):
-----
PICAXE 08M2 Project Source Code.  Very simple:

#rem
 *******************************
 ***** www.WhiskyTangoHotel.Com  *****
 *******************************
    Project Name: Walker Swim Heat Counter

    Start Date: June 1, 2012
    
    Program Rev History: 
    This version steps the a ONES digit Servo and a
    TENS digit Servo in ten increments to "display"
    the numbers 00-99.

 ******************************* 
    PICAXE PE Rev: 5.5.1
#endrem

#picaxe08m2 ' using PICAXE 08M2 uC
#COM11 'programming on COM11

'min servopos value = 75
'center servopos value = 150
'max servopos value = 255

symbol Ones_Button = pinc.4 'input button for Ones digit.  Pull high to count
symbol Ones_Position = b0 'servo location var


symbol Tens_Button = pinc.3 'input button of Tens digit.  Pull high to count
symbol Tens_Position = b1 'servo location var

'b2 is variable used for math in calculating both servo positons

'Init some stuff...
let dirsC = %11000111  ' define I/O of PortC.  Not really required.

servo 1,150 ; initialise ones digit servo
servo 2,150 ; initialise tens digit servo
Ones_Position = 0
'Calculate and move Ones digit Servo to "display" 0
b2 = Ones_Position * 15 + 75
servopos 1, b2

Tens_Position = 0
'Calculate and move Tens digit Servo to "display" 0
b2 = Tens_Position * 15 + 75
servopos 2, b2

main: 'main loop continually checks if a button is pushed to move the Servos.
If Ones_Button = 1 then 'move servo for Ones Digit
gosub Change_Ones
endif

If Tens_Button = 1 then 'move servo for Tens Digit
gosub Change_Tens
endif

goto main 'loop and check for button presses


Change_Ones: 'Routine called when "Ones" button is pressed.
If Ones_Position = 9 then 'highest position is '9'.  Wrap to '0'
Ones_Position = 0
else
Ones_Position = Ones_Position + 1
endif
'Convert the Ones_Position into the correct servo location
let b2 = Ones_Position * 15 + 75
Select Case b0
Case 0
servopos 1, b2
Case 1
servopos 1, b2
Case 2
servopos 1, b2
Case 3
servopos 1, b2
Case 4
servopos 1, b2
Case 5
servopos 1, b2
Case 6
servopos 1, b2
Case 7
servopos 1, b2
Case 8
servopos 1, b2
Case 9
servopos 1, b2
endselect
pause 500 'delay 500mSec to allow the servo to move
return ' Change_Ones

Change_Tens: 'Routine called when "Tens" button is pressed.
If Tens_Position = 9 then 'highest position is '9'.  Wrap to '0'
Tens_Position = 0
else
Tens_Position = Tens_Position + 1
endif
'Convert the Tens_Position into the correct servo location
let b2 = Tens_Position * 15 + 75
Select Case b0
Case 0
servopos 2, b2
Case 1
servopos 2, b2
Case 2
servopos 2, b2
Case 3
servopos 2, b2
Case 4
servopos 2, b2
Case 5
servopos 2, b2
Case 6
servopos 2, b2
Case 7
servopos 2, b2
Case 8
servopos 2, b2
Case 9
servopos 2, b2
endselect
pause 500  'delay 500mSec to allow the servo to move
return 'Change_Tens
-----