[home]

HO Module
Switchback Controller
revised 10-09-10  - 09-17-2016 d. bodnar
 

When I decided to develop an HO module I wanted it to have some stand-alone value so that it would be interesting even when it was not attached to other modules.

The single module grew into two modules that contain a mountainous region that the locomotive and its load must navigate through a series of switchbacks.

The three switches are automatically thrown as the train progresses up and down the grades.  The same controller also manages the acceleration, deceleration and direction of travel for the locomotive.

Click here for information on constructing the module

Controller
The controller is based on a circuit board that was originally developed for a speedometer.  It contains a PIC 16F88 microcontroller, DPDT relay and TIP101 Darlington transistor.  The last two parts control the locomotive's speed and direction.
An auxiliary board operate the switch servos.  Magnetic reed switches are used to determine the locomotive's location on the line.
The controller's settings can be changed by way of a standard TV remote control set to SONY codes.  This is used to change the locomotive's speed and direction and to adjust the time that the locomotive stays in a siding.

 

Video


Right click the boxes below and select "play"

Viewed from left end


 

Viewed from left end

Viewed from front

Schematic - 16F88 Controller

Software - 16F88 Controller - controls the movement of the mining train as it climbs the mountain on switch backs - 3 servos for switches and 7 reed switches for sensors
'10-6-10- this one (v 8.0x-XP) seems to be working with the single mainline laser
'10-05-10 - decel changed so trains stop more rapidly   
 'NOTE - 10-5-10 - may have figured out how to program this from Win 7 - see note below
 'NOTE: program in programmer (no ICSP) using old IBM laptop Microcode Studio 2.46
'CONFIRMED 8-26-10 - must use old XP laptop!  IBM /w 2.46 to get it to work! 
'Note that ICSP does not work with MCLR off & pin 4 used as input

'commands - OK start / stop
'Chan + faster / Chan - slower
'Volume + direction L to R / Volume - direction R to L
'FF more stop time / RW less stop time
' ENTER - input stop time digits 0-99 (two digits only)
DEFINE DEBUG_REG PORTA  
DEFINE DEBUG_BIT 2         ' PIN 1 on 16f88
DEFINE DEBUG_BAUD 9600 
DEFINE DEBUG_MODE 1 ' Set Debug mode: 0 = true, 1 = inverted
'NOTE 10-4-10 - find that this line is not needed if you set fuses manually in the programmer
'   not fully tested but seems to be the case.  Make sure the CCP is set to RB0, not RB3
  @ DEVICE  PIC16F88, INTRC_OSC_NOCLKOUT, WDT_OFF, LVP_OFF, PWRT_ON, PROTECT_OFF, BOD_ON, MCLR_OFF
DEFINE OSC 8
OSCCON = $70      'dec 112 binary 11100000   = 8mhz

'NOTE - at $70 (8mhz) must double ms on GETIR routines to 400 & 200

'Include "modedefs.bas"
loop                VAR BYTE
temp                VAR WORD
temp1               VAR WORD
temp2               VAR WORD
LEDTemp1            VAR BYTE
LEDTemp2            VAR BYTE
LEDTemp3            VAR BYTE             
Laps                VAR WORD 
ReportLapsTime      VAR WORD
TempByte            VAR BYTE
digit               VAR BYTE
rndYN               VAR BYTE
PauseByte           VAR BYTE        'pause at end of run in seconds
PauseWord           VAR WORD        'used in lap report correction of pause
SavePause           VAR BYTE        'temp variable to store value while working
SaveADRate          VAR BYTE        'temp variable to store value while working
SaveSpeed           VAR BYTE        'temp variable to store value while working
PauseByte2          VAR BYTE
DigitsByte          VAR BYTE        'temp for getting digit input
DigitType           VAR BYTE         '1 =speed, 2=pause, 3=ADRate
ADRate              VAR BYTE        'accel / decel rate - large # is fast rate
TempWord            VAR WORD
TempWord2           VAR WORD
TempWord3           VAR WORD
value               VAR BYTE
ForwardFlag         VAR BIT
InBlockFlag         VAR BIT         '0 if on mainline / 1 if in block

