PDA

View Full Version : Discovering devices on a bus



BH_epuk
- 20th February 2012, 21:48
Hi All

After some ideas here, I have a master unit that colects data from several slaves on a bus.

At the moment I have the master hard coded with a list of the slaves addresses, all working great.
I now need to expand the system so that a master unit can be connected to any number of slaves (In reality no more than 10) and those slaves could have any address, I'll probably be using one of the I2C EEPROMS from microchip with an EUI48/64 address to assign address to slaves or at the minimun a hard coded 16 bit address.

Now the bit i'm stuck on is coming up with a discovery routine that can be run on the master unit once all hardware is connected together. This would only ever be run when the system is deployed. I already have error handling should a device become disconected from the bus so the discovery is not time sensitive (although i'm looking at < 30 seconds).

Any thoughts welcolmed

ecoli-557
- 12th March 2012, 18:28
I am about to wrestle with this same problem. I will have IO boards all connected via 485. While I can use addressing switches for a 16 bit address, I would prefer to come up with some kind of discovery to identify the 1st board, the 2nd board, etc. in a chain. I don't think I can rely on propogation down the 485 wire......
I have NOT found a way even in pseudo code to get started before I can even tackle putting it into real code <grin>.

Anyone else solve this?

Jerson
- 13th March 2012, 01:14
I must forewarn you, these are totally untested ideas. Just loud thinking.

HARDWARE SETUP:

You will need slaves that have a full duplex RS485 channel. What I mean is that the slaves should be able to see their own transmissions. This way we will have CSMA-CD (collision detection)

FIRMWARE

The master sends a broadcast (slave address 0) to set ID to 1 that is 'seen' by all the slaves. After a random delay, each slave will try to respond to the broadcast. Each slaves' transmit routine is written such that it checks that its own transmission is received back without data being corrupted(data collision) If there is a collision, the slave 'backs-off'.

In this process, one of the slaves will be detected and can take the set ID for itself. The master now increments the set ID.

You then repeat the process for the rest of the slaves. In case there are indeterminate number of slaves at the start, some kind of timing scheme will be needed to detect that condition(no responses from slaves) and terminate the discovery process.

languer
- 13th March 2012, 05:01
I would take a look at how some of the ethernet works (sort of). You want to have a minimum and maximum timeout period. After master sends out query, each slave must wait a predetermine "random" timeout which is no less than the minimum and no more than the maximum. Whoever answers first gets first dibs at the channel. The other slaves must now re-start their timers and wait again. This is kind of expanding a bit on what Jerson mentioned.

As an example:
>Slaves are happily going along
>Master sends special command to re-assign IDs
>Slaves go into special "listening" mode
>>Slaves start random timer to request first ID
>>Slave response goes like this: wait for random timer
>>>If random timer expires look at TX line to make sure it's idle
>>>To simplify, you may add a "busy" line on a wired or configuration
>>>If line is idle, send simple acknowledge back
>>>Whoever "grabs" the line first, gets the first ID
>>First slave to respond creates a "busy" condition on the TX line (or the special "busy" line)
>>Any other slaves see this busy condition and must re-start their respective random timers
>>Any other slaves must also increment their IDs by 1
>Master re-starts its own timer to wait for next response
>Slaves keep self-assigning IDs until nobody else is left
>Master times-out and send special "back to normal" command
>Slaves go back to their happy lives

You could of course start adding more "intelligence" to this.

ecoli-557
- 14th March 2012, 14:08
Great ideas and I appreciate the discussion. I understand the 'random' addressing of the IO boards on the chain but for my project I HAVE to have them in a linear order. For example: the 1st board is 1024, 2nd board is 1040, the 3rd board is 1056, etc. This is because I have to know what the address is of the outputs and the inputs on the board (there are 16 each).

The addressing rotary switch idea will work but then if I forget to address a board or if I quickly address it, there will be conflicts on the bus.
An idea I have been working is if I have a 485 network in half-duplex mode (less bus collisions), but have 2 serial channels on each IO board. The Master talks to the 1st board via the 485-IN, then the 'chain' continues to the next board by going out a 485-OUT which is connected to the next board and so on.
For the hardware I plan on using an 18F part

The MASTER will initiate a command and the 1st board in the chain will answer, get its address unless it already has one, and then merely acts as a forwarding node on the chain.
This looks like it will work but my question now is at what latency cost? I have successfully driven the 485 at 57.6K but it will take some CPU time to read in the packet and transmit it back out on the chain.
This method while adding network latency, does overcome the total number of slaves on the network as each IO board starts over <grin>.

Criticisms or comments? Any further thoughts?

dhouston
- 14th March 2012, 14:32
This is from memory so it may be slightly off but here's how ADI does it for their RS485 devices. Activated devices have addresses from 0-252 (I think) with no gaps. All start with an address of 253 (FE) and as they are added to the network, the master sends a command to FE assigning it the next available address. A variation might work for your purposes.

Looks like they have revised it since I worked with it about 12 years ago. See Section 5.2 (http://appdig.com/manual/Ocelot-2.pdf) (p77) in their manual.

BH_epuk
- 14th March 2012, 20:04
I've not had a chance to do much more on this but my though's were

All slaves have fixed unique addresses, they also have a broadcast address to listen in to

The master broadcasts a start new discovery command - slaves wait a random time and respond to master with their address

After a period of time the master then attempts to talk to each discovered slave

If the master can talk to the slave the slave address is marked as valid and the slave is given a mute command

The master goes through the remaining discovered slaves as previous step

The master then issues a retry discovery command - only slaves not muted would respond, again at random time delays

The Process then repeats until the master can issue a retry discovery command and get no responce from any slaves - assume all slaves discovered.

Any comments welcolme