Robot Trains in the Garden

d. bodnar  revised 4-18-2004  4:00 pm

 Click here for MS Word Version


I have only been actively involved with garden railroading for a little over one year but have found it to be a wonderful way to use the skills and interests that I have developed over the years in other hobbies.  For example, I used my love of woodworking to help me design and construct two scratch built bridges and nearly 100 trestle bents to support much of the 200 foot main line on the railway.  My interests in photography, computers and web pages allowed me to document the work on the railway and share it with my friends and family, wherever they may live. (see: )

My latest collaboration between hobbies involves using my work with programming small, single board microprocessors and using them to control devices and sense things around them.  For many years I have worked with small Basic Stamp microprocessors (see: ).  I have used the Basic Stamp to sense and react to temperature changes, monitor and control the charging of batteries, record the acceleration of model rockets and to operate small, autonomous robots.  This project is a logical extension of my work with robotics as it involves using a similar microprocessor to control a battery operated railroad engine.  The system is designed to have the engine slowly accelerate from a complete stop and then cruise at a preset speed until it passes over a magnet located on the track.  When this happens a reed switch closes and the microprocessor gently slows the engine to a full stop.  After a short pause the engine reverses and starts up again until it passes over another magnet when the process repeats.

Although the original objective of the system was the auto-reverse system as described above, the hardware is capable of much more sophisticated operation by modifying the software.  It could, for example, have a train start off and pause any number of times at various locations identified by magnets in the track.  In conjunction with another microprocessor and controller it could also cause turnouts to switch so that the train could follow a different route.  The only limitation is one’s imagination.  (In the event that your imagination is suffering from a long, cold winter I have some ideas at the end of this article!)


Having spent many years writing lesson plans for my classroom I always start off projects with a set of objectives.



1)      The engine will be able to accelerate and decelerate smoothly, run at a constant speed, stop and sense its location on the track

2)      The engine will operate from batteries

3)      A microprocessor will control the train’s motion

4)      The microprocessor will must use interrupts to detect crossing over a magnet so that no magnet crossings are missed

5)      All motor control will be solid state using an “H-Bridge”

6)      Motor speed control will be by PWM (Pulse Width Modulation)

7)      It will be possible to change some settings without reprogramming

8)      Programs will be easy to create and revise



Battery Operation

I have begun to switch much of my railway over to battery power.  Battery operation simplifies this  particular system by allowing all electronics to be housed in the engine.  It also allows us to ignore problems that arise when entering switchbacks and wye’s and allows us to run multiple engines on the same line.  NiMH batteries are used as they provide the most economical rechargeable power source.  A total of 12 AA cells provide 14.4 volts and should power a small engine for several hours.


Microprocessor Operation

Although most of the objectives for the project could be met by creating a circuit using discreet logic and timer integrated circuits the overall flexibility and design is simplified greatly by the use of a microprocessor.  Changes can be made in seconds with a simple program modification rather than needing to rewire or add components to a circuit. 


The choice of microprocessor is always a challenge.  The most popular small programmable system is the Basic Stamp by Parallax.  Unfortunately the two most common “stamps” do not have interrupt capability.  The most inexpensive unit that supports interrupts costs nearly $80.00.  A new entry into the hobby microprocessor market is the PICAXE from Great Britain .  There are a number of different styles.  The 18X has all of the hardware capabilities that are needed at less than one forth of the cost of the Stamp.



Interrupts are something that we use on our computer every day.  Whenever we use a mouse on a PC we are using interrupts.  An interrupt simply tells the microprocessor that something very important is happening and that it must “interrupt” everything else that it is doing so that it can deal with that special event.  When you move your mouse it is very important that the PC not miss that movement.  An interrupt is generated that stops other things, moves the mouse cursor and then returns to its other obligations.  Our system has one very important event that can’t be missed.  The microprocessor must catch every magnet crossing.  The best way to insure this is with interrupts.  Without interrupts, if the microprocessor is busy resetting the motor speed when a magnet is crossed it is possible that it would miss that event.  Interrupts do a great job of making sure that does not happen.


Motor Control

There are several ways to control the direction and speed of an electric motor.  A double pole / double throw switch (or relay) can be used to change the direction of rotation by switching the + and – terminals providing power to the motor.  Speed can be adjusted by using switches or a rheostat to introduce different resistances into the circuit.  The more the resistance, the slower the motor spins.  Unfortunately the energy that the resistance takes from the motor is dissipated as heat, something that can be difficult to get rid of, to say nothing about being inefficient!