ReedSW5             VAR porta.0     'pin 17  - reed in mountain
ReedSW1             VAR porta.1     'pin 18  -lowest reed
SerialPin           VAR porta.2     'used by debug not as SerialPin
ReedSW3             VAR porta.3     'pin 2   - center right reed
ReedSW2             VAR porta.4     'pin 3   - lower left reed
MainLine            VAR porta.5     'pin 4
ReedSWX7            VAR porta.6     'pin 15 - positioned lower side of xover
ReedSWX6            VAR porta.7     'pin 16 - positioned upper side of xover
'NOTE: swapped 6 & 7 8-26-10

TIP101              CON 2          'pin 6 for PWM  port b.0
ReedSW4             VAR portb.1     'pin 7   - upper left reed
ServoSW3            VAR portb.2    'pin 8
relay               VAR portb.3     'relay to control Direction pin 9
ServoSW1            VAR portb.4    'pin 10 
ServoSW2            VAR portb.5    'pin 11
BlueLED             VAR portb.6     'pin 12
IRin                VAR portB.7     'pin 13

StoppedTrain        VAR BIT         'shows train stopped or not =1 on stopped
StopTime            VAR WORD        'time to stop after reverse in siding
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
TVVCR               CON 165
FF                  CON 29
RW                  CON 28
Speed               VAR BYTE
Direction           VAR BIT
MainLineThereFlag   VAR BIT  '=0 if no main line / =1 if there
StopForMainLineFlag VAR BIT  'set if stop conditions exist
StoppedAtXingFlag   VAR BIT  ' set to 1 if stopped waiting for mainline to clear
ReedSWX6HitFlag     VAR BIT 'shows that reedsw6 was hit once
ReedSWX7HitFlag     VAR BIT 'shows that reedsw7 was hit once
IRpulse_length      VAR WORD(13)
xx VAR BYTE
Command VAR BYTE
VersionWhole        VAR BYTE
VersionDecimal      VAR BYTE
UP          CON 1   'for Direction relay
DOWN        CON 0   'for Direction relay
Straight    CON 1   'for turnouts
Turned      CON 0   'for turnouts
Hit         CON 0   'for reed switches
RtoL        CON 0   'for right to left relay
LtoR        CON 1   'for right to left relay
Yes         CON 0   'is main line train on track?
No          CON 1   'is main line train on track?

ansel = 0
cmcon = 7
trisa = %11111011
trisb = %10000010
Delay   VAR WORD
Delay=15 
CW1    CON   265
CCW1   CON   320
CW2    CON   265
CCW2   CON   320
CW3    CON   255
CCW3   CON   315
PWMFreq CON 2200
VersionWhole    =   8
VersionDecimal  =   0
MainLineThereFlag = 0   '=0 when no main line active
StopForMainLineFlag = 0 'indicates no main line train there
StoppedAtXingFlag = 0
laps=0
HIGH blueled

DATA @0,150,005, 1, 3   '150 speed, 005 pause, 001 adrate (1 is slow rate)
                                'stoptime = 5 sec
READ 0, speed
READ 1, pausebyte
READ 2, ADRate
READ 3, stoptime
HPWM TIP101, 0, 0			'all stop
DEBUG 10,13,10,13,10,13,10,13,10,13,10,13
'Debug 10,13,10,13,"Module Controller -SERVOS- (c) TrainElectronics.com",10,13
DEBUG "10-06-10 - Version ",#versionwhole,".",#versiondecimal,"x XP" ,10,13
DEBUG "no ICSP",10,13
PAUSE 2000
LOW servosw1:LOW servosw2:LOW servosw3
temp=0
ReedSWX6HitFlag =0
ReedSWX7HitFlag =0

VeryTop:
temp=temp+1
'debug 10,13,"15, 16, 4 ",#porta.6," ",#porta.7," ",#porta.5 , " ",#temp
'pause 500
'goto VeryTop: 

relay = UP 'Direction
Direction=UP    '1=up, 0=down

tempword=0
command=0
forwardflag=0
InBlockFlag=0
stoppedtrain=0

start0:
'low sound2:pause 100:high sound2 ' ring bell
PAUSE 500 
LOW blueled
DEBUG 10,13,"@ vt",10,13
GOSUB accel:PAUSE 200 'pause to get out of block - may help?
Start01:

