Notifications
Clear all

Model Railway Signal Lights

32 Posts
10 Users
5 Likes
10.6 K Views
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

Hi I am using this sketch to control up to 6 sets of signal lights on a model Railway and as my program skills are almost none, but I used this sketch i found on another forum and extendedto use 6 pushbuttons to control 6 sections, what I would like to happen is in each void loops is to add an IR sensor so the light will stay on Green till the sensor is triggered were at the moment it is just a 5 second delay so after the Green LED lights it will go back to RED, how can I put a wait command without stopping the Arduino so the other pushbuttons will still function..the signal is a RED YELLOW GREEN plus 2 sets of WHITE lights for direction LEFT or RIGHT...

Also as I am a relative novice with Arduino sketches and I am sure there is another way for this sketch but it works for me.

I would be very grateful for any help.

I will only include part of the sketch as it is repeated 6 times in 6 void loops..

Regards John

void loop() {

buttonState1 = digitalRead(pushButton1); //All button Press to activate
buttonState2 = digitalRead(pushButton2);
buttonState3 = digitalRead(pushButton3);
buttonState4 = digitalRead(pushButton4);
buttonState5 = digitalRead(pushButton5);
buttonState3 = digitalRead(pushButton6);
buttonState4 = digitalRead(pushButton7);
buttonState5 = digitalRead(pushButton8);

if (buttonState1 == HIGH) {
routeUpplatform3left(); // All Trains Up Via Platform 3 to Preston
}

if (buttonState6 == HIGH) {
routeUpplatform3right(); // All Trains Up Via Platform 3 to Blackburn
}

if (buttonState2 == HIGH){
routeUpmainleft(); // All Trains Up Via Main Line to Preston
}
if (buttonState7 == HIGH){
routeUpmainright(); // All Trains Up Via Main Line to Blackburn
}

if (buttonState3 == HIGH) {
routeDownmain(); // All Trains Down on Main Line to Manchester
}

if (buttonState4 == HIGH) {
routeDownplatform1or2left(); // All Trains Down via Platforms 1 or 2 to Manchester or Terminate
}
if (buttonState8 == HIGH) {
routeDownplatform1or2right(); // All Trains Down via Platforms 1 or 2 to Manchester or Terminate
}

//if (buttonState5 == HIGH) {
//routeUpplatform1(); // All Trains Up Via Platform 1 to Blackburn or Preston ( But not used at moment)
// }

}

void routeUpplatform3left() { // All Trains Up Via Platform 3 to Preston

digitalWrite(upplatform3RedLed, LOW);
digitalWrite(upplatform3YellowLed, HIGH);
digitalWrite(upplatform3GreenLed, LOW);
digitalWrite(upplatform3WhiteLed1, HIGH);
digitalWrite(upplatform3WhiteLed2, HIGH);
digitalWrite(upplatform3WhiteLed3, LOW);

delay(mainLedDelay);

digitalWrite(upplatform3RedLed, LOW);
digitalWrite(upplatform3YellowLed, LOW);
digitalWrite(upplatform3GreenLed, HIGH);
digitalWrite(upplatform3WhiteLed1, HIGH);
digitalWrite(upplatform3WhiteLed2, HIGH);
digitalWrite(upplatform3WhiteLed3, LOW);

delay(mainLedDelay);

digitalWrite(upplatform3RedLed, HIGH);
digitalWrite(upplatform3YellowLed, LOW);
digitalWrite(upplatform3GreenLed, LOW);
digitalWrite(upplatform3WhiteLed1, LOW);
digitalWrite(upplatform3WhiteLed2, LOW);
digitalWrite(upplatform3WhiteLed3, LOW);

}