Solid state motor control can be accomplished with a number of different devices that simulate the operation of a double pole double throw switch.  The easiest to use and interface to a microprocessor is called an “H-bridge’ due to its internal arrangement of transistors in an “H” pattern.  A typical “H-bridge” has three control pins.  Two of the pins determine the direction of rotation and the third is used for speed control.  By applying the right sequence of controlling pulses to these pins the motor speed and direction can be set.  Some heat still must be dealt with, but the overall system is much more efficient, something that is especially important when working with battery operated equipment 


Pulse Width Modulation

The objective that identifies PWM for speed control is part of the solid state motor control objective.  When the microprocessor needs to change the speed of the motor it sends a series of pulses, called Pulse Width Modulation, to one of the “H-bridge” pins.  This pin spins the motor at full speed if it sees 5 volts and stops the motor if it sees 0 volts.  A voltage between 0 and 5 volts gives a speed proportional to the voltage.  Microprocessors generally don’t deal well with variable, or analog, voltages.  That is where PWM comes in.  PWM sends a series of pulses of 5 volts to a pin to simulate a variable voltage.  For example, if it sends pulses that are on ½ of the time the pin appears to have 2.5 volts on it.  Sending pulses that are on 25% of the time looks like 1.25 volt and so on. (see graphic)



Changing Settings with ADC

This project has a number of settings, or variables, that change the operation of the engine.  Among them are the top speed setting, the rate of acceleration and the length of time to delay when the engine pauses between direction changes.  While we could reprogram the microprocessor to change any or all of these settings that can be inconvenient when you are in the garden and don’t have a laptop handy!  To make changes, several potentiometers (variable resistors, often called “pots”) have been included in the design.  A potentiometer is a fixed resistor that has a movable wiper that can slide along the fixed resistor to provide a continuously variable resistance between zero ohms and the full value of the fixed resistor.  Our microprocessor has the ability to do Analog to Digital Conversion (ADC).  If we hook one end of the fixed resistor to 5 volts the other to ground and one of the input pins of the microprocessor to the wiper on the pot the microprocessor will see a variable voltage between 0 and 5 volts as the wiper moves across the fixed resistor.  ADC converts this value to a number, usually between 0 and 255.  Once we have that value we can use it to control speed, time delay and other settings.  (see graphic of a section of the schematic showing one potentiometer connected to ground, +5 volts and pin 1 on the Picaxe)



BASIC Programming

The last objective may be the most important.  There are a number of microprocessors that meet the first set of objectives but they use specialized and highly complex programming languages that are not easy to learn and master.  The PICAXE family of microprocessors uses a version of the well known BASIC programming language.  BASIC uses easily understandable commands and is a language that many people have already experienced.  The programming tools to write, debug and send programs to the PICAXE are easy to use, run on nearly any Windows PC and are a free download on the Internet.  Download it from - click on Software and download the full program.


The Circuit

The schematic is a graphical diagram of each of the parts that make up this project.  As you can see there are two ICs (Integrated Circuits), the Picaxe and the LM293D “H-bridge” and a number of other parts that tie the whole thing together.  Spend some time familiarizing yourself with the schematic as it will be a great tool if you are in doubt about how to attach a part to the circuit board or if you are building the circuit on your own project board.



Parts list

a.       Microprocessor - PICAXE 18X

b.      H-bridge - LM293D or sn754410ne

c.       Voltage regulator - 78L05

d.      Resistors – 470 (7), 4.7K (1), 10K (3), 22K (1)

e.       Potentiometers – 47K (2 or 3) – the value is not critical – anything from 10 K to 100 K should work

f.        Capacitors – 10 mfd tantalum (3)

g.       IC Sockets – 16 pin (1) and 18 pin (1)

h.       LEDs – color is not important (3)

i.         Switches – SPST (1) for power, SPST momentary (1) for reset

j.        Reed Switch – small with normally open contacts (1)

k.      Magnets – high strength (2 or more)

l.         DB9 / Female connector (1)

m.     Fuse or circuit breaker (1)

n.       Circuit board (1) – prototype board or custom board

o.      Wire, other connectors as needed for your installation






Prototype Construction

My first prototype for this project was hand wired on a Radio Shack circuit board (276-150).  If you want to go that route the photos, parts list and schematic should be all you need.  I built 4 circuits that way and found that each one took several hours to build and troubleshoot.  Stripping and soldering tiny pieces of wire can be a bit of a challenge. 


Custom Circuit Board

After getting the prototypes working well I came across a company that would make small batches of custom printed circuit boards. (see: ) Their web page boasted free software for designing schematics and the circuit boards.  After a few hours of experimentation with their software I sent off the initial plan for the circuit board.  In three days I had boards in hand.  I found that the construction time was cut by more than half and troubleshooting was almost unnecessary!  Even more important they looked much better, almost professional!  I have a few of these boards on hand and most of the parts.  Please contact me by email if you would like to order any or all of these items.  I also have a few completely wired and tested boards for those who are not able or interested in building this circuit from scratch.


