Automating Train Movement

Not too long ago, I started a thread to see if an Arduino micro-controller could be used to replace the train dispatcher-in-a-closet on a large model train layout. I received a lot of good advice and several options to follow. Original Thread I've progressed sufficiently to start building my actual train layout, knowing that this simplified scheme has a high probability of working...at least in my head. I wrote everything down and attached the paper and the Mega 2650 program.

At the moment, trains can only move in 1 direction on the sidings. I've tried but can't figure out how to allow bi-directional travel. It's not a signal issue. The GreenSteam GSP-14 can handle bi-directional travel. My first thoughts are to associate a direction with each path and then associate that direction with the train as it travels.

Ideas would be greatly appreciated.

Chaz

Automating Train Movement.pdf (127 KB)

TrainMovementControl.ino (5.82 KB)

How is the train controlled?

Nothing in there makes it clear to me how you make the train move at all - maybe I'm missing something.

Thanks for catching that. I'll put something into the document.

Just like on a real railroad, the train crew makes the train move. Green means go, Red means stop. I would never take the controls away from the train crew. That's the fun of operating trains. I do not want to hang a computer on my layout.

I also want to add a time out, in case the train crew is not paying attention, and the train doesn't move onto the mainline. You snooze, you lose your turn.

Chaz

I mean, what is done to make the train move? Put voltage across the tracks? light a torch under a steam boiler? light a fuse on a rocket engine attached to the train? Pull the lever on a trebuchet?

This is what you need to give details on, because that's the part of the project you're having problems with. We can't tell you how to make it go backwards without knowing anything about how the train moves.

I assume these are model trains, not full sized ones...

Sounds to me like you cannot get away from communicating with the engine somehow via onboard uc.
More info on how power is applied as DrAzzy says.

The trains are controlled by a Digital Command Control (DCC) system. A basic system has a throttle for each engineer, which communicates to a central DCC command station, which communicates to a DCC decoder located in each locomotive by modulating the track voltage. All locomotives have unique addresses. In addition to locomotive decoders, there are stationary decoders. DCC is very popular when you want to operate many trains at the same time, on the same tracks.

You can assume that the engineers can run the trains. You can assume that the GreenSteam GSP-14 Automatic Signal Controller (monitoring all the blocks and the positions of the turnouts) can run the signals.

All I want to do is mimic the functions of a central dispatcher and align turnouts attached to the mainline so trains can move efficiently without yelling at the other operators or me...to see if it's safe to take the mainline.

Ok....beyond me I am afraid as I cannot get a complete picture although it seems you have a very good knowledge of the system and just what you need.

I did a quick read of the DCC system on Wiki and I wondered as to whether or not you have read the same as there may be something there to get you on the right track. Many links there also.

I think the piece that may be causing confusion is that (I believe) humans control the trains using speed controllers that communicate with locomotives over DCC.

The arduino is not intended to drive the trains on full automatic - it just enables their safe use of the track so long as the human driver obeys the signals.

The piece I still don't understand is how the driver gets instruction about what the train is to do. Is there some paper manifest system that says "This train is loaded with take it to "?

You are correct, there is a person with a DCC throttle in his hands. He has total control over train movement. In addition, he can make sounds, like brakes releasing, bells, horns and other fun things by pushing buttons.

In addition he could send commands to stationary decoders to do just about anything you want. The level of automation can be quite sophisticated. I choose not to control the turnouts this way, because the operator may not know it is safe to take the mainline. That part is best done by the Arduino Mega because it knows what blocks are occupied by trains and how all the turnouts are aligned.

Train crews (usually a Dad and a Lad) pick up written instructions explaining where to go and what to do when they pick up their handheld throttle. My example layout does not include any industrial tracks, because those tracks are not controlled by the dispatcher. That is, the dispatcher doesn't care about a train doing work, if it is not on the mainline or the sidings. The instructions are mostly about what to do on those tracks in each town.

My instructions look remarkable like the Track Warrants used on real railroads.

The written instructions are the track warrant. What the train crew doesn't have is permission to take the mainline, because the signals in front of the train is red. My program, checks each path looking for a train that is ready to move to the next town. If it is not safe to take the mainline, the signal remains red because the turnout is aligned against the train. If it is safe to take the mainline, my program aligns the turnout with the train. The GSP-14 Automatic Signal Controller recognizes that the turnout is aligned with the track and sets the signal green. Finally, the train crew has permission to take the mainline. That is, I control the signal indirectly, just like a dispatcher sitting in the central office.