void routeUpplatform3right() { // All Trains Up Via Platform 3 to Blackburn

digitalWrite(upplatform3RedLed, LOW);
digitalWrite(upplatform3YellowLed, HIGH);
digitalWrite(upplatform3GreenLed, LOW);
digitalWrite(upplatform3WhiteLed1, HIGH);
digitalWrite(upplatform3WhiteLed2, HIGH);
digitalWrite(upplatform3WhiteLed3, LOW);

delay(mainLedDelay);

digitalWrite(upplatform3RedLed, LOW);
digitalWrite(upplatform3YellowLed, LOW);
digitalWrite(upplatform3GreenLed, HIGH);
digitalWrite(upplatform3WhiteLed1, HIGH);
digitalWrite(upplatform3WhiteLed2, LOW);
digitalWrite(upplatform3WhiteLed3, HIGH);

delay(mainLedDelay);

digitalWrite(upplatform3RedLed, HIGH);
digitalWrite(upplatform3YellowLed, LOW);
digitalWrite(upplatform3GreenLed, LOW);
digitalWrite(upplatform3WhiteLed1, LOW);
digitalWrite(upplatform3WhiteLed2, LOW);
digitalWrite(upplatform3WhiteLed3, LOW);

}
void routeUpmainleft() { // All Trains Up Via Main Line to Preston

digitalWrite(upplatform3RedLed, LOW);
digitalWrite(upplatform3YellowLed, HIGH);
digitalWrite(upplatform3GreenLed, LOW);
digitalWrite(upplatform3WhiteLed1, HIGH);
digitalWrite(upplatform3WhiteLed2, HIGH);
digitalWrite(upplatform3WhiteLed3, LOW);

delay(mainLedDelay);

digitalWrite(upplatform3RedLed, LOW);
digitalWrite(upplatform3YellowLed, LOW);
digitalWrite(upplatform3GreenLed, HIGH);
digitalWrite(upplatform3WhiteLed1, HIGH);
digitalWrite(upplatform3WhiteLed2, HIGH);
digitalWrite(upplatform3WhiteLed3, LOW);

delay(mainLedDelay);

digitalWrite(upplatform3RedLed, HIGH);
digitalWrite(upplatform3YellowLed, LOW);
digitalWrite(upplatform3GreenLed, LOW);
digitalWrite(upplatform3WhiteLed1, LOW);
digitalWrite(upplatform3WhiteLed2, LOW);
digitalWrite(upplatform3WhiteLed3, LOW);

}

 


   
Quote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

Hi, it seems like no one wants to touch this problem for a couple of reasons.

1. The code is extremely bloated if the above code is showing only one-sixth of the entire code, my guess it was written by someone with only a basic knowledge of C++. Assuming your signals have only three possible combined states, all you need are three functions called with the correct parameters from your main loop.

2. One of your worst enemies in this code is the delay() function, learn how to use the millis() function, this will help with the next point.

3. If you want to add more functionality i.e. sensors, then you should look at using interrupts. Using the delay() function stops the microprocessor in its tracks and interrupts are useless.

You will then have to decide how many further sensors you wish to add. If you are polling info from sensors in your main loop then you only need to attach these to a digital pin, but if not then you will need interrupts. The UNO only has two available interrupt pins, I believe the Mega has many more.

I will only include part of the sketch as it is repeated 6 times in 6 void loops..

This I did not understand, a sketch can only have 1 loop(). the word void is only used to tell the sketch that there is no returning value, it has no other relevance.

A tip from me is to check out Derek Banas on YouTube, I am pretty sure that he has a one-hour crash course on C++, it would be an hour well spent.


   
ReplyQuote
Chrissy
(@chrissy)
Member
Joined: 5 years ago
Posts: 3
 

To try and answer you question directly, you might consider reducing the number of code lines by writing to a port rather than the individual pins driving LEDs.  If  you look at the I/O pins of pretty much any processor, they are grouped into 'ports'.  It is possible then to write to a port using a single line of code changing the state of, in this case, several individual LEDs.

You stated that you are new to programming, and so while I hate to suggest something overly technical, you should give the following a read.

https://www.arduino.cc/en/Reference/PortManipulation

