Infrared Train Identification

Revised 04-12-07

The objective of this project is to design and construct a set of sending and receiving units so that the track-side receivers can identify the train that is passing.

This will add considerably to the capabilities of another project where a DCC control unit operates trains.

It could also be used to activate track-side accessories based on which train goes past... lots of possibilities!

Each engine will have a sending unit that continually transmits an infrared code that identifies it.

The track-side receivers will initially only respond to a particular engine.  Ultimately they may transmit the ID code to the master control unit.

 

Hardware:

There are two components to this system, one goes on each engine and one sits track-side where identification takes place.

The on-board transmitter has these components:

  • Power supply that takes power from the DCC supplied constant voltage and converts it to regulated 5 volts DC.  Power can also be supplied by batteries or track voltage.
  • Microcontroller that generates the unique ID for an engine - this ID can be changed by changing jumpers on the board (lower left in the photo)
  • IR LED that sends out the ID code continuously as a modulated 38 KHz data stream..  This can easily be hidden as 3mm LEDs can be used.

The track-side receiver has these components:

  • Power supply that takes power from the DCC supplied constant track voltage and converts it to regulated 5 volts DC.  Power can also be supplied by batteries, track voltage or another power source. 
  • Microcontroller that decodes the IR data stream that is received. 
  • IR Detector that is mounted next to the track so that it "sees" the IR emitter on the train as it passes.  The detector needs to be several inches back from the passing train so that it has a chance to "see" the emitter for at least a second.

Schematic:

Click on this thumbnail to see the schematic

Software:

The PICAXE 08M can transmit any of the Sony IR codes - the command is:

INFRAOUT 1, code

If code=1 then the receiving program detects button 1 - if code =2 button 2 and so on - see PICAXE manual for details

TEST CODE FOR RECEIVER - PICAXE 08M

top:

infrain2
'debug infra
if infra=5 then do5
if infra=6 then do6
if infra=7 then do7
goto top:

do5: ' relay
high 1
pause 400
low 1
goto top:

do6:
high 4
pause 400
low 4
goto top:

do7:
high 0
pause 400
low 0
goto top:

TEST CODE FOR TRANSMITTER - PICAXE 08M

top:
for b0=5 to 5  'change 5 for each engine -
for b1 = 1 to 1
toggle 1

infraout 1,b0
pause 45
'debug b0
next b1
pause 100
next b0
goto top:

 

TEST CODE FOR RECEIVER - 16F684 - PicBasic Pro

'1-5-07 test
DEFINE DEBUG_REG PORTA
DEFINE DEBUG_BIT 4 ' PIN 3 on 16f684
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 1 ' Set Debug mode: 0 = true, 1 = inverted
define PULSIN_MAX 555

Include "modedefs.bas"
' Serial_in var porta.5 'pin 2 on 16f684
Serial_out var PORTA.4 ' pin 3 on 16f684
LED var portc.4
temp var word
temp1 var word
temp2 var word
TempByte var byte
digit var byte
TempWord var word
TempWord2 var word
TempWord3 var word
zero con 136
one con 128
two con 129
three con 130
four con 131
five con 132
six con 133
seven con 134
eight con 135
nine con 136
channelUP con 144
channelDOWN con 145
volumeUP con 146
volumeDOWN con 147
OK con 148
Menu con 224
ENTER con 139
Power con 149
IRpulse_length var word(13)
xx var Byte
Command Var Byte
IRin var portc.3 'pin 7
ansel = 0
cmcon0 = 7
trisa.4=0 'debug an output
trisa.1=0 'make relay pin an output
trisc.4=0 'make led output
trisc.1=0
trisc.2=0
trisc.4=0
trisc.3=1 'pwm pin 7
debug 13,10,13,10,"(C) 2007 - d. bodnar - ver 0.1",13,10,"TrainElectronics.com",13,10

start:
gosub GetIR

if command=135 then high led:pause 500:low led
goto start:

GetIR:
Getstartbits:
Pulsin IRin ,0,IRpulse_length(0)
if IRpulse_length(0) < 200 then
goto getstartbits
return
Endif

for xx=1 to 12
pulsin IRin,0,IRpulse_length(xx)
next xx

displaybits:
if IRpulse_length(1) < 100 then
Command.bit0 = 0
Else
Command.bit0 = 1
endif
if IRpulse_length(2) < 100 then
Command.bit1 = 0
Else
Command.bit1 = 1
endif
if IRpulse_length(3) < 100 then
Command.bit2 = 0
Else
Command.bit2 = 1
endif
if IRpulse_length(4) < 100 then
Command.bit3 = 0
Else
Command.bit3 = 1
endif
if IRpulse_length(5) < 100 then
Command.bit4 = 0
Else
Command.bit4 = 1
endif
if IRpulse_length(6) < 100 then
Command.bit5 = 0
Else
Command.bit5 = 1
endif
if IRpulse_length(7) < 100 then
Command.bit6 = 0
Else
Command.bit6 = 1
endif
if IRpulse_length(8) < 100 then
Command.bit7 = 0
Else
Command.bit7 = 1
Endif
If Command.bit7 = 0 then 'Bit 7 is one of the device bits
Command = Command + 1
Endif
If Command = 10 then
Command = 0
Endif
debug "code= ", #command
return