I'm planning a project which will consist of two parts. There will be anywhere from 1 to 4 "slaves" which are basically atmega168s with Arduino firmware and a couple of relays.
Then I want to have 1 master (also with atmega168) which will tell these units what to do. The slaves should also be able to tell the master what they are currently doing.
Since I will have a number of slaves but the master only has one serial in/out connection, I would like to know how I can make this work. Can I just connect the slaves' serial ports in parallel or is there anything else that I need to do?
Ideally I want to have them connected like this:
slave > slave > slave > slave > master
So as you can see, I really can't give the master 4 serial ports and then merge them in the master but rather each slave needs to take the serial data it gets from the slave to the left, merge it with its own serial data and then pass it further down the chain.
Is what I've described so far reasonable? I've got a bit of board space left so adding a converter chip or whatever is not a problem.
I will probably be using USB connectors as they have just the right amount of wires, they are easy to find in both male and female versions and there are good eagle libraries available. As an added bonus, would it be possible to make the communication follow the USB standard? If that's possible, is it doable to make a computer application that could function in the same way as the master?
I hope what I've described so far makes sense. If not, let me know.
Can I just connect the slaves' serial ports in parallel
Not as RS-232 or TTL, but you could if you set it up as an RS-485 network.
You could do your "daisy-chain" configuration with RS-232 or TTL, have the master feed commands into the last slave, and program each slave to feed any packet not addressed to it down the chain. If you had the master do that, too, you could effectively turn the system into a "peer-to-peer" network in which the slaves could communicate with each other directly.
What volume of messages are you expecting? You want to make sure that you don't exceed the capacity of the serial port, or keep the slaves so busy relaying messages that they don't have time to do their primary job.
I2C may be the way to go for this one... it supports about as many devices as you could ever need chained together.
RS485 seems great although obviously I'd prefer to use arduino's regular serial interface for simplicity.
So this daisy chain thing you talked about, if I've understood this correctly then I'd connect send from master to receive on the first slave and then do the same thing all the way down. The only thing I can't quite figure out is how I would know when to connect a slave back to the master again, how would slave know if it's the last one in the chain and then change the connections accordingly?
If there's a good way to do this then that's probably be the way to go but if not, I need to look up some tutorials on I2C or RS485.
The problem with chaining them like this is that you need two serial ports, one to receive and the other to transmit further down the chain. RS485 comes in two flavours half duplex and duplex, depending if you need to transmit or receive at the same time. Duplex is easer because you don't have to switch the drivers. RS485 also involves a protocol as well to allow switch round of messages.
Your system is made much more complex by the requirement of the slaves having to report back. If you could manage that the slaves only listen then you could wire all the RX lines together and send from the master. Then have a protocol that involved device addresses so that only one slave responded to any one command.
I2C is probably your best bet. You could implement some kind of similar protocol system over serial where all of the chips share the same tx/rx lines, but each chip only pays attention to commands that are addressed to it. Pololu does this with their motor controllers and servo controllers so you can control several over the same serial output. I2C takes care of all of this for you though, there's tutorials in sketchbook->examples->wire
The problem with chaining them like this is that you need two serial ports, one to receive and the other to transmit further down the chain.
i think he could get away by having only one port per “station”
1 RX and 1 TX, you get the message from previous and transmit to next, but the TX of the last one must be connect to the first one.
And it could all be in TTL, no converter.
BUT: if you send a message, it could come back through your RX after making the whole circle. and if you are not removing your request, the communication could be jam.
Patgadget got it right: it’s one big circle, with each node having one Tx and one Rx.
He also identified one vulnerability the code need to protect against: each node needs to identify anything it’s sent that’s gone full circle, and avoid flooding the network. Although it might want to retry it once or twice first.
The other serious weakness is that, if any node goes down, the network fails: everything “downstream” of it stops getting messages. One technique for protecting against this is to equip each node with a relay that switches between its Tx (normally off) and its Rx (normally on) controlled by a pin on the CPU: if the node is not powered up, or its watchdog timer resets it, it turns into a “jumper” between its input and its output.
Every approach has its costs and benefits. I’d probably lean toward RS-485 as my own first choice, with a “poll and response” protocol, but the “ring” method may well be simpler to implement for someone who doesn’t need to have nodes spaced far apart and can tolerate the vulnerability of having single-node failures disrupt the network.
Or you could wait a few days and by an Arduino Mega with 4 serial ports, use it as the master and have all the slaves directly connected.
but the TX of the last one must be connect to the first one.
Yes good idea. But that leaves the master short of a RX input for getting commands from an external source, is that needed or is the whole thing self contained.
BUT: if you send a message, it could come back through your RX after making the whole circle.
Just tag the message so the master knows it is one it has sent, a master never relays messages and a slave relays messages not intended for itself.
Or you could wait a few days and by an Arduino Mega with 4 serial ports
An even better idea.
I will be using a standalone ATmega168 with my own PCB so using an arduino mega isn't really an option.
So it seems like I2C would be a good way to go. It's easy to implement and doesn't need any extra hardware besides a resistor or two.