As you will see, port addressing works in both directions, so you can read sensor inputs in a similar manner while using far less code.

As far as railway signal operation, you don't necessarily need to use a timer (but still can if desired).  A typical way to control a block of signals using sensors, is to trip a red signal in a given block, and then change it to yellow signal when the next block is tripped, followed by a green when the block after that is tripped.  Indeed, this is how actual railroad (block) signalling works.

Really, it is simple ladder logic when you take a high level view.  Indeed, it can be accomplished with simple relays alone.  Where software and programming is concerned however, you have even more options, including the possibility of overriding the aforementioned automatic sequence through the use of push buttons.

The code you posted is as mentioned, pretty bloated.  That however isn't your issue, especially since you copied what someone else did. 

The best thing you can do is to step back and think about what you want to happen and in what order (if any), write out a flow diagram, and then start thinking about writing the code to do it.

Writing code is no different than any other project, so having a plan of what it is you are trying to accomplish goes a long way to getting there.

This post was modified 5 years ago 3 times by Chrissy

   
Skynet reacted
ReplyQuote
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

@pugwash

Hi, You are correct in you comment I have only basic knowledge of programming I am 72 and have problems grasping the advanced code and even if I follow others everyone seems to do things different, and I copied this from a Model Railroader "Newcastle Central" Youtube and added more buttons to this sketch, also again correct with the Delay function as if I select 1 button the others won't respond till the first one has finished  I tried using Millis() but with my limited knowledge couldnt get that to work either


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@john40131

The problem for me is that I do not understand the whole problem. If you could post a schematic diagram of your track layout with the signal you are trying to control I may be able to suggest a better solution.

even if I follow others everyone seems to do things different

There's more than one way to skin a cat, as my mother used to say!

Perhaps you could upload the complete .ino file with all the code, using "Choose a files", below! Although it is probably not worth trying to make your file slimmer and better, but create a completely new solution from the ground up.

I assume you have six tracks in your station, each track with its own set of signals. My solution would be to use dedicated 74hc595 bit shift registers for each track/signal, with 8 outputs on each chip, you would have 5 outputs to control the lights and 3 to spare for other things like turning on the power to particular sections of track or setting the points before the train moves off.

Let me know if you are interested!


   
ReplyQuote
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

Hi Pugwash, I will try and upload a plan of Bolton Trinity Street layout of 1963, my original thoughts were that of the 6 lines the 5 to the right of the LH patform were bi-directional ... Maybe today as there are only 2 middle lines and 1 on the right hand side of the RH platform... BUT ... in the day I think the 3 LH tracks are up and the 3 RH tracks are down i.e to Manchester so my signals around there are going to be 2 for the Crossover at platform and seperate signals for various points which there are lots so I will have to start with a few and add...

Bolton Station West

 


   
ReplyQuote
(@dronebot-workshop)
Workshop Guru Admin
Joined: 5 years ago
Posts: 1053
 

Hi everyone

I've moved this thread into the "Model Railways" section, you have the honor of being the first thread in this (relatively) new section! 

That looks like a great layout BTW, years ago I built an HO gauge model railway and automated it. But that was back in the '90s and there were no Arduinos, so I built it around a 6502 chip.

Looking forward to more posts on this fascinating topic!

?

Bill

"Never trust a computer you can’t throw out a window." — Steve Wozniak


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@john40131

I tried to rotate and zoom in to your plan but the resolution is awful, really can't see what I need to see, to help!

I don't own a model railway or have space for one but they do fascinate me immensely and I don't think that my better half would tolerate another expensive hobby. ? 

That is why I visit this place a few times a year, as it is only 15 minutes from where I live. You could say this is where I get my "fix"!


   
ReplyQuote
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

Cheers Bill thanks for that, I think I can use my existing sketch even though it may not be perfect but only problem is getting round these delay() functions and using millis() and that I tried and is were im stumped so if can help with that I would be grateful...

