PICAXE Model Railroad Speed Controller
Train Recorder Version - SOFTWARE
d. bodnar
revised 11-08-11
 

Software:
The software uses the READADC command to get the setting of the potentiometer.  Since we are dealing with a range of 0-255 on the pot the program splits this into three parts.  The lower 118 points determine the speed of the train in one direction.  The upper values (from 137-254) points determine the speed in the other direction and the center points (118-137) stop the train entirely.  The very first and last values (0 and 255) are used to indicate where the sync block relay should be and where the end of the recording is located.

The toggle switch (RecOrPlay) is read to determine if we are recording or playing back and the data from a recording is sent to the memory chip with the I2C commands.  The push button switch (SyncButton) sets the point where the sync block is turned off.

This version of the software uses the START button so that the playback routine only runs after the START button is pushed.  To have it playback continuously either short the START button connection or change the line highlighted in RED so that it reads

if StartButton = 0 then

rather than

if StartButton = 1 then

 

'CHP MOD - 11-08-2011 - change so one memorized run takes place on each button push
'using IR IN button pin for StartButton
'see "START mod" lines for changes from ver 1.9b


'It also works at 32MHz speed by adding
     'setfreq m32
     'i2cslave %10100000, i2cfast_32,i2cword
     'serout serial,N19200_32, ("Ready")


#PICAXE 18M2
#NO_DATA
#TERMINAL 19200 'must be 19200 to show @ terminal due to speed change (m16)
setfreq m16 ' double speed
Symbol Direction1 = b.5 'pin 11->was pin 7 - one high & one low - swap to change direction-if = fast motor stop
Symbol Direction2 = b.0 'pin 6 - one high & one low - swap to change direction
symbol SLC = b.4 'pin 10
symbol SDA = b.1 'pin 7
Symbol StartButton= pinb.2 'pin 8 - START mod - normally used for IR IN
Symbol Motor = b.3 'pin 9 - PWM output for motor speed
Symbol SyncButton = pinb.7 'pin 13 - will use weak pullup
Symbol RecOrPlay = pinc.5
Symbol LEDAmber = c.6 'pin 15
Symbol LEDBlue = c.7 'pin 16
Symbol Relay = c.0 'pin 17
Symbol PWMValue = w13
Symbol memaddress = w12
Symbol PotValue = b1
Symbol Temp = b2
Symbol VerWhole = 1
Symbol VerDecimal = 9
Symbol MiddleLow = 118
Symbol MiddleHigh = 137
high direction1:low direction2
pwmout motor,150,500
pwmduty motor, 0
Symbol memmin = 0
Symbol memmax = 32000 ' change to 64000 for 24LC512 memory chip

Pullup on
Pullup %10000100 'weak pullups on b.2 and b.7

i2cslave %10100000, i2cfast,i2cword
low Relay 'NOTE: relay contacts CLOSED when it is off!
for temp = 1 to 10
toggle ledblue
pause 200
next temp

sertxd("d. bodnar",13,10,"11-08-2011 v START Mod ",#VerWhole,".",#VerDecimal,"c",13,10,13,10)

if RecOrPlay = 0 then PlayBack:'if low playback

Record:
sertxd ("Ready to record - pausing 3 sec.....",13,10):pause 6000
low Relay 'start with relay block powered
time=0
high LEDAmber
for memaddress = 0 to memmax'1023
if time <4 then
low relay
endif
toggle ledblue
if SyncButton = 0 then
high relay
sertxd ("Block Button Hit Time",#time,13,10)
writei2c memaddress, (0) 'code for end of recorded info
goto Skip00
endif
if RecOrPlay = 0 then
PotValue=255
sertxd ("sec, adc ",#memaddress," ",#PotValue," time = ",#time,13,10)
writei2c memaddress, (PotValue) 'code for end of recorded info
sertxd ("Done recording.....",13,10)
pause 4000
goto PlayBack:'if low playback
endif
READADC c.1, PotValue
sertxd ("sec, adc ",#memaddress," ",#PotValue," time = ",#time,13,10)
if PotValue <>0 and PotValue <> 255 then
writei2c memaddress, (PotValue)
else
if PotValue = 255 then
writei2c memaddress, (254) 'never write 255 unless done!
else
writei2c memaddress, (1) 'never write 0 unless in stop block
endif
endif
if PotValue <= MiddleHigh and PotValue >= MiddleLow then
pwmduty motor, 0 'stop if in middle
high ledamber
goto Skip00
else
low ledamber
endif
if PotValue < MiddleLow then
high direction1:low direction2
PotValue=MiddleLow-PotValue
endif
if PotValue > MiddleHigh then
high direction2:low direction1
PotValue=PotValue-MiddleHigh
endif
PWMValue = PotValue * 5
pwmduty motor,PWMValue
Skip00:
next memaddress
WaitHere:
if RecOrPlay = 1 then ' 1=record - wait for play switch setting
sertxd ("Waiting for Playback Switch!",13,10)
goto WaitHere:
endif

PlayBack:'START MOD stay here till start button pushed then run once
if StartButton = 1 then ' Change 1 to 0 to ignore START button and run continuously
sertxd ("Done with one run - waiting for button!",13,10):pause 140
toggle ledamber:low ledblue
goto PlayBack
endif

time=0
Low LEDAmber
for memaddress=0 to memmax'1023
if time <4 then
low relay
else
endif
toggle ledblue
if RecOrPlay = 1 then Record:
readi2c memaddress, (PotValue)'read b13,PotValue
sertxd ("sec, adc ",#memaddress," ",#PotValue," time = ",#time,13,10)
if PotValue = 0 then
high relay
goto Skip000:
endif
if PotValue=255 then 'end of memory section
pwmduty motor,0
sertxd ("DONE WITH RECORDED STUFF!",13,10):pause 4000
goto playback
endif
if PotValue <= MiddleHigh and PotValue >= MiddleLow then
pwmduty motor, 0 'stop if in middle
high ledamber
goto Skip000
else
low ledamber
endif
if PotValue < MiddleLow then
high direction1:low direction2
PotValue=MiddleLow-PotValue
endif
if PotValue > MiddleHigh then
high direction2:low direction1
PotValue=PotValue-MiddleHigh
endif
PWMValue = PotValue * 5
pwmduty motor,PWMValue
skip000:
next memaddress
time=0
goto WaitHere: