PIC/MOSFET PWM Model Train Controller

Having been unable to resist buying some old Hornby OO Gauge bits from the second hand cabinet in a model shop, justification came from the educational value it would offer my son if I could make a speed controller, perhaps adding a sensor or two – the essence of industrial control and feedback mechanisms. Being three and a half, he just wanted to make the train fly off the track, but at least he enjoyed it.

This is a project to create a model train speed controller using the Pulse Width Modulation (PWM) output of a PIC16F690 microcontroller, to drive a MOSFET that ultimately controls the voltage on the tracks. The train will automatically switch into reverse when the control is turned anti-clockwise through the zero point.

The input to control the voltage is a potentiometer to the PIC’s Analogue to Digital Converter (ADC), and two LEDs (forward and backward) give feedback on the direction of travel. The polarity is switched using a double-pole double-throw (DPDT) relay.

The software on the PIC reads the ADC value and converts this to either a positive or negative voltage on the rails, depending on the position of the pot, with the mid-point giving zero volts (train stopped). A dead-zone is included around the mid-point to make it easier to stop the train (i.e. without it immediately heading off in the opposite direction).

The Schematic

The following schematic was drawn in Cadsoft Eagle, and while I routed a board, I’ve decided not to make it into a PCB yet, because I still want to add sensors and perhaps an LCD display with buttons to allow programming of sequences. So it’s still on the breadboard for now.

Model train controller using a PIC for PWM motor control.

The MOSFET is an IRF540A (Maplin code N10AH). The relay is an RSB-5-S (Maplin code N18AW). Equivalent parts could easily be chosen, but bear in mind that the Rds of the MOSFET must be low, and the Vgs should be logic-level (the lower the better, the IRF540A is 4V maximum, as I recall).

I added a heat-sink to the 7805 voltage regulator, since the input voltage is relatively high. I don’t think that the power requirement on the 5V rail is ever likely to take the device to dangerous temperatures, but I was concerned for curious little fingers poking around, and so erred on the side of caution.

The Code

The C code below compiles on the Hi-Tech C compiler, but it’s simple enough that it should easily convert to other variants.

The PWM is running at around 100Hz, and getting this low requires running the PIC’s internal oscillator no higher than 1MHz. Pulsing at low frequencies reduces motor noise and helps keep the MOSFET cool.

The DEADBAND and DIVISOR defines are used to implement the dead-zone and also to limit the output voltage (i.e. limit the train speed) depending on your power-supply (mine is 15V, and I don’t want to run the train at such a high voltage).

The dead-band has two states – completely off, and direction LED active – this means that an LED will come on in the dead-band prior to crossing into a voltage state.

The code for the dead-band is about to be cleaned up, so check back later if you want an update – it’s not as clear as it should be because it was ‘tinkered’ with while testing the intuitiveness of the controller. It should be more readable after the clean-up!

The Photos

The case was just an old ABS enclosure I had been given – it has space for an LCD display so I’m duty bound to add one eventually (whether it needs one or not). The control knob is the lid from a kid’s smoothie pouch, fixed onto the pot with polymorph (low melting-point plastic).

The train controller is housed in an ABS box with a smoothie lid for a control knob.

The circuit is still on a breadboard. The power connector is on the left hand side, fixed with hot-melt glue. I used an old laptop charger that can deliver 15V and 2,5A. In practice, the train runs on a few hundred milliamps, but start-up current can approach 1A, I believe.

Hot melt glue is amazing stuff. Even more useful than BluTac.

Future Bits

I’ll post the hex for the controller firmware and some oscilloscope shots of the PWM pulses – they’re pretty smooth, no nasty spikes.

There will probably be some sensors added to detect when a train either passes a point or when it’s close to the buffers in a siding (optical break or proximity sensor).

Add I2C Slave or UART code to allow a computer such as a Raspberry Pi to override the pot and take control of the train.

References

The following sites were either useful while developing this circuit, or helpful to me afterwards when I wanted to check that my design wasn’t going to burn out train motors.

Review of Train Controllers – comprehensive review of existing train controllers by Jonathan Scott. The oscilloscope traces he’s published helped me decide the standard to aim for (and the problems to avoid).

Mosfets & Mosfet Drivers – a clear and well written article on MOSFET characteristics, in particular how they behave during switching transitions.

PIC16F690 – datasheet for the PIC microcontroller used in this project. This is quite a versatile chip with a good range of peripherals supported.

IRF540A MOSFET – datasheet for the MOSFET I chose. It switches with 4V and has a low Rds, so at the switching speeds of the controller, it doesn’t generate a lot of heat (it remains only warm to touch).

A Computer Driven Train Controller – some detailed information on driving model train motors specifically, including how characteristics of the controller circuitry affects the ideal motion of the train.

PWM DC Motor Controller – if you’re looking for general motor control, rather than model train control, then this would be a better option. In any case, it’s quite a comprehensive article and is well worth a read.

PIC PWM Calculator – a utility to calculate the register values required for a specific pulse frequency, given the microcontroller clock speed and the required frequency.

Post navigation

5 thoughts on “PIC/MOSFET PWM Model Train Controller”

Thank you for your work I am playing with it I am going to set it up to use a pic kit 2 low pin count board I tried the code but it had errors godone vs go_ done what version of hi tech compiler do u have and where in the code does it point the pwm to pin 5
I am sorry I am new to pics and to hitech

Hi, I’m using the PIC10/12/16 compiler V9.70. I did a search for GO_DONE, and it might be that the headers have changed in a more recent version. You could change the code to suit your version or #define _LEGACY_HEADERS (according to a post on the net).

Looking at the datasheet for the PIC16F690, pin 5 has P1A. Register bits CCP1CON<7:6> define which pins are modulated in PWM mode. These bits are configured with ’00’ in the code, which means P1A is the modulated pin. (See definition of CCP1CON in chapter 11).

i am thinking of trying it at a higher freq for the pwm like 3k and put a low pass filter and a cap to turn it into dc to drive the motor i am looking into it more its just what i have pictured in my head what do u think