Regards John


   
ReplyQuote
robotBuilder
(@robotbuilder)
Member
Joined: 5 years ago
Posts: 2037
 
Posted by: @pugwash

@john40131

I tried to rotate and zoom in to your plan but the resolution is awful, really can't see what I need to see, to help!

https://signalbox.org/diagrams.php?id=429

 


   
ReplyQuote
(@john40131)
Member
Joined: 5 years ago
Posts: 95
Topic starter  

Hi, thats the website I found forgot about that, having more thoughts about points and signals and they are really interlinked so my thoughts are switching the point servo which I can mount up to 2 microswitch on the mount I have made this can then change LED signals the only problem is this has to interlock with other signals that cross the same line and also take inputs from IR Avoidance sensors mounted under the track which in turn brings us to Block signalling ... its a nighmare senario but I think I will just have to take small steps with sketch, I do have another sketch I can work on as well from " Tom's Trains and Things " using the PCA9685 which I talked about in another post ... there is another senario but want to leave till later that is JMRi running on a PC but that gets expensive as you need decoders on signals and points and at £10 a throw ... I cant afford that..

This pic is underside of crossing..

DSC 0740

 

John


   
ReplyQuote
Skynet
(@skynet)
Member
Joined: 4 years ago
Posts: 5
 

Hi 

I would use a timer or output compare to generate an interrupt so you could monitor the push buttons first of all. Another thing there is no denounce protection. So how often do want to test for a push button and which Arduino board are using John40131. I'm having a tough time understanding you logic requirements. Normally as a train passes a signal the track circuit is shunted by the axles this causes a track relay to drop on it's back contacts. Why do you have the delay and it loks like you may have changed leds colors ot's hard to look at that code you have. 

 

We use timer overflows or even output compare timer interrupts to execute some code at a predefined time which would stop the main loop and say read the switches set a flag and the main loo would read the flags that how you can still read other push buttons and preform your other tasks. Railroad signalling written for electronic operation uses a RTOS realtime operating system. using a state machine we could make our our to preform and task you want.

 

Timers : https://www.robotshop.com/community/forum/t/arduino-101-timers-and-interrupts/13072

finite state machine: https://en.wikipedia.org/wiki/Finite-state_machine

ARR signaling diagrams: https://www.jonroma.net/media/signaling/standards/na/AAR.%20Typical%20circuits%20representing%20current%20practice%20for%20railway%20signaling.%201971.pdf

Simple track circuit: https://images.app.goo.gl/jgt75Ne8GCvptwy26 https://images.app.goo.gl/ttT57viyUQBSbA5T7

Don

 

 

 

 


   
ReplyQuote
Skynet
(@skynet)
Member
Joined: 4 years ago
Posts: 5
 

@chrissy

I guess I would be defining signal color aspects  and lose the HIGH, LOW and define ON and OFF. 

when a led is HIGH is the led ON? or OFF? @john40131

 

Don


   
ReplyQuote
(@chatty)
Member
Joined: 5 years ago
Posts: 1
 
Posted by: @dronebot-workshop

"BTW, years ago I built an HO gauge model railway and automated it. But that was back in the '90s and there were no Arduinos, so I built it around a 6502 chip"

 

?

Bill

Ha, they were days!

Kind regards

Geoff


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@john40131

There are a couple of existing threads that may be of interest. The first one is about the TM1638 module which saves a lot of digital pins for other things and only costs a pound apiece, therefore very reasonably priced.

https://forum.dronebotworkshop.com/technology/i-fell-in-love-with-the-led-key-board/#post-3515

The other thread is about the 74hc595 bit shift register, with demos and code for controlling LEDs.

https://forum.dronebotworkshop.com/project-help/control-12-leds-from-arduino/#post-795

Something else that is worth researching is the TLC6C5912-Q1 Power Logic 12-Channel Shift Register LED Driver, although I haven't worked with it myself but have attached the datasheet below.

 


   
ReplyQuote
Page 1 / 3