I have a small RS485 two-wires network with about ten nodes. I have a master that initiates the communication on the bus. All the other nodes are always in receiving state and start transmitting only if the message from the master is addressed to them.
A simple method to assign an address to a slave is to have a set of jumpers/dip-switch on the board, but during the installation/setup phase, the technician must be careful to avoid duplicate addresses.
I'm thinking about an alternative method to implement in the master that, during the start-up phase, assigns automatically the addresses to the slaves. However, at the moment, I didn't find a good solution.
I don't believe there are any techniques that are guaranteed to produce unique addresses for each slave if the slaves are otherwise identical.
An approach that will work most of the time is:
master to slaves: Send "First one to answer is assigned address #1."
slaves: All wait a random interval while listening for another to claim #1. One (or more!) with the shortest wait time claim #1.
Since there's a non-zero chance that two (or more) slaves replied at exactly the same time:
master to slaves: Send "Okay, confirm address #1."
slaves: The one (or more) that think it/they has/have #1 wait for another random interval. The first to speak, gets #1 and the possible others relinquish it.
Repeat for the remaining addresses. However, I don't believe there is a way to make the probability exactly zero that more than one slave does not behave in an identical fashion throughout the process (even given an arbitrary number of confirmation cycles).
The way I've implemented auto addressing in the past is to arrange the serial bus connection to pass through the slave units on a gated pass through. Initially all slaves wake up with the pass through gated open. This causes just one slave to "see" the master. He gets the first address and then after a confirmation step with the master closes his pass through. The process repeats till the master realizes that no further devices respond on the serial chain. This works like a champ and is reliable.
In addiction DIP switches are unreliable in harsh conditions.
If the master has persistent memory and each slave is initially known slave address (say 255), build the network by adding one node at a time (e.g. by powering up the devices one by one). The master checks for slave 255 and assigns it an other slave address. This is repeated for all slaves.
If a faulty node needs to be replaced, the new replacement unit is again at address 255 and the master then commands it to the same slave ID as the original device.
If each slave has a unique vendor:serial_number, either readable through the ordinary bus or some configuration port there are various methods.
The address data base could be done by adding one device at a time, as in the previous case or using some off-line configuration (running on a laptop) to run a point-to-point connection with a new slave, either to the network port or through some configuration port and command the slave address.
Take a look at CanOpen Layer Setting Services (LSS).
If the slave has a unique vendor:sertial_number, generate a hash code and use it for slave address. The master runs through all possible slaves by asking e.g. "Slave 37, report your serial". If there is a timeout, none is there, if there is a garbled reply, there is a duplicate, there is a collision and if there is a clean response, assign the address. Repeat the scans but ask "slave 37, report serial except serial37" and if you got a response, force the slave address to a free slave address.
If there still are garbled responses, refine your search "Slave 37 report your serial ending in 0" up to serial ending in 9. Of course, this requires that you are able to differentiated between no response, garbled response and valid response.
Assign each unit a unique serial number. This can be done during manufacturing, or using an external ID chip. If that's too expensive, you can use a random number. For instance, you can use the LSB of an ADC input to generate a random number. If you make the serial number big enough, the chance of duplicates is very unlikely (32 bit for instance). Once you have a known good serial number, program it into the EEPROM/Flash if you have it.
The master then broadcasts a probe:
"any device that's not initialized, please respond with your serial number".
To avoid collision, clients use a random backoff time before sending, and only send when the bus is idle.
If the master receives a valid response from serial number X, it sends a packet: "device with serial number X, you are now initialized with bus ID Y". This device then stops responding to the probe broadcasts.
The master repeats this process until it gets no response. After that, it can send an occasional probe during normal operation to detect new attachments to the bus.
Of course, like somebody else remarked, you still may need to figure out which device is which, depending on your application.
I've never seen a case where the address of a 485 node wasn't part of the node's configuration identity - we always had to know what the role of the thing at address was. It therefore had to be static.
It's also usually preferable to have the address stored on the device in some way other than dip switches.
For truly identical slaves, that would be somewhat obviously either pointless, or impossible. There must be _something_ that differentiates the slaves from each other --- otherwise, why would you have more than one in the first place?
How best to address individual slaves depends on what that differentiating "something" is. It could be the type of node (--> I2C addresssing by device type), a physical ID assigned to the node beforehand (--> dip-switch, configurable EEPROM), a universally unique ID like in Maxim's 1-wire bus devices, or even just its position along the cable connecting all nodes (--> "auto-addressing", "cable select").
So it's really your choice to make, depending on the specifics of your situation.
Assigning addresses in Plug-and-Play manner is only a half of the problem. You need to make sure that devices would always be enumerated in the same way. Also, the master should somehow identify the roles of the devices; i.e. which device does what.
One obvious solution is assigning globally unique ID to every device. Like EEPROM with pre-programmed MAC address or serial number.
The other solution is token ring network topology. The devices are automatically numbered in their order in the ring. Done that with RS-232; very simple and elegant.
Correct, that's why mentioned that too. But it can help to first discover all the devices. If the master knows all the devices, and let's say each device has a LED, the master can blink each LED in succession, and ask the operator for more information about the device.
Yes. I have used that technique before. Each device was programmed with a unique ID, and then tagged with a physical label with the same ID. After the plug-and-play sequence, the operator could assign a name/function to the device using the unique ID as a reference.
It does not directly avoid collisions, but a s far as I understand, all RS-485 transceivers are collision tolerant (i.e. doesn't emit he "magic" smoke) for short collisions.
Any message with CRC should give a rejected message when received, if there is a collision.
CanOpen can be implemented with ordinary RS-485 transceivers by tying the Transmit Data input to "0" and connecting the actual transmit data to the Transmit Enable pin, thus, the transmitter will be actively driven to the Dominant state, while the fail safe termination will drive the bus to the Recessive state, when the RS-485 transmitter is disabled.
The network is a very simple access control. I have many points where users can enter in a protected space if they type a correct "password" (in practice, they should have a valid RFID tag). The logic of the system is in a central board (the master on the network).
The central board doesn't need to know where the slaves are positioned, because the behaviour of all of them are identical: if a correct password is typed, open the gate. Nothing else.
So the master polls each node if someone is at the gate. If the slave answers with a password, the master check its validity and answer with an ack (open the gate), otherwise with a nack (gate is keeped closed).
In this simple scenario, the slaves are effectively identical and should be nice if the installer can wire a new slave in the network without worrying about addressing methods.
Actually, the system as described seems overly complex for the task. If there's only one security zone, thus no need to know _which_ door is being asked to open, then there's no need for node identification at all, thus no need for an addressing scheme.
The master could just as easily poll on a broadcast basis, i.e. "master to all slaves: do you have activity?" Slaves that do, reply with their data. Add collision detection and a randomized back-off mechanism, et voila.
This is the best solution *AND* it remains within the original design specs.... unlike other ideas which ignore the original problem and start chasing collision detection, etc. And it can be built so that the Master does a periodic poll to see if any new Slave nodes have joined the network.
This one gets printed & placed in my RS-485 folder for future use.
Depends on the application doesn't it? And how the gating is done I suppose. For example it looks like a node that is switched off or faulty will bring down the whole network (or a big part of it). May be OK for systems where everything has to be working at once anyway. But for something like machine monitoring you need more flexibility.
I agree. I've seen too many HI'Z network transceivers get stuck when something "bad" happens. I'm kind of fond of the "Screw Auto detect" and go with fixed addresses for special stuff and a couple BCD knobs for everything else. Sure stops a lot of head aches, and if someone is too stupid to know how to twist a knob, maybe they shouldn't be installing the thing in the first place.