Automatic Switch Project
Revised 09-4-06
Progress:
Tuesday, August 22 | Monday, August 28 | |
Tuesday, August 29 | ||
Thursday, August 24 | Wednesday, August 30 | Monday, September 4 |
Friday, August 25 | Thursday, August 31 | |
Sunday, August 27 | Friday, September 1 | |
The objective of this controller project is to have automatic block and switch control of five separate engines that run on two completely independent loops of track. Part of each loop is outside (public) and part is inside (hidden from public view). The inside part has switch controlled sidings where the idle trains wait. The inner loop can accommodate three trains and the outer two trains. When a train completes its outside run and enters the inside area it is automatically assigned to an empty siding. It enters the siding and, when it reaches an optical sensor, power is removed from that block. One of the idle trains is activated and moves onto the outside area of the layout. This process continues alternating trains so that two trains are outside (one on each of the loops) while the other trains wait inside. |
Progress |
Tuesday, August 22 Built prototype board using a PICAXE 28X microcontroller, 3 SPDT high current relays (Omron, 16 amp / 30 volt DC), H-Bridge (TI - SN754410NE), 5 volt filtered power supply. In this top view the microcontroller is at the bottom next to the H-Bridge. The three relays are together in the upper right. The power supply is to the left. The connection block in the far upper right (4 screws) connects the 3 relays to the 3 independent blocks of insulated track. The connector in the lower right goes to the two LGB switch motors This is a view of the back of the hand wired prototype board. This will all be replaced with a custom printed circuit board.
|
Wednesday, August 23 Completed installation and testing of one of three infrared emitter detector pairs. In the photo below the back of the IR detector is shown at the top. The small clear LED lights when the emitter and detector pair are NOT properly aligned and goes out when they are aligned. A four conductor cable goes to each pair. This provides +5 volts, ground, 38 KHz for the LED and an input for the controller that goes high when the detector sees the IR from the emitter.
The schematic was revised to include the IR pairs and H-Bridge. The LCD display was removed as this will be on a separate circuit board. The main task of the day was the design of the printed circuit board. This was completed and the drawing was sent off to Oregon to be fabricated. Delivery is scheduled for Monday. The red layer shows traces that are on the top of the board while green shows traces on the bottom. The yellow layer will not be visible on the finished boards.
Notes: |
Thursday, August 24 The three sets of IR emitter / detector sensors were completed and tested. Track was laid out with three separate sidings that all met and fed the same main loop. Insulators were placed to isolate blocks in each siding. Powered LGB switches were placed on the left side of the layout (the trains will always run in a counter clockwise direction) and unpowered switches were placed on the right.
Three small engines are running in the two photos. A PRR switcher pulling a log car on the smallest loop, a Hartland railcar on the middle one (it is blurred in the photo below as it is moving as it approaches the IR sensors) and an Eggliner pulling a gondola on the longest loop..
Some experimentation showed that the LGB powered switches didn't work well when cars and engines relied on the internal springs in a non-powered mode - long rubber bands were used to return the switches once a train passed.
The reset of the day was spent on software development. The latest version of the software for the PICAXE 28X is at the very bottom.. |
Friday, August 25 The software matured to the point that it did what was intended. The next set of improvements will involve anticipating and dealing with unusual situations (where a train may not return to the loop in a set time or if one is removed from a siding unexpectedly) The photo below shows the Hartland car going between a set of sensors.
Some configuration will be done through an AristoCraft accessory receiver. This will allow a function button to stop all trains after a run is completed.
The system was tested all afternoon and no glitches were observed. The image below is of the display - note that it shows 1117 laps. The actual number was in excess of 1200 but I got tired of taking pictures.
The serial LCD microcontroller arrived and was interfaced to the PICAXE 28X. The software was modified to use the new control codes and tested successfully |
Sunday, August 27 Switches were added to the relay outputs to allow you to manually "nudge" the engines in the blocks even if the power to the blocks are off. Three switches allow control of the three blocks. Diodes were placed in series with the power that goes to the blocks. Each of the diodes drops the voltage in the blocks by 0.7 volts. An array of switches and diodes will be installed so that you can use one or more of three switches to add 0, 1, 2, 3, 4, 5, 6 or 7 diodes. A binary grouping has the first switch add one diode, the second switch adds two and the third switch adds four. Both of the above changes are detailed in the schematic below. Please click to enlarge. The software was modified to make sure that an engine was sitting directly in front of a sensor when power is removed from a block. This is to resolve a problem where a sensor is blocked by the front of a rail car, the power is removed from the block and the car rolls to a place where the beam goes through an opening in the car (or on a train between cars). The new routine will check the sensor in a loop and nudge the engine should the beam not be blocked after the power is removed and it pauses for a second or so.
|
Monday, August 28 The custom circuit boards arrived. All three of the boards were populated and tested successfully! The only error on the boards was a connection to the block control / relay board to +5 volts rather than to +12 volts. This was easily corrected. |
Tuesday, August 29 The next major project was to complete the design and construction of the relay / block control boards. These boards are interfaced to the main processor board by a five conductor cable that delivers +12 volts for the relays, ground and three control signals that activate any of the three block control relays. In addition to the three relays there are seven diodes is three groups, 1, 2 and 4 diodes each. SPDT toggle switches can put any, all or none of the diodes in series with the track voltage, dropping the voltage to the blocks up to nearly 5 volts in .7 volt increments. Here you see the three relays and the 4 pole header that will connect to the blocks. Also note the marks on the board in the upper left corner. They indicate where the voltage control diodes will be placed.
Here the same board is seen from the back with the header and relays soldered in. The holes for the 3 amp diodes have been drilled out so that their larger leads will fit.
The diode leads are bent so that they can be inserted vertically.
The diodes have been inserted in the board so that they can be wired in series.
Here is a view of the diodes as soldered to the back.
Each relay is connected to a diode, to protect the circuit from voltage surges when it is in operation, and a transistor that is used to activate it. The orientation of the diodes and transistors is critical!
The back of the board shows where some foil needs to be removed to protect against short circuits where the diodes connect to the relays.
The additional parts shown here are the transistors and the resistors that connect to their bases.
|
Wednesday, August 30 The main objective today was to place the LCD display unit, main microcontroller board, relay/block control board and the various switches and buttons in a Plexiglas housing. The mounting material is 1/4" clear Plexiglas.
The photos below are of a complete unit (front and back) as it is being tested.
|
Thursday, August 31 Three duplicate unit were made up with two controlling the layout and one spare. Switches were added for Menu and Enter (upper right in the photo above.) These will be used to make program changes to the unit without the need to use the PICAXE programmer. Each of the three control units were tested.
|
Friday, September 1 The hardware platform was fine tuned a bit by reinforcing some connections and supporting boards with standoffs. Most of the day was spent working on software so that it additional features could be incorporated. These include:
|
Saturday, September 2 Additional progress was made in fine tuning and adding features to the software. A basic menu was added to allow the end user to select either two or three train operation. Routines were added to help align engines with sensors and to bring the running of trains to a stop when both the MENU and ENTER buttons were pressed at the same time. |
Sunday, September 3 The AristoCraft accessory receiver was interfaced to the circuit board (pin 15). This allows the remote control buttons "D" and "E" to shut down the train's runs when all trains are back at the station. In order to make the connection a 100K resistor was run between pin 15 and +5volts. One of the receiver's leads was run to ground and the other to pin 15. The original "nudge" buttons were replaced by ones that can handle 1.5 amps. The original buttons were likely to fail after continued use. |
Monday, September 4 Testing of the two main units and the backup continued. Labels were applied to help with setup and use. Additional work was done on the user manual (see below)
|
User Manual Hardware Installation:
Software Setup:
Speed Control in Blocks:
Nudge Control Buttons
|
|
'd. bodnar 9-4-06 'works with 2 or 3 trains based on value of SensorValue 'problem with intermittent detection of all sensors blocked cured by turning PWM on/off 'rather than leaving it on constantly 'TODO: ' 1. XXX configure one button to be an "end after all in blocks" and interface to remote control - may use pin 2 (input port a0) ' ("if porta pin0 = 1 then jump") ' 2. Create menu function - variables to be modified and written to memory (WRITE location, bytevalue) - 0-127 available on 28x ' a. 3 or 2 engines / blocks ' b. pause time for "nudge" function ' c. fixed order or random (random to allow repeats or no?) ' d. reset counter on power up or keep running count? ' e. time between trains exiting blocks - quick, fixed or random? ' f. ' 3. XXX Menu called up by pressing and holding MENU button on power-up (Menu on pin 14 (in3)) ' a. change data through button or pot (pot set up on pin 5 (an3)) ' 4. XXX When "Sensors not Blocked" flashes show which one(s) (is/are) not blocked ' 5. XXX BUG - when speed is too fast a long car with big spaces (lil critter & log car) set off sensor like it is back as it leaves ' 6. XXX Stop all blocks when 2 or more sensors not blocked after or during first and subsequent runs symbol relay1 = 0 symbol relay2 = 1 symbol relay3 = 2 symbol sensor1 = pin5 symbol sensor2 = pin6 symbol sensor3 = pin7 symbol EnterSw = pin2 'pin 13 on PICAXE - 1 when out, 0 when pushed symbol MenuSw = pin3 'pin 14 on PICAXE - 1 when out, 0 when pushed symbol EndSwitch = pin4 'pin 15 on PICAXE - 1 when out, 0 when pushed symbol swmotor1 = 3 symbol swmotor2 = 4 symbol swdir1 = 5 'h-bridge symbol swdir2 = 6 'h-bridge symbol nextloop = b4 symbol temp0 = b3 symbol temp1 = b5 symbol temp2 = b2 symbol temp3 = b6 symbol tempCL = b7 'temp storage of Current Loop Engine symbol Laps = w6 symbol EndFlag = bit8 symbol version = 28 symbol dlay = 120 symbol SensorValue = b8 symbol PinsByte = b0 'using b0 allows us to access each sensor bit with bit5, bit6 & bit7 NextLoop = 0 'use 0-2 in stead of 1-3 for branch statement 'NOTE SensorValue must be set on first run with MENU!!!!!!!!!!!!!!!!!!! 'SensorValue = %11100000 ' %11100000 for 3 trains and %01100000 for 2 trains 'SensorValue = %01100000 ' %11100000 for 3 trains and %01100000 for 2 trains read 0, SensorValue if SensorValue <>%11100000 and SensorValue<>%01100000 then fixSensorValue goto NoNeedtoFix fixSensorValue: SensorValue=%11100000 'set to 3 trains if read is bad NoNeedtoFix: pause 6000 'pause while LCD wakes up and does test display pause 100 if SensorValue=%11100000 then engines3a temp0=2:goto skipover1a: engines3a: temp0=3 skipover1a: serout 7, t2400,("?f?c0"):pause 200:serout 7,t2400,("?f?c0"):pause 200 '?c0 turns cursor off serout 7,T2400,("Switch Controller?nd. bodnar 8-2006?nVersion ",#version," Trains=",#temp0) serout 7, T2400,("?x00?y3 MENU FOR SETTINGS") Check4MenuButton: for temp1=1 to 100 if MenuSw=0 then goto MENU pause 30 next temp1 serout 7, T2400,("?fResetting Switches") gosub sw1turn:pause 200:gosub sw2turn:pause 200:gosub sw1straight:pause 200:gosub sw2straight:pause 400 ' set for initial run 'pause 4000 Start: PWMOut 1, 25, 52 ' 38.4 kHz to IR emitters temp1=pins & SensorValue PWMOut 1,0,0 if temp1 <> SensorValue then ShowError serout 7,T2400,("?fSensors All Blocked") goto start1: ShowError: 'SensorValue=pins serout 7,T2400,("?fSensor(s) OPEN ",#temp1) serout 7,t2400,("?nSensor 1 = ") temp0= temp1 & %00100000 if temp0=0 then closed1 temp0=temp1 & %00100000 if temp0=1 then open1 open1:serout 7,T2400,("OK"):goto show2 closed1:serout 7,T2400,("open"):goto show2 show2: serout 7,t2400,("?nSensor 2 = ") temp0= temp1 & %01000000 if temp0=0 then closed2 temp0= temp1 & %01000000 if temp0=1 then open2 open2:serout 7,T2400,("OK"):goto show3 closed2:serout 7,T2400,("open"):goto show3 show3: if SensorValue=%01100000 then done: serout 7,t2400,("?nSensor 3 = ") temp0=temp1 & %10000000 if temp0=0 then closed3 temp0=temp1 & %10000000 if temp0=0 then open3 open3:serout 7,T2400,("OK"):goto done closed3:serout 7,T2400,("open"):goto done done: pause 500 goto start: Start1: endflag=0 serout 7,T2400,("?fAll Trains Ready!?n?nPress ENTER?nto START") loop: if EnterSw =1 then loop: serout 7,T2400,("?f") Start2: 'serout 7,T2400,("?fnextloop= ",#nextloop) if endflag=1 then Start1 Branch NextLoop, (one, two, three) serout 7,T2400,("?fnextloop= ",#nextloop):serout 7,T2400,("?nERROR FIX ?nPausing 60 seconds"):pause 60000 nextloop=0:goto start2 'error trap - sometimes hung here end one: gosub Sw2Straight:gosub Sw1Straight 'return 1 to 1 high NextLoop 'start train on block # NextLoop +1 goto AddOneToNextLoop two: gosub sw1turn:gosub sw2straight 'return 2 to 2 high NextLoop 'start train on block # NextLoop +1 goto AddOneToNextLoop three: gosub Sw2Turn high NextLoop 'start train on block # NextLoop +1 goto AddOneToNextLoop end AddOneToNextLoop: Laps=Laps+1 TempCL=NextLoop 'stores Train Running for possible nudge adjust below NextLoop=NextLoop + 1 serout 7,T2400,("?x00?y0Train Out=", #NextLoop, " Lap=",#Laps) serout 7,T2400,("?x00?y1 ?x00?y2 ") 'clear lines 2 & 3 if nextloop= 2 and SensorValue = %01100000 then FixIt if NextLoop = 3 and SensorValue=%11100000 then FixIt goto Wait2Clear FixIt: temp3=NextLoop 'store for use in Wait2Clear routine NextLoop=0 goto Wait2Clear Wait2Clear: ' wait for train to clear sensor 'may need to add a pause, too (see next note) for temp2=1 to 255 'Was 100 - increased to insure that a car with big breaks won't show end at low speed PWMOut 1, 25, 52 ' 38.4 kHz to IR emitters temp1=pins & SensorValue PWMOut 1, 0,0 if temp1 = SensorValue then Wait2Clear next temp2 temp3=tempCL+1 serout 7,T2400,("?x00?y1Sensor ",#temp3," Cleared") 'wait for train to return to end of block and block sensor serout 7,T2400,("?x00?y2Waiting for Return ") Wait4Return: gosub CheckEndSwitch: gosub CheckForMultipleSensorsOpen: 'if endflag=1 then Start: PWMOut 1, 25, 52 ' 38.4 kHz to IR emitters temp1=pins & SensorValue PWMOut 1, 0,0 if temp1 <> SensorValue then Wait4Return low relay1:low relay2:low relay3 DoubleCheck: pause 1000 PWMOut 1, 25, 52 ' 38.4 kHz to IR emitters temp1=pins & SensorValue PWMOut 1, 0,0 if temp1 <> SensorValue then NudgeForward goto start2: serout 7,T2400,("?x00?y2Nudging... ") NudgeForward: high tempCL pause 300:low tempCL goto DoubleCheck Sw1Straight: high swdir1:low swdir2 high swmotor1:pause dlay low swmotor1 serout 7,T2400,("?x00?y3Switch1=S") return Sw1Turn: high swdir2:low swdir1 high swmotor1:pause dlay low swmotor1 serout 7,T2400,("?x00?y3Switch1=T") return Sw2Straight: high swdir1:low swdir2 high swmotor2:pause dlay low swmotor2 serout 7,T2400,("?x11?y3Switch2=S") return Sw2Turn: high swdir2:low swdir1 high swmotor2:pause dlay low swmotor2 serout 7,T2400,("?x11?y3Switch2=T") return 'ClearLCD: serout 7,T2400,("?f") pause 200 return CheckEndSwitch: if endswitch=0 or MenuSW=0 and EnterSW=0 then setendflag return setendflag: endflag=1 serout 7,T2400,("?fEnd Flag Set?n STOPPING?n at End of Lap") 'pause 3000 return CheckForMultipleSensorsOpen: for temp0=1 to 5 'check 5 times to make sure reading is valid PWMOut 1, 25, 52 ' 38.4 kHz to IR emitters temp1=pins & SensorValue PWMOut 1, 0,0 'serout 7,T2400,("?x00?y3temp= ",#temp1," ") 'if temp=28 or temp=60 or temp=92 or temp=156 then badSensor if SensorValue=%11100000 and temp1<>0 and temp1<>32 and temp1<>64 and temp1<>128 then NoBadSensors: if SensorValue=%01100000 and temp1<>0 then NoBadSensors: next temp0 BadSensor: serout 7,T2400,("?fBAD SENSOR?n STOPPING?n ALL") low relay1:low relay2:low relay3 Pause 3000 goto start NoBadSensors: return MENU: serout 7,T2400,("?f MENU") pause 1000 if SensorValue=%11100000 then engines3 temp0=2:goto skipover1: engines3: temp0=3 skipover1: serout 7,T2400,("?f# of Engines Now = ",#temp0) serout 7,T2400,("?nENTER to Change?nMENU to Skip") CheckSwitch1: if MenuSW=0 then skipover2: if EnterSW=0 then ChangeEngineNumber goto CheckSwitch1 ChangeEngineNumber: if SensorValue=%11100000 then EnginesTo2: EnginesTo3: SensorValue=%11100000:write 0,SensorValue serout 7,T2400,("?fNEW VALUE WRITTEN"):pause 1000 goto MENU: EnginesTo2: SensorValue=%01100000:write 0,SensorValue serout 7,T2400,("?fNEW VALUE WRITTEN"):pause 1000 goto MENU if enterSW=1 then menu 'stay here till button pushed (gives a "0" when pushed) SkipOver2: 'serout 7, T2400,("?f") goto start |