# Ideas for measuring model railway loco speed

#### neiltechspec

##### Senior Member
Using an M2, I want to measure loco speeds.
I have two IR sensors (TX/RX) in small packages mounted in the track 12 inches apart.

So, 1 Foot Per Sec = 0.6818 MPH, for N Scale multiply by 148 gives me scale speed. Should be easy enough.

Thinking of using the 'pulsin' command to measure time between IR's. The number of 10uS units will give me a time.
1st IR has to start pulsin.
2nd IR has to stop the count.
Was thinking of a simple S/R logic gate latch to use with pulsin ('srlatch' doesn't make any sense to me).

I seem to be having a bit of a 'senior moment' presently & can't seem to get my head around the best way to achieve what I want.

Anybody any better ideas, or has it been done before.

Neil.

Last edited:

#### Eng460

##### Well-known member
Hi Neil, one of the first things I learned about using “Pulsin” is that it times the duration of a pulse, Not the time between pulses. It can handle a pulse which is high for the duration, or one that is low, which ever you require.

Its big advantage is that it is great for really short pulses, but there is a limit to long duration pulses before it times out. Depending on the speed of your locomotive, the sensors may have to be much closer together, but that is not a problem for pulsin. Worth exploring the maths on how long a duration causes pulsin to time out and give a zero result. But your detectors may only have to be inches apart, or less for the required accuracy.

To pursue your approach, it might be necessary to use some external components to make the two sensors work together to make a value first high then low, or vice versa. There are 74 series chips that will do this, look for various forms of J-k flip-flop, which have two inputs, one trips the out put high and the other trips it low. Possibly some 4000 series chips that also do this. Then the flip flop output can be used as the input to your Picaxe to be timed by pulsin, calculate the speed and output to either your computer or to the Picaxe serial display.

I hope that helps get you moving in a useful direction. It’s great fun developing a concept that will achieve these tasks.

Eng460

#### AllyCat

##### Senior Member
Hi,

PULSIN will Time Out after about 650ms and, as said, measures between the positive and negative edges of a pulse on a single pin, so you would need some external hardware. No, I've never found the internal S-R Latch to be of any use with PICaxe.

For sensors 12 inches apart, the timed period is presumably going to be a second or more. Also, to calculate a speed, you need to DIVIDE by the time taken (the longer the time, the slower the speed) and the "best" practical divisor is only a few hundred with PICaxe Basic, so you may need to measure in, say, 10 ms units. The easiest way to do that it is a simple Program "counting" loop: the program loops until the first input changes and then repeatedly tests the second input, incrementing a counter (variable) each time until there is a change in the second input.

You may need to calibrate the loop with a test, e.g. a manual period of 10 or 100 seconds, but a good starting point for a 10ms increment would be something like: gap = 0 : DO : gap = gap + 1 : PAUSE 7 : LOOP UNTIL inputpin2 = 1 (because the loop instructions will take a few ms to execute). For better accuracy of shorter time periods, you might use a higher SETFREQ , or trim the value of a PAUSEUS 700 instead of the PAUSE.

Cheers, Alan.

#### neiltechspec

##### Senior Member
Gents, thanks for the thoughts.

Yes, I was going to use either 74HC or 4000 series CMOS gates for the latch. That's fairly easy for me (my original background was TTL logic).
Forgot about the pulsin max duration of 650ms, good point. I haven't drilled the holes for the sensors yet, 12 inches was just a first thought.
It's looking like the counting loop may be the best way to go.

I wouldn't be suprised If I don't end up doing most of it in TTL Logic - I have still got 'tens' of chips in the draws, just may use the PICAXE for the display, or end up using one of the many 74C912's I still have (used loads of them in the past - very easy to use & even used one with a PICAXE once).

It maybe a PICAXE is not the best solution for what I want to do, but thought it may save time, perhaps not.

Accuracy need only be approximate, 10% error wouldn't be too much of a concern.

Think I'm going to have to experiment and do some testing.

Neil.

#### westaust55

##### Moderator
My speedometer wagon could be another option rather than a fixed device:

#### neiltechspec

##### Senior Member
What an interesting idea.
Not sure I can fit that into a 'N' guage wagon though, it's half the size of yours.
But I will study the code to see how you did it.

Neil.

#### neiltechspec

##### Senior Member
Here's what I have come up with.
Using a 28x2 with direct drive of 3 x 7 seg 0.3" LED displays.
Calibrated with a Xtal'd Pulse Generator & tested at scale speed of 33, 66 & 99, all display within 10% accuracy.

Code:
``````#rem
3 Digit 7 Seg Com Cathode display direct drive for
display of 0 - 199 with dp's for timing activity.

Using PICAXE28X2, V1 Aug 2020

Connections:

[code]
#rem
3 Digit 7 Seg Com Cathode display direct drive for
display of 0 - 199 with dp's for timing activity.

Using PICAXE28X2, V2 Aug 2020

Connections:

Hall Sensors A3144 on A.0 & A.1 with 2.2K pullups, set 100mm apart,
gives 33MPH for 100mm/s

Hundreds segments b & c on A.3 thru 100R

Tens
C.0 ..... 330R to Segment  a
C.1 ..... 330R to Segment  b
C.2 ..... 330R to Segment  c
C.3 ..... 330R to Segment  d
C.4 ..... 330R to Segment  e
C.5 ..... 330R to Segment  f
C.6 ..... 330R to Segment  g

Units
B.0 ..... 330R to Segment  a
B.1 ..... 330R to Segment  b
B.2 ..... 330R to Segment  c
B.3 ..... 330R to Segment  d
B.4 ..... 330R to Segment  e
B.5 ..... 330R to Segment  f
B.6 ..... 330R to Segment  g

Decimal Points on A.2 thru 100R
#endrem

#picaxe 28x2
#no_data
#no_table

symbol delay = 150    'display segment test
symbol dp    = a.2        'decimal points
symbol sens1 = pina.0    'hall sensor 1 (active low)
symbol sens2 = pina.1    'hall sensor 2 (active low)

init:
setfreq m16
dirsB = %11111111
dirsC = %11111111
pinsB = %00000000 'blank units
pinsC = %00000000 'blank tens

pause 1000

gosub test_units
gosub test_tens
gosub test_hun
gosub test_dp

main:
b0 = 0
pinsC = %01000000
do
if sens1 = 0 then goto clockwise
if sens2 = 0 then goto anticlock
loop

clockwise:
pinsC = %00000000
high dp
do
inc b0
pause 18
loop until sens2 = 0
low dp
goto display

anticlock:
pinsC = %00000000
high dp
do
inc b0
pause 18
loop until sens1 = 0
low dp
goto display

display:

b1 = 112*33/b0
bintoascii b1,b25,b26,b27
sertxd("b0:",#b0," b1:",#b1,"  MPH:",b25,b26,b27,cr,lf)

if b25 = 49 then
high a.3    'display "1" on hundreds
endif

if b25 = 48 then
low a.3     'blank hundreds
endif

select case b27    'units
case 48 let pinsB = %00111111    '0
case 49 let pinsB = %00000110    '1
case 50 let pinsB = %01011011    '2
case 51 let pinsB = %01001111    '3
case 52 let pinsB = %01100110    '4
case 53 let pinsB = %01101101    '5
case 54 let pinsB = %01111100    '6
case 55 let pinsB = %00000111    '7
case 56 let pinsB = %01111111    '8
case 57 let pinsB = %01100111    '9
endselect

select case b26    'tens
case 48 let pinsC = %00111111    '0
case 49 let pinsC = %00000110    '1
case 50 let pinsC = %01011011    '2
case 51 let pinsC = %01001111    '3
case 52 let pinsC = %01100110    '4
case 53 let pinsC = %01101101    '5
case 54 let pinsC = %01111100    '6
case 55 let pinsC = %00000111    '7
case 56 let pinsC = %01111111    '8
case 57 let pinsC = %01100111    '9
endselect

pause 12000    'show speed display for 3 sec

low a.3        'blank hundreds
pinsB = %00000000 'blank units
pinsC = %00000000 'blank tens

goto main

test_units:
pinsB = %00111111    'display "0"
pause delay
pinsB = %00000110    'display "1"
pause delay
pinsB = %01011011    'display "2"
pause delay
pinsB = %01001111    'display "3"
pause delay
pinsB = %01100110    'display "4"
pause delay
pinsB = %01101101    'display "5"
pause delay
pinsB = %01111100    'display "6"
pause delay
pinsB = %00000111    'display "7"
pause delay
pinsB = %01111111    'display "8"
pause delay
pinsB = %01100111    'display "9"
pause delay
return

test_tens:
pinsC = %00111111    'display "0"
pause delay
pinsC = %00000110    'display "1"
pause delay
pinsC = %01011011    'display "2"
pause delay
pinsC = %01001111    'display "3"
pause delay
pinsC = %01100110    'display "4"
pause delay
pinsC = %01101101    'display "5"
pause delay
pinsC = %01111100    'display "6"
pause delay
pinsC = %00000111    'display "7"
pause delay
pinsC = %01111111    'display "8"
pause delay
pinsC = %01100111    'display "9"
pause delay
return

test_hun:
high a.3        'display "1" on hundreds
pause 2000
return

test_dp:
high a.2        'illuminate dp's
pause 2000
low a.2        'blank dp's
low a.3        'blank hundreds
pinsB = %00000000 'blank units
pinsC = %00000000 'blank tens
return``````
edit: slight cock up on loop timings, must wear glasses when looking at data sheets !!
edit2: Corrected code shown.

Neil.

Last edited:

#### popchops

##### Active member
Great idea... Now just need closed-loop speed control up and down the hills(?)

Pops.