would you like a program challenge?

This may be a little cheeky but I am trying to program an uno to run a small section of a garden railway, the sort that people sit astride the carriages behind small steam engines.
I want to control four sequential signals. Two of which are four aspect, that is they have four lights, red, yellow, double yellow and green. One has three aspect - red yellow and green and one has two aspect, red and green. By using diodes I could use just two yellow lights and have one or both light as required from two outputs.

There are five switches that the trains trigger as they pass.

The lights go to red when first turned on, if relays are used on the outputs the first relay could be de-energised to light the red lights and energised to light the yellow. When the system is reset everything finishes with all on green, this could be done by one pass of a train and not a separate switch.

When a train passes the first switch the first signal (four aspect) goes red. When it passes the second switch the second signal goes to red and the first to yellow. This sequence continues until the train passes the fifth switch, because the third signal is three aspect and the forth two it would mean that the fifth switch turns the second signal and both the third and the four signals to green.

A second train could enter the system when the first train is beyond the second switch and the first signal has gone to yellow.

If anyone is interested in a challenge I would welcome the input. Can you do it in fewer ports from the uno than the eighteen it first looks as if it requires? remember a relay on the output could save at least one output to each signal.

Thanks for at least reading this far,
Bob.

As described, whenever a signal is red, the one behind it is yellow. So one of the yellow lights in each signal can be driven from the same pin as the red light in the following section. Similarly, the second yellow light in the first 2 signals can be driven from the same pin as the red signal 2 sections ahead. You can use diode gates to ensure that both yellows are lit when required. Not only does this save 5 pins, it simplifies the wiring.

One of my first thoughts but actually wrong.
If a second train follows the first is would put the first signal to red whilst the first train was between the second and third signals and the second signal would be red, two reds. I could have a train in each section - four reds.
I mentioned the use of a diode for the two yellows in the second paragraph.

First of all, you should not make it harder for yourself.
So if you use an Arduino Mega2560, you can have all the inputs and outputs. That makes it a lot easier.
With long wires, I prefer relays with optocouplers and also inputs with optocouplers.

To me it seems that it is harder to understand what you want than the actual programming....

Without much consideration, I would probably use two pins and 3 external chips. This would allow me to only have 4 wires going from the control circuit (with the Arduino) to each of the signal displays and a central switch hub. This allows the connection to be made with simple 4-wire modular wiring. The magic solution to this: I2C. Thus the four wires would be Power, Ground, SDA, and SCL. MicroChip makes a couple of nice I/O expanders that communicate via I2C, 16bit and 8bit versions are available. Because these chips are GPIO, you use the same chip on your light outputs as you do for your switch inputs. For this application, 8bit would probably be sufficient which would be MicroChip's MCP23008. (See MCP23008-E/P Microchip | Distributors, Price Comparison, and Datasheets | Interface and Transceiver IC | Octopart for availability, pricing, and data sheet for the through-hole version). I don't know the line length limitations of an Arduino's I2C so depending on how long the runs are you may need to have an I2C line driver. Then because all the switches and lights are individually addressable, the logic for what light turns on based on which switches being activated is all in your program. Makes it flexible for changing things, or adding future lights and switches. (Note, these chips only provide the lower 3 bits for addressing, so the maximum you could have on one I2C bus at a time is 8.)

Just some thinking out loud for your consideration.

Edit: "for" => "four"... homonyms...

yes optocouplers would be fine. the present switches are sensors that pull the voltage to zero with optocouplers this wouldn't matter for the inputs they could be any direction if fed from optocouplers.
Is the 2560 language the same as the uno? can I programme in one and port it?
I dont have a 2560.

sembazuru,
Are you saying have a chip at each set of signals?
The idea of four wires sounds good.
The furthest signal is about 200 yards from the place I want to put the central hub which is near the third signal (about 10 yards).
The switches are close to each signal head.

matelot:
One of my first thoughts but actually wrong.
If a second train follows the first is would put the first signal to red whilst the first train was between the second and third signals and the second signal would be red, two reds. I could have a train in each section - four reds.

If you are using relays to switch the lamps, then you could still use the same pin-saving arrangement with this modification. You probably want all the lights to be red by default (when the controller is not working); so the red lights will be connected through the NC contact of the associated relay. You can then gate the power for the orange and green lights in the same signal through the NO contact of the same relay.

The idea of using a common bus and a chip at each signal is appealing, however to get I2C to work over anything like that sort of distance, I think you will have to use some sort of amplification in order to meet the rise time specification.

yea dc42 thanks for the reply.
do you know how to wire and prog a I2C system? would it be much beyond basic uno programming?
I've never gone that far .

matelot:
sembazuru,
Are you saying have a chip at each set of signals?
The idea of four wires sounds good.
The furthest signal is about 200 yards from the place I want to put the central hub.
The switches are close to each signal head.

Yes, that is exactly it. Attached closely to each signal head (possibly even inside the housing) would be an I/O expander chip, and then in a central box for all the switch inputs would be another I/O expander chip. So you might have (please pardon the ascii graphics...)