WaitForReed:
'mainline = 0 if there is no train on main line track - =1 if train is there!
IF mainline=0 AND stoppedatxingflag = 1 THEN ' train cleared after stop
    GOSUB accel :DEBUG "@ restart!",10,13
    stoppedatxingflag=0    
    mainlinethereflag=0
ENDIF
'if mainline=yes and mainlinethereflag=0 then ' signal from other board that train is there
'    mainlinethereflag=1
'    debug "MLTF= ",#mainlinethereflag,10,13    'XXXXXXXXXXX Error here - reports this even if ML not there - causes loco to pause
'    'Pause 500 
'endif

command=0
TOGGLE blueled
IF IRin = 0 THEN GOSUB GetIR
start02:
IF command=OK THEN         ' stop if running if OK hit or start if stopped
    StoppedTrain=NOT(stoppedtrain)
    DEBUG "Stopped ",#stoppedtrain,10,13
    PAUSE 200
    command=0
    IF stoppedtrain = 1 THEN   '=1 if stopped
        HPWM TIP101, 0, 0
        PAUSE 1000
    ENDIF
    IF stoppedtrain = 0 THEN GOSUB accel    
ENDIF    
IF command=0 THEN skipit0:
IF command =	channelUP THEN speedup:
IF command =	channelDOWN THEN speeddown:
IF command =	volumeDOWN THEN relayoff:
IF command =	volumeUP THEN relayon:
IF command =    FF THEN IncreaseStopTime
IF command =    RW THEN DecreaseStopTime
IF command =    ENTER THEN GetDigits:

skipit0:
'debug #reedsw1," ",#reedsw2," ",#reedsw3," ",#reedsw4," ",#reedsw5,10,13: ''," Speed= ",#speed,10,13:goto verytop:
IF reedsw1=1 AND reedsw2=1  AND reedsw3=1 AND reedsw4=1 AND reedsw5=1_' then waitforreed:_
 AND ReedSWX6 =1 AND ReedSWX7 =1 THEN waitforreed:    


IF (ReedSWX6 = Hit AND direction = UP) OR (ReedSWX7 = Hit AND direction = DOWN) THEN
    DEBUG "Xing Hit dir=",#direction,10,13
    IF mainline=1 THEN
        DEBUG "stopped @ xing",10,13
        IF MainLineThereFlag = 1 THEN 'set stop conditions
             IF StopForMainLineFlag = 1 THEN
                HPWM TIP101,0,0:LOW TIP101 'gosub decel
                StoppedAtXingFlag = 1  
             ENDIF           
        ENDIF
        HPWM TIP101,0,0:LOW TIP101
        stoppedatxingflag=1
    ENDIF     
ENDIF

GOTO skip1

IF ReedSWX6 = Hit AND ReedSWX6HitFlag =0  AND direction = UP THEN  ' - positioned lower side of xover
        DEBUG "swx6 hit" ,10,13
        ReedSWX6HitFlag =1:ReedSWX7HitFlag =0
        IF MainLineThereFlag = 1 THEN 'set stop conditions
             IF StopForMainLineFlag = 1 THEN
                HPWM TIP101,0,0:LOW TIP101 'gosub decel
                StoppedAtXingFlag = 1  
             ENDIF           
        ENDIF
        IF direction = DOWN THEN stopformainlineflag=0
ENDIF    

IF ReedSWX7 = Hit AND ReedSWX7HitFlag=0 AND direction = DOWN THEN  ' - positioned upper side of xover
        DEBUG "swx7 hit" ,10,13
        ReedSWX6HitFlag =0:ReedSWX7HitFlag =1
        IF MainLineThereFlag = 1 THEN 'set stop conditions
             IF StopForMainLineFlag = 1 THEN
                HPWM TIP101,0,0:LOW TIP101 'gosub decel
                StoppedAtXingFlag = 1             
             ENDIF
        ENDIF
        IF direction = UP THEN stopformainlineflag=0
ENDIF    

skip1:

IF reedsw1=Hit THEN 'and Direction = down then
        DEBUG "1 hit dn",10,13
        GOSUB ResetFlags
        GOSUB decel     
        GOSUB StopBetweenLegs
        relay = RtoL
        GOSUB sw1straight 
        DEBUG "sw1=S "
        GOSUB accel
        Direction=UP
        DEBUG "Dir UP",10,13
ENDIF

IF reedsw2=Hit AND Direction=UP THEN
        DEBUG "2 hit up",10,13
        GOSUB ResetFlags:StopForMainLineFlag=1
        GOSUB decel
        GOSUB StopBetweenLegs      
        relay=LtoR
        GOSUB sw1curved
        DEBUG "sw1=C "
        GOSUB sw2straight
        DEBUG "sw2=S",10,13  
        GOSUB accel
ENDIF      

IF reedsw3=Hit AND Direction=UP THEN
        DEBUG "3 hit up",10,13
        GOSUB ResetFlags
        GOSUB decel
        GOSUB StopBetweenLegs
        relay=RtoL
        GOSUB sw2curved
        DEBUG "sw2=C "
        GOSUB sw3straight
        DEBUG "sw3=S",10,13        
        GOSUB accel
ENDIF

IF reedsw4=Hit AND direction=UP THEN
        DEBUG "4 hit up",10,13
        GOSUB ResetFlags
        GOSUB decel
        GOSUB StopBetweenLegs        
        relay=LtoR
        GOSUB sw3curved
        DEBUG "sw3=C",10,13
        GOSUB accel
ENDIF

IF reedsw5=Hit THEN 'and direction=up then
        DEBUG "5 hit up",10,13
        GOSUB ResetFlags
        GOSUB decel
        GOSUB StopBetweenLegs
        Direction=DOWN
        DEBUG "Dir DOWN",10,13
        relay=RtoL
        GOSUB sw3curved
        DEBUG "sw3=C",10,13        
        GOSUB accel
ENDIF

IF reedsw4=Hit AND direction=DOWN THEN
        DEBUG "4 hit down",10,13
        GOSUB ResetFlags
        GOSUB decel
        GOSUB StopBetweenLegs
        relay=LtoR
        GOSUB sw3straight
        DEBUG "sw3=S "                        
        GOSUB sw2curved
        DEBUG "sw2=C",10,13                        
        GOSUB accel
ENDIF

IF reedsw3=Hit AND direction=DOWN THEN
        DEBUG "3 hit down",10,13
        GOSUB ResetFlags:StopForMainLineFlag=1
        GOSUB decel
        GOSUB StopBetweenLegs
        relay=RtoL
        GOSUB sw2straight
        DEBUG "sw2=S "
        GOSUB sw1curved
        DEBUG "sw1=C",10,13                
        GOSUB accel
ENDIF

IF reedsw2=Hit AND direction=DOWN THEN
        DEBUG "2 hit down",10,13
        GOSUB ResetFlags
        GOSUB decel
        GOSUB StopBetweenLegs
        relay=LtoR
        GOSUB sw1straight
        DEBUG "sw1=S",10,13        
        GOSUB accel
ENDIF
GOTO WaitForReed:

speedup:
StoppedTrain=0
IF speed > 250 THEN start0:
speed=speed+2
WRITE 0, speed
GOTO dospeed:

speeddown:
IF speed < 5 THEN start0:
speed=speed -2
WRITE 0, speed

dospeed:
HPWM TIP101, speed, PWMFreq
DEBUG 13,10,"Speed= ",#speed
WRITE 0, speed
GOTO start01:

relayon:
IF direction =1 THEN 
DEBUG "error",10,13
GOTO start01:	'if already going backward skip
ENDIF
GOTO dorelay:

relayoff:
IF direction=0 THEN
DEBUG "error",10,13
GOTO start01:	'if already going forward skip
ENDIF

dorelay:
GOSUB Decel
TOGGLE relay
GOSUB Accel:
direction=NOT(direction)
GOTO start01:

IncreaseStopTime:
IF stoptime < 98 THEN
    StopTime=StopTime + 1
'    high relaypolarity:pause 50:low relaypolarity
    GOSUB ShowStopTime
    WRITE 3, stoptime
ENDIF
GOTO start01:

DecreaseStopTime:
IF stoptime > 1 THEN
    StopTime=StopTime - 1