Note that the following assumes you are using the custom circuit board.  If you are wiring your own by hand you should be able to place and wire components similarly.


First gather all of the parts that you will need and heat up your soldering iron.  Make sure the tip of the iron is clean and “tinned” with a light coat of fresh solder.  Check off each section of the construction list as you go.  I have inserted a few test items as each section is completed as well as some test software.  Make sure one section is tested successfully before moving on. 


I also recommend that you use a magnifying glass or jeweler’s eyepiece to visually inspect each solder joint before applying power.  Solder “bridges” between pads on the board are a common source of problems.  It is also important not to get solder onto pads or other areas of the board before you insert components.  If solder fills a hole before you insert a device it can be very difficult to get it in later on.


All of the component locations are not marked on the circuit board due to space issues.  The photos and schematic should provide enough information for placement.  If in doubt double & triple check!  It is much easier to get it right the first time than it is to remove and relocate a component!


Construction Check List


  1. Insert the two sockets into the board.  The sockets go on the side of the board marked TOP.  Note that the small notch at one end of each socket indicates the end with pin 1.  Be sure that each and every pin passes through to the back of the board before soldering.  Once you start soldering the chip in it is very difficult to remove it should you find a pin bent under the socket!

  1. Turn the board over and begin soldering the sockets.  I usually solder just two pins on each socket (diagonal corners) then check to make sure the socket is flat against the board before continuing with the other leads.  DO NOT insert the ICs into the sockets now.



  1. Insert the 78L05 into the board.  See the photo for the placement of this device.  The flat part of the device goes towards the edge of the board.  Once it is soldered in cut off any wire extending from the back as close to the board as possible.


  1. Insert the 10 mfd capacitor in front of the 78L05.  There is a small line on the capacitor that identifies the positive lead.  The positive lead is also the longer of the two.  On the caps I am using the labels goes towards the 78L05.  The positive lead goes in the hole marked with a + sign.  Solder and clip the leads


  1. Insert an LED and 470 ohm (yellow / violet / brown) resistor as in the photo.  Bend the resistor leads carefully over a pencil tip to form them.  The longer lead on the LED goes in the + hole.  There is also a flat side to the LED that goes to the negative side.  Place close to the board and solder.  Note that resistors don’t care about polarity and can go in either way.


  1. If you are soldering power and motor leads directly to the board you can solder a red wire to the + solder pad to the right of the 16 pin socket (see photo) and a black wire to the – solder pad.  The motor leads will go to the pads marked with “M”’s.  If you are using the 4 position terminal block solder it in now.  Note that the ones I have been using can be a tight fit but the pins should go through the holes!

  1. Briefly connect a 9 volt battery to the + and – terminals.  If the LED does not light remove power immediately and recheck your connections.  If it does light use your meter to test for + 5 volts between pins 5 and 14 on the 18 pin socket.  Just put the black test lead on pin 5 and the red lead on pin 14.  The meter should show 5 volts.  You can also test for 5 volts between pin 4 and pin 16 of the 16 pin socket (black on pin 4, red on pin 16)


  1. Locate the 22K (red / red / orange), 10K (black / brown / orange) and 4.7K (yellow / violet / red) resistors.  Each of these components go to the left of the 18 pin socket.  Their locations are marked on the board.  The 10K and 22K resistors must stand up on the board.  Bend the leads as in the photo before inserting in the board.  Solder and clip the leads.



  1. Insert the 3 pin header into the holes next to the 10K resistor you just placed.  This is the connection that will go to the PC for programming.  Solder in place.


  1. Solder the three wires from the 3 pin plug to the DB-9.  On the cable I made the black wire goes to pin 5, the yellow wire to pin 3, and the red wire to pin 2.  If you are using your own materials consult the schematic.  The important thing is that Pin 5 on the DB-9 goes to the right connector pin that goes to pin 5 on the Picaxe, DB-9 pin 3 goes through the 22K resistor to Pin 3 on the Picaxe and DB-9 pin 2 goes to Picaxe Pin 2.  Make sure that you always insert the cable so that the ground wire (black wire that goes to pin 5 on the DB-9) goes towards the potentiometers.  In the photo it would be towards the right.


  1. If you haven’t already downloaded and installed the software from the Picaxe site do it now as we will be testing the microprocessor in the next step.   


  1. Connect the 9 volt battery again and double check that you have 5 volts between pins 5 and 14 on the 18 pin socket.  We will be inserting the Picaxe microprocessor and don’t want to “smoke” it!


  1. Remove power from the circuit and insert the 18 pin Picaxe.  Note that pin 1 is at the end of the chip that has a crescent shaped notch in it.  It is also identified with a small dimple in the top of the chip.  It is sometimes necessary to form the pins before inserting the chip in the socket.  If necessary, gently bend them to better fit the socket.  Be careful when inserting the chip as it is easy to bend one or more pins if you force it.


  1. Briefly restore power to the circuit.  Make sure the LED lights before continuing.  If it does not remove the Picaxe and check your wiring.


  1. Connect the DB-9 to the serial port on your PC.  Connect the other end to the circuit board.  Make sure the black wire goes to the right as you look at the side of the board.  


  1. Run the Picaxe Programming Editor.  You will be asked what mode you are using.  Select 18x.  Click on COM and select the com port you are using.  If these questions do not come up automatically just click on View and Options.



  1. Type this simple program into the editor:



for b1 = 0 to 255

debug b1

next b1

goto start:


Press the F4 function key to check your syntax.  Correct any errors in the program.

Press the F5 function key to download the program to the Picaxe.

You should see a download screen and a progress indicator as the program loads.  Once it is done a Debug windows will come up and show the value of B1 (a variable in the Picaxe) changing from 0 to 255 over and over.

  1. If the program does not download to the Picaxe make sure your com port is not being used by another program (a palm pilot, for example, will frequently hang onto a com port even when disconnected)  Also check wiring and examine the circuit board to make sure there are no solder bridges between pads.  Also check that the programming cable is plugged into the board correctly.


  1. Locate three 470 ohm (yellow / violet / brown) and one 10K (black / brown / orange) resistors.  Shape the leads so that all can be inserted standing up.  See the photo for placement.  Each of these components is inserted to the right of the Picaxe (next to pins 10-18 on the Picaxe).  There are holes for many more resistors than we are using.  These may be added later on when more sophisticated things are done with the system.  Be careful that you put the components in the right holes!  Note that the 470 ohm resistors all go next to the Picaxe and that the 10K resistor is placed to the side of the 470 that goes to pin 15 on the Picaxe.


  1. If you are planning on soldering LEDs and the reed switch directly to the board you can skip this step.  The header I am using is 2 pins wide x 8 pins long.  I removed two pins that are not used so that the header has 2 x 3 pins, a space and 2 x 4 pins.  The 3 pin section goes next to the pins marked sw 6, 7 and 8.  The 4 pin section next to led 7, 6, 5 and 4.  Place and solder the header.


  1. Place the last two 10 mfd capacitors as in the photos.  Remember that the longer lead (the one identified with a line on the cap) goes into the + hole and the other in the – hole.  Solder and clip off the leads.  



  1. Connect two LEDs to the header next to “led 7” and “led 6” – the longer (+) lead on the LED goes to the part of the header closest to the Picaxe and the shorter (- end with a notch on the LED) goes to the part on the edge of the board.  Solder wire to each end of the reed switch and connect it to the two pins next to “sw 6” on the header. 


  1. Apply power and type the following program into a new editor window to test the LEDs and reed switch:


‘led test program


high 7:low 6

if pin6 =1 then reed:

pause 300

low 7:high 6

if pin6 =1 then reed:

pause 300

goto start:



high 6

high 7

pause 5000

goto start:


The two LEDs should blink on / off.  When a magnet comes close to the reed switch both LEDs should stay on for 5 seconds.


  1. We now need to make a decision about where to locate the potentiometers.  They can either go on the board or somewhere external to the board (under the engine, for example). 
    1. On board pots -  the two 47K pots go over the two large holes between the 78L05 and the PC connector – the leads for the pots are too large to go through the holes but fit nicely over them.  Bend the leads slightly (see photo) and tin the ends with a bit of solder.  Place the pots over the pins on the board an apply heat with the iron.  Repeat with the 2nd pot.  Note that the pots I used can be adjusted from both sides of the pot.  That is why there is a large hole under each pot.  It gives you the capability of adjusting the pot from a strategically placed pair of holes under the board. 


    1. Off board pots – some or all of the pots can be placed off the board.  If you want to place them elsewhere all you need to do is run 4 wires (one for +5 volts, one for ground and one each for the connections to pins 1 and 18 on the Picaxe.)  Wire one end of the fixed part of each pot to + 5 the other end of the fixed part to ground.  Run the center (wiper) lead to the board.  The lead for “speed” goes to the pad above and a bit to the right of the “d” in the word “speed” and the lead for delay goes to the pad above and to the right of the “y” in “delay”
  1. Open a new editor window and type the following program into the Program Editor (or cut / paste it in) to test the three pots.  When run you should be able to change the value of B1 and B2 between 0 and 255 by adjusting the pots with a small screwdriver

‘pot test program


readadc 0, b1

readadc 1, b2

debug b1, b2

goto start:


If any of the variables do not change make sure that the potentiometer associated with that variable is properly connected to +5 volts on one side and ground on the other.  For example, if B2 stays at 255 it is likely that one end of the pot that  goes to Picaxe pin 1 is properly connected to +5 volts but the other is not connected (or has a bad solder joint) to ground. 


  1. Make sure power has been disconnected and put the “H-bridge” chip in the 16 pin socket.  Remember that the notch is next to pin 1.  This chip does NOT have a dimple next to pin 1.  Note that both the Picaxe and “H-bridge” face in the same direction.


  1. Apply power and confirm that the LED lights as before.  Disconnect the power and connect a small DC hobby motor to the two pads labeled “M”.  Since we are still working with a 9 volt battery there will not be sufficient power to turn a large engine’s motor.  The advantage of doing things this way is to protect the chips from being damaged should the wiring be incorrect.  A 9 volt battery can’t deliver any where near the current of a set of NiMH or NiCad cells.


  1.  Type or cut & paste the following program into a new editor window to test the motor.


‘motor test program

high 1

low 2


for w1= 200 to 1000 step 40

pwmout 3, 249, w1

pause 400

next w1

pause 5000


for w1= 1000 to 200 step -40

pwmout 3, 249, w1

pause 400

next w1

pause 5000

toggle 1

toggle 2

goto start:


      The motor should start slowly, speed up, run for a few seconds, slow, stop, reverse and repeat.  If you note a tone coming from the motor that is due to the PWM pulses being used to activate the “H-bridge”


  1.  That’s it for construction – congratulations!



Software – how it works


a.       The first line is a comment (starts with an apostrophe)

b.      The second line is a label “start:”that is used as an address that the program can return to when needed.

c.       “high 7 and low 6”turn the LED on output pin 7 on and the one on output pin 6 off

d.      “if pin6 = 1 then reed:”does a test – if input pin6, which goes to the reed switch, is connected to 5 volts then it jumps to the label “reed”

e.       “pause 300”waits for 300/1000 seconds

f.        The next three lines switch the LEDS that are lit, check for the button being pushed and pause again.

g.       “goto start:”starts over

h.       “reed:”is another label – the program goes here when the switch is on.  The lines that follow turn both LEDs on, pause for 5 seconds and return to “start:”


a.       The first two program lines,  high 1 and low 2, set the LM293D motor control chip to turn in one direction.  If both were high or both low the motor would not run

b.      After the “start:”label is a for/next loop.  It tells the computer to count from 200 to 1000 by 40’s and to store the current number in a storage place, or variable, called W1

c.       The magic happens in the next line, “pwmout 3, 249, w1”- this line tells the computer to send a variable voltage to the enable pin on the LM293D.  You may recall that the enable pin on this device turns it on and off.  It interprets 5 volts as on and 0 volts as off.  The pwmout command sends a series of pulses that can simulate voltages between 0 and 5 volts.  The higher the voltage it sends with this command the faster the motor spins.

d.      After the pulse is sent the program pauses for 400/1000 seconds

e.       “next w1”tells the program to continue counting with the for/next command.

f.        Once the computer counts up to 1000 it pauses for 5 seconds and counts back down with the “for w1 = 1000 to 200 step -40”command.

g.       After another 5 second pause the direction pins are toggled, that is the one that is on goes off and the one off goes on and the program continues


a.       This simple program uses the command “readadc”to read a voltage between 0 and 5 volts on a pin and report that voltage as a number between 0 and 255.

b.      “readadc 1, b0”reads the voltage on pin 1 and places the result in the variable b0 – the second readads reads pin 2 into b1

c.       “debug b0, b1”has the program report the value of the variables to a box on the programming screen .  This is an easy way to see what is happening with a program.


Auto reverse software

The objectives of this program are

  1. Train accelerates smoothly to some preset speed
  2. Speed is maintained until the train crosses a magnet on the track
  3. The programs uses interrupts to assure sensing a magnet even at high speed
  4. Train decelerates smoothly and stops for a predetermined time
  5. Train reverses, accelerates and continues on its way until another magnet is encountered where it reverses again



Since this is the main program that is used for the engine controller it is much more detailed containing comments on most lines and using word labels to represent variables.  This makes the program much more understandable.  The “symbol”command that is used more than a dozen times at the top of the program substitutes a word for a pin or variable.  Besides making a program more understandable, it also allows you to easily modify a number that occurs at a number of places in a program by simply changing its value in the symbol area.

