Dynamic slave address?
Basil
Posts: 380
Hi All,
I have a concept floating around in my head and due to lack of experience can't answer this questions for myself.
Is there any way to automatically assign bus address' to slave devices on say an I2C or RS485 multidrop bus?
All slaves will start with address 0. On slave start up they will request an address from the master which will give them the next free address.
The problem I have in my head is at startup. All the slaves will start with address 0 at power up and so will all ask at the same time to the master which will corrupt all the data.
One thing I have thought up to prevent this, is on startup the slaves each wait a random amount of time, say between 0 and 500ms, and then make the request. There is only a small chance of collisions but I don't really want the delay.
Another option is on startup the master asks address 0 if there is anyone home, and if it gets a reponse then it tells device 0 to change its address. This will again cause trouble because all the slaves start with address 0 so will all respond.
Any thoughts? This has probably already been implemented by someone!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
I have a concept floating around in my head and due to lack of experience can't answer this questions for myself.
Is there any way to automatically assign bus address' to slave devices on say an I2C or RS485 multidrop bus?
All slaves will start with address 0. On slave start up they will request an address from the master which will give them the next free address.
The problem I have in my head is at startup. All the slaves will start with address 0 at power up and so will all ask at the same time to the master which will corrupt all the data.
One thing I have thought up to prevent this, is on startup the slaves each wait a random amount of time, say between 0 and 500ms, and then make the request. There is only a small chance of collisions but I don't really want the delay.
Another option is on startup the master asks address 0 if there is anyone home, and if it gets a reponse then it tells device 0 to change its address. This will again cause trouble because all the slaves start with address 0 so will all respond.
Any thoughts? This has probably already been implemented by someone!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
Comments
If your I2C slave has a digital output you could do something similar. After it resolves its address it asserts its output, which powers the next I2C slave in the chain.
(edit) There would be a limit to how many you could connect depending on current loading, voltage drop, but I assume since you mentioned i2c you are working in a compact local area
tubular
Post Edited (Tubular) : 4/30/2009 10:26:20 PM GMT
I would prefer it wasn't daisy chained. Also, i2c will probably have too shorter distance each run can be so would prefer to go in the direction on RS485 or something similar.
Thanks for the thoughts though [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
The second way of doing it is called token ring. The slaves are connected in a ring, and the master passes a token to the first slave in the ring, and the slave passes it to the next one when it it finished with it. The slave that has the token can communicate with the master.
There are several other methods as well.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
My thinking is that if you can spare a single wire you can save yourself a lot of coding effort (effectively its is a hardware token)
Tell us a bit more about the topology and what you need to do at the nodes. Someone in the forum will have probably done something similar.
tubular
This concept is an addition to this one from Peter http://forums.parallax.com/forums/default.aspx?f=25&m=335216 where each node is a programmable, semi-smart slave IC on a multidrop bus.
Only I don't want to have fixed slave address' because I want the end user to be able to just plug the slave in and it will work without configuration. I also don't want to have to assign a unique slave address to each and every slave at the time of programming.
The nodes will be pretty simple to start with, recieving a byte sent from the prop (master) and transfering this byte to its 8 outputs. It will then read its 8 inputs and send the results as a byte back to the prop.
There will be a bit of smarts to check the state of the devices connected to the I's and O's and generate error messages if required. This may involve A/D conversion and some basic continutity tests, but I have not gotten that far yet.
In the future there will be more advanced nodes.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
How will the master device know which slave device (i.e. which physical I/Os) it's talking to if nothing is preassigned? In other words, if I say my address is $0E, how will the master know whether I'm controlling the toaster or the lights?
-Phil
Using your example, the toaster controller should only be connected to a toaster. If they user connects it to the lights then they have issues :P
This is quite a specific application and so I don't need a one size fits all algorithim just yet.
In saying that though, if a satisfactory solution can be found i'd like to adapt it into a generic solution. In which case there would be a small amount of user intervention required to assign a 'task' to each node.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
My approach is to use jumpers, read very briefly at power on, to configure the slave's operating mode and address. There are over 80 different jumper settings easily possible on the 4x2 GPIO header. After configuration the jumpers are permanenty removed, and the mode and address are retained in non volatile memory. Upon next boot the GPIO can be used for their chosen purpose (ADC PWM EEPROM emulation etc).
For simple mass configuration, I plan to have one long configuration socket say a 32*2 to accept 8 modules at a time. Then I would simply plug 8 modules in side by side, power them up a couple of times, and bingo they're set to go on address 1-8.
Peter's intention was to use the single wire BDM protocol to configure the slave from the Prop. That way standard Obex modules can be created and the end user doesn't have to get involved with the (Freescale/other) development environment at all. This has a lot of merit and also live debugging may be possible.
tubular
*************
"Basically the server comes up and sends a global "HELLO ALL" packet
which the slaves hear. The slaves accept this packet and a "prepare."
The unidentified slaves then wait "A random amount of time" and send a
three digit random number to the master. Once the data is quiet the
master then sends the three digit sequence in reply tagging on an ID# for
the slave. The slave (single) responds with the same and an OK packet.
If received OK then the slave is told to standby and await data. This
takes it out of the "HELLO ALL" loop.
This sequence runs "for a reasonable time" until you are confident that all
slaves are likely to have been identified.
I've used this to allocate ID's to PC's in a random network when running
applications that require a good amount of redundancy. In my application
slaves pinged the server every few seconds and if my reply was found the
slave then took over the server's job and maintained the network. This also
involved distributing to all slaves the entire server data required for control.
This was burst randomly as bandwidth allowed.
It was a **** to get right but it was immensely stable and secure from
machine fallouts when started. It also allowed new slaves to arrive at any
time if the "HELLO ALL" was broadcast occasionally.
*************
Sounds good?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
It does sound reasonable, but Phil has a perfectly valid point - you need a way of 'tagging' each slave IO so you know what you're talking to. It is possible for the tag info to be in the master or indeed in the slaves. Unless you are hooking up to something very generic (eg Chrismas tree lights) where the exact light being illuminated doesn't matter.
tubular
(edit) sorry... just realised you already answered this in part. Still intrigued how you can get away without it though
Post Edited (Tubular) : 5/1/2009 2:04:35 AM GMT
However, for the purpose of continuing this conversation, lets consider the idea of a non-generic slave. Perhaps each type of node could have a variable (ID) and 1 constant (TYPE).
'constant TYPE' would be defined at the time of coding and would hold information identifying the type of node. For example, an 8 digital i/o node would be one type, and a 4analog output would be another. Each node type would have a different programm anyway so this is no biggy.
The variable ID starts defined as 0 and is stored in non-volitile memory.
When the node is given its new bus address using the above algorithim, it is the asked 'what is your type and ID' by the master.
If the ID returned is 0, then the this is the first time the node has been connected to the bus. The master then assigns a random ID (say 4 hex numbers in length) and records the node bus address, TYPE and its newly created ID in an array. The slave node then updates its ID with the same number.
Because this is the first time the node has been on the network, the master does not know its purpose. This is where user intervention comes in. Perhaps a simple GUI could be implemented telling the user there are some un-indentified nodes and they need to give that node a task.
In any subsequent reboots, the master will lookup the ID and TYPE of each node on the bus and check if the ID and TYPE match any nodes in its database. If so, then the node has already been configured and it uses the current settings. If the combination of TYPE and ID do not match, then the node could be from a different bus and so the master performs the new node procedure.
Just a thought and I probably explained it funny :P Let me know what you think and if that makes sense [noparse]:)[/noparse]
EDIT:
Hi Tubular,
Well in my application, each node will have an identical hardware setup (buttons and lights effectivly) and the logic behind each set of buttons and lights is identical.
They are also location independent. The only commonality is a time clock which the master is to take care of.
For all other types of node, there can be a maximum of 1 of each because that is all thats required.
Its actually a very easy application and the prop is WAAAAYYYY overkill, but its fun [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
Post Edited (Basil) : 5/1/2009 2:12:35 AM GMT
1 - The slaves have to communicate with the master to get an address. To do this it needs to send some form of ID to the master, perhaps a randomly generated number
appended to an address request. The rest of the slaves would compare their random number to this number and regenerate their random number if it is a match.
2 - The master sends each slave an address when they request one, using the random number as an initial address.
3 - The slave sends it's "type" information to acknowledge the receipt of the address.
Thanks!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
Yes, it's quite do-able in a distributed network; I do it all the while. My code is based on this...
http://www.ibrtses.com/embedded/dynamicid.html
Ill have a good read of that one [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
-Alec
Velden in N scale
Using this technique, the master does not need to remember the serial numbers (which are rather long), since each unit remembers its unit number and can be addressed that way instead.
-Phil
PS - That method was also used as a bus access method for both serial and parallel open drain buses. Same protocol, but the bus addresses were fixed and based on device priority.