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:
Top