'    high relaypolarity:pause 50:low relaypolarity
    GOSUB ShowStopTime
    WRITE 3, stoptime
ENDIF
GOTO start01:

Decel: 
DEBUG 13,10,"D-Speed= ",#speed, "  "
FOR Temp=speed TO 0 STEP -5'changed to stop locos more rapidly 4-13-10 -adrate
    HPWM TIP101, Temp, PWMFreq
    'debug "."
    temp1=255-speed: temp1=temp/20  'adjusts ad rate for low top speed
    PAUSE  temp1 
NEXT Temp
HPWM TIP101,0,0:LOW TIP101
DEBUG 10,13
RETURN

Accel:
DEBUG 13,10,"A-Speed= ",#speed,"  "
FOR Tempword3=10 TO speed STEP adrate
    HPWM TIP101,  tempword3,PWMFreq
    'debug "."
    temp1=255-speed: temp1=temp1/10  'adjusts ad rate for low top speed
    PAUSE  temp1 
NEXT Tempword3
HPWM TIP101,  speed,PWMFreq
DEBUG "p 1.5 sec", 10,13
PAUSE 800 ' allow the train to pass the reed switch on its way out
DEBUG "p DONE!", 10,13
RETURN

StopBetweenLegs:
GOSUB ShowStopTime
FOR temp= 1 TO stoptime 
    DEBUG #temp," "
    FOR temp2=1 TO 4
        TOGGLE blueled
        GOSUB getir          'problem if remote command seen here!
        IF command <>0 THEN start02:    'exit on IR command
    NEXT temp2
NEXT temp
DEBUG 10,13
RETURN

GetIR:
Getstartbits:
PULSIN IRin ,0,IRpulse_length(0)
IF IRpulse_length(0) < 400 THEN
   'goto getstartbits
   RETURN
ENDIF

FOR xx=1 TO 12
PULSIN IRin,0,IRpulse_length(xx)
NEXT xx

displaybits:
IF IRpulse_length(1) < 200 THEN 
    Command.Bit0=0 
    ELSE 
    Command.Bit0=1
ENDIF
IF IRpulse_length(2) < 200 THEN
    Command.Bit1=0
    ELSE
    Command.Bit1=1
ENDIF
IF IRpulse_length(3) < 200 THEN
    Command.Bit2=0
    ELSE
    Command.Bit2=1
ENDIF
IF IRpulse_length(4) < 200 THEN
    Command.Bit3=0
    ELSE
    Command.Bit3=1
ENDIF
IF IRpulse_length(5) < 200 THEN
    Command.Bit4=0
    ELSE
    Command.Bit4=1
ENDIF
IF IRpulse_length(6) < 200 THEN
    Command.Bit5=0
    ELSE
    Command.Bit5=1
ENDIF
IF IRpulse_length(7) < 200 THEN
    Command.Bit6=0
    ELSE
    Command.Bit6=1
ENDIF
IF IRpulse_length(8) < 200 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 ,13,10
'serout serial_out,n9600,[13,10,"command", #command," speed ", #speed," PauseByte ", #PauseByte, 13,10]
RETURN 


GetDigits:
DEBUG 10,13, "@G Digits", 10,13
HPWM TIP101, 0, 0	'all stop
digit=2
command=0
DigitsByte=0
HIGH BlueLED:PAUSE 1000:LOW BlueLED
GetDigits0:
GOSUB GetIR:
IF command=0 THEN GetDigits0
IF command > 137 OR command < 128 AND command <>139 AND command <> 0 THEN 
    GOTO VeryTop:	'abort on non number 0-9
ENDIF
IF command=139 THEN GetDigits0:
Value=command-127
IF Value=10 THEN value=0

IF value=0 THEN HIGH BlueLED:PAUSE 500:LOW BlueLED
FOR tempbyte=1 TO value:HIGH BlueLED:PAUSE 200:LOW BlueLED:PAUSE 200:NEXT tempbyte
DigitsByte=DigitsByte*10+Value
digit=digit-1
PAUSE 200:command=0
IF digitsbyte > 255 THEN digitsbyte=255
IF digit=0 THEN 
    
       StopTime =digitsbyte
        WRITE 3,stoptime