The rather cryptic command “setint i_rupt, i_rupt” sets up a very powerful capability of the program called an interrupt.  The interrupt forces the microprocessor to continually look at one or more of the input pins and to immediately react if the condition that is being looked for is met.  The command “setint i_rput, i_rupt” (i_rupt =%01000000) tells the computer to look at input pin 6 and to go to the interrupt part of the program if that pin becomes high.  This happens when the reed switch is closed by a magnet on the track. 

The section of the program after the label “interrupt” is executed whenever the engine passes over a magnet. 

The other special feature of the program is the variable “magnetFlag” that has the microprocessor skip over the magnet that told it to reverse.  If this is not used the engine will go back and forth over the same magnet over and over again!  This was discovered the first time I ran the prototype on a track with a magnet.  The engine passed the magnet, slowed, paused and reversed and promptly repeated the sequence as soon as it passed over the magnet again!  I had a wonderful oscillating railroad engine!  Cute, but not of much use until the “magnetFlag” was added.


'd. bodnar 4-13-04 -  18x chip rev 9a

' third pot added

'speeds up motor and slows / reverses on reed switch

'magnetFlag (bit0) is flag to skip 2nd pass over same magnet on reverse

symbol    ver           =      9             'version to flash at start

'symbol   howlong       =      100           'delay in accelerate / decelerate loops

symbol    HBridgeD1     =      1             'output - H-Bridge chip direction pin

symbol    HBridgeD2     =      2             'output - other H-Bridge chip direction pin

symbol    pulse         =      3             'output - H-Bridge pin for pwm

symbol    LED           =      6             'output - LED on pin 6

symbol    LED2          =      7             'output - LED on pin 7

symbol    magnetFlag    =      bit0          'used to skip over first magnet on reverse

symbol    doitflag      =      bit3          'set if ready to reverse

symbol    tone          =      b1

symbol    flashLED      =      b2            'variable for for/next flash

symbol    stoptime      =      b3            ' long to pause

symbol    toppot        =      b4            'read pot for top speed

symbol    stoppot              =      b5            'read pot for pause time

symbol    accloop              =      w3            'variable for accelerate for/next

symbol    top           =      w4            'top of accelerate for/next

symbol    period        =      124           'constant for PWM period

symbol    lowend        =      300           'constant for small end of for/next loop

symbol    stp           =      4             'constant for step in for/next loop

symbol    i_rupt        =      %01000000     'binary for pin 6 interrupt

symbol    temp          =      b10           'temporary variable

symbol    accpot        =      b11           'read pot for acceleration /decel rate

'the next three lines flash major version number on LEDs at startup

high LED:low LED2

for temp=1 to ver:toggle led:toggle led2:pause 200:toggle led:toggle led2:pause 200:next temp

pause 1000


setint i_rupt, i_rupt                        'Use interrupts to check for pin 6 being high

high HBridgeD1:low HBridgeD2:magnetFlag=0           'initialize, forward -clear skip magnet flag



gosub get_toppot:                                  'read setting from top speed potentiometer

for accloop=lowend to top step stp           'accelerate loop start

   pwmout pulse,period, accloop                    'send pwm pulses

   toggle led:toggle led2:                  'blink LEDs

   pause accpot                             'pause sets acceleration rate

   toggle led:toggle led2:                  'blink LEDs

   pause accpot                             'pause sets acceleration rate

   if doitflag=1 then slow_reverse:         'doitflag set by interrupt detecting magnet

next accloop                                 'back to start of for/next loop


maintain_speed:                              'keep steady speed routine

   high led                                 'LED on

   gosub get_toppot:                        'read setting from top speed potentiometer

   pwmout pulse,period, top                 'send pwm pulses

   low led                                         'LED off

   if doitflag=1 then slow_reverse:         'doitflag set by interrupt detecting magnet

   pause 50                                 'brief pause

goto maintain_speed:                         'go to start of maintain_speed loop until interrupt


slow_reverse:                                'decelerate reverse routine

high LED:low LED2                                  'toggle LEDs

gosub get_toppot:                                  'read setting from top speed potentiometer

for accloop=top to lowend step -stp          'decelerate loop start

   high LED2                                'turn off LED

   pwmout pulse,period,accloop              'send pwm pulse

   toggle led:toggle led2:                  'provides a pre-scale of 1:4 use $06 for 1:16

   pause accpot                             'pause

   low LED2                                 'turn on LED

next accloop                                 'back to start of acceleration loop

toggle HBridgeD1:toggle HBridgeD2                   'reverse direction

magnetFlag=1:high LED                        'set magnet flag & light LED

pwmout pulse, period,0                       'send pwm for stop!

readadc 1,stoptime                                  'get pot reading for stop time

