In distributed network systems it may happen that ID's have to be assigned dynamically. Eg
As usual, a device may only send a packet when a master requests it to do so. This means a device cannot broadcast a message such as 'hello, I'm here ! ID#A2W4567VZ'. The network has to provide broadcasts though. The broadcast is used exclusively by the master. It is obvious that only one device can answer at a time, otherwise the reply becomes corrupted. Assigning a dynamic ID requires a series of steps and a few commands. Both, the master and the slave device act as state machines. The master has to be able to detect the sending of a corruped reply.
The command, here simply named AssignID is set up similar to :
|Length||length of packet|
|SRC||ID of the master|
|data||assign unknown / assign all|
|CRC||checksum to detect valid packet|
The device state machine :
receive AssignID and probability evaluates to 1
|possibly assigned||receive any command to this ID||reply to this command||probably assigned|
|probably assigned||receive any command to this ID||reply to this command||assigned|
The master state machine, concerning this try :
|idle||timer||make new ID and send AssignID||1|
|1||timer||send any command to new ID||2|
|2||receive valid reply||send any command to new ID||3|
|2||receive invalid reply||cache ID for non use while timeout of the device||1|
|3||receive valid reply||add new device to list of devices||1|
|3||receive invalid reply||retry||3|
|3||retries expired||mark device|
The state machines require some finish, that they are water tight.This depends on the actual implementation.
As there may be more than one device in the unassigned state, not all of them should reply to an AssignID request. This can be achieved with a random number generator. The device calculates a random number each time an AssignID request is received. The probability is a mask, ANDed with the random number gives zero or not. A zero means reply to the request. Note that the random number must not be just an incrementing counter as at powerup, all devices would have the same value and it would repeatedly be so. Use a random number XOR the serial number or such a thing.
RandomNumber:=Random16() XOR Serial; // random number 0x0000..0xFFFF //generate mask from probability Mask:=(0xFFFF << Probability); // 0 -> 0xFFFF, 15 -> 0x8000 Reply_To_Assign:=((RandomNumber AND Mask)<>0); // reply if not zeroThe probabilty here is in fact inverse - but the point is shown.
The master does the AssignID from time to time. A bit more often when more that average invalid replies are encountered during AssignID. In a loop the probability is increased, when no reply comes forth, and lowered when the number of invalid replies rise.
The AssignID is best run in an own thread (task). It should run exclusively, meaning no other commands may interfere.