Greetings.

This post is going to be the first in a multi-part post on adding custom lighting to some model train coaches.

First some background. I am currently setting up an H0 scale layout modeled on South Africa. One of the reasons for this is that I have a few of my old Lima Trans Karoo coaches from when I was young. As they are the junior version they are pretty sparse. No interiors, no glass, very basic indeed.

I bought some extra, including a baggage wagon that I had never personally owned, and wanted to make them a little better. I added some 3D interiors, which I will do a post on later, people, “glass”, and finally some lighting. Being that these units have plastic wheels, it would be impossible to run pickups from the rails for power, and I didnt want to go through the pain and cost of finding metal ones that would work.

I wanted a system that would light the moment the train starts, but would continue to burn for a short while after the train stops so that they would stay lit in stations etc. Clearly some sort of triggered timer circuit was in order, but I also wanted to be able to add customization after the fact if I could. The obvious choice was a cheap MCU, and as I have been playing with the Texas Instruments MSP430’s, it was an easy choice.

The next part was to figure out how to trigger once moving. After a couple of days on this, I settled on using a kind of vibration sensor as this would allow me to run a setup clear of track voltage. This could be a self contained system that would require battery changes every so often. For vibration sensors, I decided to use non mercury tilt switches because most of them use a little metal ball in a channel that shorts out 2 or more pins depending on their tilt. If I set the angles correctly, the slightest movement in one direction would set the ball (through inertia) onto or off their pins and so create a trigger effect.

Now I could start working on code for the MCU. It must be said here that, while I am aware that button or trigger events should be written as an interrupt and not polled in the MCU world, what I found was that when the system runs the LED’s, it draws more power in a short period of time than is saved by interrupting. It was simple to get the code to run the way I wanted in a poll situation and meant I could add as many triggers as I wanted without too much additional code. In “standby” mode, the MCU is drawing 0.47 ma anyway. On a set of 900 mah AAA cells, I would get 79 days in full standby. Interrupt code gave me no better than 0.37 ma and would result in full standby of 100 days. The figures make no difference when running with LED’s on as the draw is 2.7 ma regardless of interrupt usage.

With that out of the way, here is the code, currently running on an MSP430G2553.

Code was done in code composer studio. Test areas have been left in and commented. I have added comments inline for clarity, and will supply the code in a file attached at the end.

#include <msp430.h>

Setup the variables

//volatile unsigned int mvg; // For Test
volatile unsigned int cartrg;
volatile unsigned int offcnt;
volatile unsigned int offtrg;
volatile unsigned int stillon;

Rough estimation of time

//Static assignments
unsigned int seconds = 60;
unsigned int secsplit = 25713;

/*
* main.c
*/
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

// Set P1.2 for LED output
// Set P1.4 for vibration sensor1
// Set P1.5 for vibration sensor2

// Set P1.6 – LED1 for test mode – moving signal
// Set P1.0 – LED2 for test mode – not moving signal

//P1DIR |= (BIT0 | BIT6 | BIT2); // Set out at P1.0 1.6 1.2 – For Test

Using P1.2 as the LED pin. All LED’s that need to be light are powered from here. I currently use 4 LED’s and they do not overtax the amp rating of the pin.
P1DIR |= BIT2;
//P1OUT &= ~BIT6; // Switch LED at P1.6 off – For Test
P1OUT &= ~BIT2; // Switch LED at P1.2 off

Set the resistor networks at P1.4 and P1.5 on. Some of this code is useless as it is for interrupts, but it works as is so well leave it.

P1REN |= BIT4;
P1OUT |= BIT4;
P1IES |= BIT4;

P1REN |= BIT5;
P1OUT |= BIT5;
P1IES |= BIT5;

Set P1.3 P1.4 P1.5 as inputs for the vibration sensors. I kept P1.3 in as it allows us to use the dev boards button as a trigger as well.

P1IN |= (BIT3 | BIT4 | BIT5); // Set in direction at P1.3 1.4 1.5
//mvg = 0; // Set moving off – For Test
cartrg = 0;

for (;;)
{

// Main cycle

Here I poll the input for P1.4 and P1.5

if ((P1IN & BIT4) | (P1IN & BIT5))
{

If either (the | is or) triggers off (circuit open) – thats the reason we use pullup and a resistor network to hold the line high.

//mvg = 1; // For Test

This is a flag for the LED test later. In this case, cartrg is 1 which means turn on LED’s

cartrg = 1;

These reset the offtrg and offcnt so that the counter never gets above the turn off value. In other words, when the ports trigger, they reset the 1 minute counter, and the counter is always working to turn off the LED’s

offtrg = 0;
offcnt = 0;

}
else {

//mvg = 0; // For Test

Here the flag is 0 and so tells the LED test to begin the count down to turn off the LED’s
cartrg = 0;

}

// For Test
//if (mvg == 1) // Is movement detected
//{
//P1OUT |= BIT6; // P1.6 – Test signal green on
//P1OUT &= ~BIT0; // P1.0 – Test signal red off
//cartrg = 1;
//}
//else {
//P1OUT |= BIT0; // P1.0 – Test signal red on
//P1OUT &= ~BIT6; // P1.6 – Test signal green off
//cartrg = 0;
//}

If the flag is set

if (cartrg == 1 )
{

and the LED’s are off

if (stillon == 0)
{

Switch them on

P1OUT |= BIT2; // Switch P1.2 – main lights on
stillon = 1;

}

}
else {

If they are on
if (stillon == 1)
{

increment counter

offcnt ++;
if (offcnt >= secsplit) // count the number of seconds

Count up the seconds

offcnt = 0;
offtrg++;
if (offtrg >= seconds)

if the offtrg is larger than the amount of seconds, then turn off the lights

offtrg=0;
stillon = 0;
P1OUT &= ~BIT2; // Switch P1.2 – main lights off

 

As promised, here is the file: Lima-Light-Timer.