'        write 4, stoptime-temp*256

      GOSUB ShowStopTime:DEBUG " ",#temp," ",#stoptime-temp*256,10,13
    ' speed=DigitsByte
     GOTO Start0: 'StartReverse:
ENDIF
GOTO GetDigits0:

AllRelaysOff:
LOW ServoSW3:LOW ServoSW2:LOW ServoSW1 ':low RelayPolarity:
RETURN

SW1curved:
DEBUG,"1=S  " ,#direction ,10,13
FOR Temp=CW1 TO CCW1 STEP 1
    PULSOUT servosw1, temp
    TOGGLE blueled
  PAUSE Delay
NEXT Temp
RETURN

SW1straight:
DEBUG,"1=S  "  ,#direction  ,10,13
FOR Temp=CCW1 TO CW1 STEP -1
  PULSOUT servosw1, temp
  HIGH blueled
  PAUSE Delay
NEXT Temp
RETURN

SW2Curved:
DEBUG,"2=C  ",#direction  ,10,13
FOR Temp=CW2 TO CCW2 STEP 1
    PULSOUT servosw2, temp
    TOGGLE blueled
  PAUSE Delay
NEXT Temp
RETURN

SW2Straight:
DEBUG,"2=S  " ,#direction  ,10,13
FOR Temp=CCW2 TO CW2 STEP -1
  PULSOUT servosw2, temp
  HIGH blueled
  PAUSE Delay
NEXT Temp
RETURN

SW3Straight:
DEBUG,"3=S  " ,#direction  ,10,13
FOR Temp=CW3 TO CCW3 STEP 1
    PULSOUT servosw3, temp
    HIGH blueled
  PAUSE Delay
NEXT Temp
RETURN

SW3Curved:
DEBUG,"3=C  "  ,#direction  ,10,13
FOR Temp=CCW3 TO CW3 STEP -1
  PULSOUT servosw3, temp
  TOGGLE blueled
  PAUSE Delay
NEXT Temp
RETURN

ResetFlags:
StopForMainLineFlag = 0:ReedSWX6HitFlag =0:ReedSWX7HitFlag =0:RETURN

ShowStopTime:
DEBUG "STime= ",#stoptime,10,13:RETURN


 

Schematic - 16F684 Controller

Software - 16F684 - monitors main line train via a single laser & optical sensor and alerts the main controller if a train is on the mainline
' 04-23-10  -revisited 10-6-10
 ' turns laser on for 5 us then tests phototransistor to see if it "sees" laser
 ' demonstrates that a very fast pulse of the laser is enough to detect
 ' effectively dims the laser 
 ' Tests several hundred times / second
 
 'Note:  for train detection if the button is set so that the laser is on full
    ' bright then the reaction to the break in the laser beam will be immediate
DEFINE DEBUG_REG PORTA  
DEFINE DEBUG_BIT 0         ' PIN 8 on 16f88
DEFINE DEBUG_BAUD 9600 
DEFINE DEBUG_MODE 1     ' Set 'DEBUG mode: 0 = true, 1 = inverted
ansel=0                 'use pins as digital rather than analog
CMCON0= 7               'Disable comparator - makes portc LEDs work properly
DEFINE OSC 8            'use 8 mhz oscillator
OSCCON = $70            'set clock speed 
INTCON = %00001100       '00xx11xx to be CCP1 mode
option_reg.7     =0   'turn on wpu PortA
wpu              = %00010000  'just a.4 for ModeSwitch
SerialOut        VAR porta.0      'pin 13
NotUseda1        VAR porta.1      'pin 12
PhotoTran        VAR portc.5      'pin 10 
Laser            VAR portc.0      'pin 9
NotUseda3        VAR porta.3      'pin 4
FullBright       VAR porta.2      'pin 3 - switch to brighten laser for alignment
'LED1             var porta.2      'pin 11
'NotUseda5        var porta.5      'pin 2
LEDRed           VAR portc.1      'pin 9
LEDGreen         VAR portc.2      'pin 8  ' from pin that drove LED transistor
NotUsedc3        VAR portc.3      'pin 7  ' from pin on board to LED driver base
Relay            VAR portc.4      'pin 6  ' to meter on circuit board (R 21)
NotUsedc5        VAR portc.5      'pin 5  ' output to 16 ohm speaker through cap 
Temp             VAR WORD
ToggleCounter    VAR BYTE
Hit              VAR BIT
BrightModeFlag   VAR BIT
NoTrainCounter   VAR WORD       'need to see a number of no-hits to reset
trisa            = %00010100     
trisc            = %00100000  