+---------+   4-wire modular cable   +------------+   4-wire modular cable   +-------------+   4-wire modular cable   +-------------+
| Arduino |=------------------------=| Switch box |=------------------------=| Signal Head |=------------------------=| Signal Head |= (Future expansion)
+---------+                          +------------+                          +-------------+                          +-------------+
                                       |   |   |
                   Pairs of wires ->   |   |   |
                                       |   |   |
                          Switch one --+   |   +-- Switch three
                                           |
                                      Switch two

Then read from the I2C device in the Switch box, decide what the lights should be based on all the switch states and switch state history. Then write out to the I2C device in Signal Head 1, and then to Signal Head 2. Repeat this loop as fast as you can. You could even have multiple switch boxes (either for proximity reasons or if you end up with more than 8 switches in the future). You may be able to get away with a combination of star and daisy-chain topologies, but I'd research I2C bus topologies first. Don't want funny signal reflections messing things up.

If I2C doesn't work out for technical reasons, I/O expander chips are available for many different bus technologies. If you keep the pin count to 8 or below (up to 6 signals, power and ground) you can exploit the simplicity of modular connections by using either phone cables or Ethernet cables for your physical wiring. (Buy a crimper, ends and a spool of CAT3 or CAT5 cable and you can make your own custom lengths cheaply.)

Hmm.
At each box I would need four wires for the signal, one for the switch and a return. Are the signal heads you are suggesting capable of this?
Is the signal head addressed from the library wire.h?

Having thought it over some more, I think multidrop RS485 using async serial protocol might be better because of the long cable runs, with an attiny84 at each signal. If you use Cat 5 cable (or preferably Cat 6 for its lower resistance), then depending on the power requirement of the signals, you might be able to use 1 pair for the RS422 and the remaining 3 pairs for power. The attiny84 has enough pins to connect all 4 lights, the RS485 transceiver, and the switch.

ok I will examine that approach can you be more help with the details?

matelot:
yea dc42 thanks for the reply.
do you know how to wire and prog a I2C system? would it be much beyond basic uno programming?
I've never gone that far .

I'm about to dip into I2C for the first time myself, but reading through the tutorials it seems straight-forward enough. Because it is one of the built-in protocols of the ATMega chips, there is support already there using the Wire library included with the ArduinoIDE.

Well, as dc42 says, the lengths required for this might be a bit too long for raw I2C. But, doing some Google searches I found someone reporting success with LTC4300 chips being used as I2C line drivers. Datasheet: http://datasheet.octopart.com/LTC4300A-2IMS8%23PBF-Linear-Technology-datasheet-7622793.pdf
This would definitely be something that would need to be prototyped and tested thoroughly. So... what is your R&D budget? (rhetorical question...)

Sembazuru:
This would definitely be something that would need to be prototyped and tested thoroughly. So... what is your R&D budget? (rhetorical question...)

Ha Ha small as possible.

dc42,
I can use the cat 6 cable , do you think the distances would cause a problem?

dc42:
Having thought it over some more, I think multidrop RS485 using async serial protocol might be better because of the long cable runs, with an attiny84 at each signal. If you use Cat 5 cable (or preferably Cat 6 for its lower resistance), then depending on the power requirement of the signals, you might be able to use 1 pair for the RS422 and the remaining 3 pairs for power. The attiny84 has enough pins to connect all 4 lights, the RS485 transceiver, and the switch.

I was trying to keep it KISS with small part count, but the limitations of I2C might be biting me in the rump. Looking at a schematic used on something here at work I see that we use RS485 with a MAX1480 providing the UART translation and support circuitry to protect from shorts and static. If you want to see that part of the schematic I can check to see if I'm allowed to scan it and post it publicly. (I don't see why not as we are a research department at a University, not a commercial company...)

that sounds as if it is getting serious. I am only volunteering to wire a set of signals for the railway.
Would sending it to me e-mail be easiest?
I think I would want to be fairly sure I had a grasp of the software program to make it happen before I spent that sort of money.

The Arduino Mega 2560 can use the same code as for the Arduino Uno. The I2C pins and SPI pins are at another location, so not all shields are compatible.

With that distance, use many wires or use RS485 or go wireless.
I like the idea to use Cat5 or CAt6 cable.

I would like to make a layout for the code.

Programming :
The best way to do this, is to actually create the (location of the) train in software.
The second train is just another variable.
Divide the track in parts. The switches are the dividers.
Make functions for the signals. A function for each signal. So the way the signal works is in the function. But the functions can be called in the same way.
The magic happens in a block that makes decisions on the situation at that moment. This should be written well, because it will be the hardest part to understand.

Updated according post below: To make the decisions it would be handy to have all switches in variables. So perhaps the switches should be updated a number of times per second and copied in the variables. The switches should be filtered before copied, since every wheel activates it. The variables should have the 'clean' and filtered value to make the decisions upon.

yea that looks about it.
One problem is that each wheel is going to be going over the sensor so it should only trigger once for each train. A delay or a ref that the train has triggered the next switch should be enough to separate the signals. I worked out <2 secs for each bogey. i.e. if switched again in less then 2 secs it is the same train.
The system as it works now is that the switches are the dividers for each section.