I'm quite certain I've solved the problem, however, you will note that eastbound trains, moving from left to right, have to use the red sidings and westbound train, moving right to left have to use the blue sidings. This restriction does not exist on a real railroad.

My current problem is how to allow both westbound and eastbound trains to use either siding.

Chaz

mmm...situations like this I tend to sketch up a flowchart.

Good to see you may have solved it though.

bhuck:
My current problem is how to allow both westbound and eastbound trains to use either siding.

It seem to me this hinges on the question - what are the circumstances in which a train should use the "wrong line"?
And how you would capture that concept in your software. I presume the real railway has rules for that, and not just because "the driver would like a change"

If the circumstances exist so that the wrong line should be used then the software just needs to confirm that the relevant lines are free to be used.

Of course another approach is to see what routes are available and use a random number to choose.

I wonder if your initial approach to managing routes within your Arduino program has inadvertantly associate directions with the track sections?

...R

PS it would be useful if you edit your original post and include a link to your earlier Thread. It may also be wise to ask the moderator to lock the other Thread.

I've defined a path as list of track blocks, including the source, the mainline and the destination track block numbers.

Since I dedicated one siding to Eastbound trains, and one siding to Westbound trains...I've solved the problem where trains pass, traveling in opposite directions. Dedicating one siding to eastbound and one siding to westbound traffic required that I only look ahead 1 path.

Thinking out loud...

I will keep the dedicated siding concept as the primary travel mode. That is eastbound trains move from eastbound sidings to eastbound sidings, and westbound train move from westbound sidings to westbound sidings.

When that's not possible, I need to look ahead 2 or more paths...looking for the next free block in the correct direction. That is, and eastbound train can use a westbound siding in the first town, if it can get to an eastbound siding in the second town. Sounds like recursion to me.

When I find this condition, I have to align the turnouts all the way from the source to the final destination.

Chaz

I've attached a second example layout that connects 3 towns together.

Consider an Eastbound train (moving from left to right) that just showed up on B0. Normally, it would travel from red track to red track as it makes it's way Eastward.

In this example, the Eastbound train can't proceed normally, because the next red track is fouled. However, it could proceed to B6, the next available red track, if B2, B4. B5 and B6 are not occupied, and no warrants have been issued for the mainlines B2 and B5. I know that a warrant has not been issued when the turnouts T0, T1, T2 and T3 are in their default conditions.

When I check a list of things, I build a bitwise representation. For example,

Checking blocks 0,2,3,4,5,6 returns 010111...if a train qualifies to to move from B0 to B6.

Checking turnouts 0,1,2,3 against their default alignment, returns 1111...if no track warrants have been issued for the mainlines B2 and B5.

To issue this longer than normal track warrant, I have to align turnouts T0 and T1 opposite their default alignments. In addition I have to lock T2, T3 and T4 in their default alignment until the train arrives in B6.

Checking blocks 0,2,4,5,6 after the train arrives in B6 returns 11110.
Checking turnouts 0,1,2,3 after the trains arrives in B5 returns 0011

The turnouts T0, T1 will be returned to their default positions, after the train arrives in B6

The GreenSteam GSP-14 Automatic Signal Controller will take care of all the signals.

Chaz

bhuck:
When that's not possible, I need to look ahead 2 or more paths...looking for the next free block in the correct direction. That is, and eastbound train can use a westbound siding in the first town, if it can get to an eastbound siding in the second town. Sounds like recursion to me.

Also thinking aloud ...

I suspect that is different from the concept in my mind.

I imagine having a series of track sections - let's call them A B C D E F which get a train from A to F or from F to A
For some of them there may be pairs - say B1 and B2 and D1 and D2

Suppose that for the direction A to F the options B1 and D1 are preferred.

Then the software would check to see that all the elements B1 C D1 E and F are clear before setting the route.
If, however, it found that D1 was not clear it could then consider D2

In practice I think the order of checking would be (B1 or B2) C (D1 or D2) E and F. If any of them failed it could not set the route.

I don't see any need for recursion (which can get very tricky, especially with limited RAM) - just a system of priority.

...R

I don't mind recursion, but you are correct. It's not needed.

My program has several arrays, indexed by the path number, that include lists of things associated with that path.