DEBUG 10,13,"Laser Test v1.6d " ,10,13
DEBUG "Module Maniline Detector(c) d. bodnar 10-06-10",10,13,10,13,10,13
DEBUG "power on with button IN will only do test at full brightness",10,13,10,13
DEBUG "power on wiogh button OUT will give full features bright & dim", 10,13
PAUSE 600
DEBUG 10,13,"Note: not showing any indication that laser is seen using DEBUG - only breaks as zeros",10,13
IF FullBright=1 THEN    'if button in on power up make it all work without going dim
    BrightModeFlag=1
    ELSE
    BrightModeFlag=0
ENDIF
IF BrightModeFlag=1 THEN DEBUG 10,13,"Full Operation Mode bright or dim",10,13
Top:
'toggle laser:pause 500:goto top
'high led1:pause 500:low led1:pause 500:goto top
HIGH Laser
PAUSEUS 1
IF PhotoTran=1 THEN
    Hit=1 
    HIGH LEDGreen:LOW LEDRed
    LOW Relay
    ELSE 
    Hit=0
    LOW LEDGreen:HIGH LEDRed
    HIGH Relay
    IF FullBright=1 OR BrightModeFlag=1 THEN 'only do the wait routine if dimmed
    GOTO StayTillTrainPasses:
     ENDIF
ENDIF

IF FullBright=1 THEN LOW Laser 'if switch off dim Laser else leave on full
IF Hit=0 THEN DEBUG #Hit," "
PAUSE 10
GOTO Top
 

StayTillTrainPasses:
HIGH Laser:PAUSEUS 1
IF PhotoTran=0 THEN 
    NoTrainCounter=0
    IF FullBright=1 THEN LOW Laser 'if switch off dim Laser else leave on full
    DEBUG #Hit," "
    PAUSE 10
    GOTO StayTillTrainPasses:
ENDIF
IF FullBright=1 THEN LOW Laser
NoTrainCounter=NoTrainCounter+1
DEBUG " NHC= ",#NoTrainCounter,10,13 
 ToggleCounter = ToggleCounter + 1
IF ToggleCounter=10 THEN
 TOGGLE LEDRed
 ToggleCounter=0
ENDIF
IF NoTrainCounter=200 THEN     '300 = about 3 seconds
    LOW LEDGreen:HIGH LEDRed
    NoTrainCounter=0
    GOTO Top
ENDIF       
GOTO StayTillTrainPasses:






 

 

 
the "Track Power to Detect Direction" now goes to the LED on the relay doide.


' IR removed 9-15-2016 - replaced with 5 volt relay to turn off track power
'  tapped into the led on the relay diode to send forward/reverse info to opto. works!

' 9-14-2016 Test of IR output to stop/start train on module with pushbutton'
' when the train hits a reed switch AND power indicates that it is going from right to left
' the train will stop by sending two fast codes for STOP

' a button will restart the train by sending two fast codes for STOP (same start/stop)

'IR is putput on pin 7 OUT 0 (ignore the 1 after infraout as it needs to be "1"
' Reed switch on pin 5
' Test for direction is optocoupler on pin 2

PULLUP %00010100


TOP:
'debug
b0=pinc.2 'pin 5 (reed sw)
b1=pinc.3 'pin 4 (opto)
b2=pinc.4 'pin 3 (restart button)
if b0=0 and b1= 0 then
goto TurnOff:
endif

if b2=0 then
goto TurnOn:
endif

goto top:




TurnOff:
pause 1000 ' needed to coast past reed sw
Low c.0
goto top:

TurnOn:
High c.0
pause 1000
goto top:


for b3= 1 to 2
infraout 1, 20' code 148 for OK - MENU on phillips
pause 45
next b3
pause 1000
goto TOP:
 

 

 

free web counter