for flashLED=1 to stoptime                          'pause flashing LED routine

   high LED                                 'light LED

   temp=stoptime-flashLED                          'use temp variable for computation for next step

   pause temp                               'wait

   low LED                                         'off LED

   pause flashLED                                  'wait

next flashLED                                'back to start of flash for/next loop

doitflag=0                                   'reinitialize flag

goto speedup:                                'start over again!


interrupt:                                   'jumps here if magnet detected

  if magnetFlag=0 then doit:                 'if no flag do decelerate & reverse

  if magnetFlag=1 then makemagnetFlag_0:            'if flag was set reset it (hit magnet on way back)

  doit:                                      'label of place to jump to

  doitflag=1:low LED2                        'set flag to reverse

  goto back1:                                'skip over next part

  makemagnetFlag_0:                          'clear flag routine

  high LED2:low LED                          'light LED

  magnetFlag=0                               'clear flag

  pause 800                                        'wait 8/10 sec to make sure we don't detect same magnet again

  doitflag=0                                 'clear flag

  back1:                                     'label of place to jump to

  setint i_rupt, i_rupt                      'reset interrupt for next magnet detection

return                                       'back to where we were when magnet detected


get_toppot:                                        'start of read pot subroutine

  readadc 2,toppot                         'get pot value

   top=toppot * 4                                  'scale to max of 1023

   readadc 0, accpot                        'get accelerate / decelerate pot

return                                       'return to place were gosub was called and continue












Before installing the board you need a direct connection to the engine’s motor.   Locate these two wires and disconnect them from the other wiring within the engine.  Connect them to the two contacts on the board labeled “M”.  If you plan on using track power for other trains at the same time as the battery operated engine make sure you have disconnected any track power pickups in the engine. 


Connect your battery pack to the power connections on the board through a fuse or circuit breaker and an on/off switch. 


The reed switch should be glued to the bottom of the engine so that it will pass within a distance of ¼” or less of the track mounted magnet (remember that magnetic field strength decreases rapidly as the distance increases.)   I have found that placing the reed switch inside a channel in a piece of wood protects its glass package and gives a larger gluing surface.   When gluing the reed switch make sure that the flat sides of the reeds are down as this is the best position for detecting a magnetic field.


If you need to bend the leads on the reed switch, as I have in the prototype, make sure you grip the wire coming from the glass with a pair of pliers and bend the wire beyond the pliers.  If you try to bend the wire by holding the glass in your hand you are sure to break the glass of the reed switch.




Magnet Placement

I placed magnets by gluing one small cylindrical magnet to a piece of Plexiglas that is just long enough to be held down by adjoining ties.  I put the Plexiglas under the track and add additional ¼” magnets to make a stack that comes within ¼” of the reed switch.  This arrangement works well!




1.         Killing electrical noise from motors

Since we are using a single power supply (one set of batteries) to power both the motor and the microprocessor it is possible that some electrical interference, generated by sparks within the motor, will get back to the microprocessor.  Capacitors are the best way to filter out this noise.  The 10 mfd tantalum capacitors that I have used have been sufficient to suppress noise in the 3 engines I have tested.  If you find your system operating intermittently or randomly resetting you may need to add more suppression.  Adding 220 pf capacitors between each terminal on the motor and its case can help a great deal.   (see the photo)


2.         Setting PWMOUT variables for different motors

The PWMOUT command uses two arguments, period and duty cycle.  In the programs I have used 124 as the value for the period and changed the duty cycle with the variable in the for/next loop.  You may need to experiment a bit with the period value to suit your engine’s motor.  To simplify this process you can try this program.  It changes the period and duty cycle based on the position of the speed and delay pots and uses the debug window to display their values.  Just adjust the two pots to get a good speed range and smooth running motor.  Once you find a value for “period”, b2, that you like change the “symbol period” setting in the program accordingly.


'MOTOR test #2  d. bodnar 04-08-04

'used to adjust period and duty cycles to minimize "noise" coming from motor

'124 works well as period

symbol L293D1        =      1             'output - L293D direction pin

symbol        L293D2        =      2             'output - other L293D direction pin

symbol        pulse         =      3             'output - pin for pwm

symbol        toppot        =      b0            'read pot for top speed

symbol period        =      b2            'variable for period from adc

symbol        duty_cycles   =      w3            'top of accelerate for/next

symbol temporary     =      w4


high l293d1:low l293d2                          'spin in one direction


gosub get_toppot:                        'read setting from top speed potentiometer

pwmout pulse,period, duty_cycles         'send pwm pulses

goto start:



readadc 2,toppot                         'get pot value for max speed

duty_cycles=toppot*4                     'scale to max of 1023