In my second example, there are only 4 short paths.

Blocks per short path, ordered from source to destination
0, 2, 3
3, 5, 6
7, 5, 4
4, 2, 1

Turnouts per short path, ordered from from source to destination
0, 1
2, 3
3, 2
1, 0

and 2 long paths

Blocks per long path
0, 2, 4, 5, 6
6, 5, 3, 2, 1

Turnouts per long path
0, 1, 2, 3
3, 2, 1, 0

So, all I have to do is loop through the short paths and then the long paths, looking to issue and revoke track warrants.

For a short path, block occupancy 011 (3), indicates a train in the source block and the mainline and destination blocks are empty. Block occupancy 110 (6) after that train is completely in the destination block.

For a long path, block occupancy 01111 (15), indicates a train in the source block and all the other blocks are empty. 11110 (30) after the train is completely in the destination block.

The switch statement for short paths has case 3 and case 6. 3 to issue a track warrant and 6 to revoke a track warrant. The switch statement for the long paths has case 15 and case 30. 15 to issue a track warrant, and 30 to revoke a track warrant.

I'll code it up next week, after I figure out when a block is fouled.

Chaz

In my second example, there are only 4 short paths.

Blocks per short path, ordered from source to destination
0, 2, 3
3, 5, 6
7, 5, 4
4, 2, 1

I'm a little confused by this because none of them seems to be the inverse of the other - eg how do you get from 3 to 0 ?

In any case, let's assume that physically 0, 5, 3 is also an option - but 2nd preference because 5 is normally used for the other direction of travel.
Then I would add that group as another path to be considered if the first path 0,2,3 fails. (these numbers are just for illustration - please substitute sensible ones)

...R

Those paths apply to my second example.

The second example is taken from the middle of a larger layout. It only has eastbound and westbound sidings, and no return loops.

I'm also building a layout using Arduino to control Turnouts, Control Panel, Signals but NOT the actual trains (which are DCC). It's still a work in progress (and I keep finding something "just a bit different" to change - and then on top of that, there's the "improvements" that can be made to the layout....) but certainly the overall concept seems to be looking good.

The concept & layout so far has....

  • 36 control "blocks" - no direct DCC control, but the ability to "turn off" power if a train passes a signal at Red/Stop
  • including double track and single (bi-directional) track areas - from a programming perspective one block per direction.
  • holding loops and sidings
  • hidden sidings (fiddle yard)
  • Modern Australian practice, which can mean signals with 5 or 6 lights (LEDs....in HO...scratch built)
  • Control Panel with indicators and switches for signals, track and turnouts
  • Separate train detection (NOT track/DCC based) currently using reed switches and magnets (cost), but intended to be flexible enough to be changed seamlessly to any other type of detector system.
  • I2C communications between multiple Arduinos to handle the sheer number of inputs/outpus - I've currently got 2 Megas and 1 Uno all handling different things, with one of the Megas the Master Controller.
  • 20+ turnouts....EVENTUALLY controlled by Servo motors via Arduino........eventually.....

Basically everything except actual loco control is through the Arduinos, including directly powering the Signals/LEDs.

Happy to discuss more if anyone's interested, including sharing code.

Ross McConchie
Canberra
Australia

Forgot to say where I'm actually up to:

  • About 1/4 of the layout is "usable" with track down, train detectors, control panel & signals installed (scenery? what's that?)

  • Another 1/4 needs to have the correct wiring set up - detectors first, then signals - oh and I need to fix that bit of track....

  • Control Panel Switches and LEDs, Turnout logic (basically just the switch on the panel at this point) all working as they should - for this half of the layout

  • I2C communications working

  • Track power "control" not connected, but not critical

  • Block logic, train detection, etc working beautifully (for this half of the layout)

  • The last 1/2 has track and power, but that's about it - including no control panel.

  • Block logic for the rest....I'm slowly expanding the number of blocks "in use"...keeping a close eye on how much memory I'm using.

  • Counting inputs/outputs as well in case I run out.

So to get train "running", at least on a double track "continuous run", it's really only a couple of days work....but I'm making signals at the moment.....and.....

Ross McConchie
Canberra
Australia

Rather than hijack the Thread started by @bhuck why not start your own Thread, put all your existing content into it and then delete all your input from here apart from a link to your own Thread ?

That way Forum users could get full value from both experiences with a lot less confusion.

...R