readadc 1, period                        'get period value from pot


if duty_cycles > temporary then fixit:

debug toppot                             'show value in debug window

debug period                             'show value in debug window

debug duty_cycles

debug b2









Ideas for Enhancements

Below are some ideas for enhancements to the system.  The Picaxe is capable of much more than just reversing an engine.  Let me know if any of these ideas are of interest to you or pass along ideas of your own.  They are all possible with minor modifications to the hardware and/or software.


  1. Add a 3rd potentiometer for acceleration rate - The original board only had places for two pots.  Adding an additional pot allows you to modify the acceleration rate without reprogramming.  Alternatively you could set the top speed in the program and use the top speed pot to change acceleration rate.


  1. Use an unused output pin to turn something on or off on the engine or train – By adding a transistor switch you can easily control devices like a smoke generator or bright light on an engine.  An appropriate transistor switch can control a very high current load. 


  1. Add a 2nd reed switch – There are holes and solder pads on the board and circuitry on the schematic to support a 2nd reed switch.  This could be placed under the engine, opposite the existing reed switch, and used to activate some other event, such as creating a sound, turning lights on/off or activating the smoke generator.


  1. Add a buzzer to sound when magnets are encountered – While developing this project I found it useful to have an auditory cue that a reed switch had passed a magnet.  There are solder pads on the bottom right of the board labeled “buz” for this purpose.  You can insert a piezo buzzer (Radio Shack # 273-074) in these holes.  Make sure you observe polarity by placing the + lead in the hole closest to the “z” in “buz” and the – lead in the other hole before soldering.  Each time the reed switch passes a magnet a sound will be heard.  Note that this happens regardless of what the program is doing.


  1. Add additional LEDs – there is space to add two additional LEDs to the board by the header pins labeled LED 5 And LED 4 – additional 470 ohm resistors will need to be added to activate these LEDS.  Once more LEDs are available additional commands can be added to the program to give more detailed feedback on what is going on in the program.


  1. Use Random settings for pauses – the Picaxe has a random number generation capability.  This could be used to have the engine stop for a random time (say between 10 and 200 seconds) rather than always stopping for the same time.   Similarly a random top speed could be used rather than always having the engine cruise at the same speed.  The random function could be used to skip over some magnets some of the time, but not always.  Something to keep your guests guessing!


  1. Add a simple sound board to an output pin - You could easily connect an unused output pin on the Picaxe to a separate sound generating board.  A recent article in LSOL (Using Pre-made Electronics, Apr 14, 2004 ) shows how to make such a device. 


  1. Create a multiple magnet route plan – Rather than just using magnets to reverse your engine the program could be modified to slow and stop at any number of stations or buildings along your track.  Stops could be for random times (see above) and some could be set as places to reverse.


  1. Check for derailment – if your engine has at least two power pickups on one side of the engine you could wire them to an unused input pin on the Picaxe and test periodically for a circuit between them.  If the circuit is broken you could assume a derailment and shut down the motor.  Not a bad way to run a railroad!


  1. Getting rid of heat  - Adding a heat sink to the “H-bridge” will allow it to dissipate much of the heat that is generated as it approaches its 2 + amp capacity.  The simplest heat sink is just a piece of copper or brass soldered to pins 4, 5, 12 & 13, the ground pins on the chip.  In the photo you can see a bit of the white heat sink grease between the copper and the chip that helps to transfer heat.  You can also add a small CPU fan from an old PC.  Align it so that it blows directly on the chip & heat sink and it will operate all day at its rated capacity.   I used such a fan on a computer controlled Christmas Trolley that ran in front of my house throughout the month of December and never had a problem with heat.



  1. More Power!  - If you are into “More Power”, like Tim Allen on Home Improvement, here is something that you can do to operate bigger motors on bigger locomotives.   You can stack a second “H-bridge” chip, piggy back style, on top of your first chip to double the current capacity.  Just align one atop the other and carefully solder the pins of the top chip to the bottom one, being careful to align the chips pin 1 to pin 1, pin 2 to pin 2 and so on. (see photo)  Make sure you also use a heat sink and fan if the motor draws anything close to the 4 + amp capacity of this setup.


  1. Electromagnets rather than fixed on the track – if you replace one or more of the track mounted permanent magnets with a small electromagnet you could have a track-side event signal the train to stop or reverse.  For example, you could connect the electromagnet to a semaphore on a station to signal the train to stop for passengers.  If it is up the magnet is energized and the train stops, if down the train keeps on going.


Now for your ideas!


I hope that this project gives you enough information to consider building your own, custom train control system.  The “store bought” units are great but there is something about doing it yourself!  Good luck and let me know if I can help.