Hi Folks
I am thinking about making an I2C connected uC (atmega master, attiny
slaves) cluster consisting of up to 10 participants. What I want is that
you can connect or disconnect any number of "clients" if the power is
down.
The cluster will have one master, all the other are configured as slaves
BUT: the master does not know how many slaves it has, because the user
can add or remove slaves (not during operation though). Also the slaves
do not know how many other slaves there are and what their addresses
are. The addresses need to be random.
To sum up:
One master, up to 9 slaves. Unknown addresses of the slaves. Slaves need
to be able to change address to have a unique address.
Has anyone done something like this? Can it even be done?
My approach would be something like this:
The devices later to be slaves (attiny) start out as masters, the later
master (atmega) starts as a slave. Each attiny does an analog read on a
floating pin to get a random number and sets it as its address. It then
starts transmitting this random address to the atmega, which has a fixed
address. the winning master (the one with the highest address) gets
through. It then goes to slave mode and stops transmitting. the
remaining masters continue like this until all have transmitted their
address. the atmega then switches to master mode and sends a init
command to all detected slaves. If a slave (attiny) does not respond, a
timeout needs to be triggered on the master and the slave, chaning the
transmission direction and having the attiny re-transmit its address.
The problems I see is in how to detect which attiny wins the master
battle, especially if two have the same random address. I know that
something similar is done in a bluetooth network to detect the devices.
I do not need this to be very fast.
Hey DedeHai,
could you use 4 Pins of the ATMega for an multiplexing system?
If you use 1 Pin as an "Slave Select" and every slave get the same
startup adress, u can count up the multiplexer and activate the
i2c-interface from the slave by multiplexer-state. After that, you send
a new adress over the bus, and the selected slave send an acknowledge.
If the master dont get that, the selected slot is unused.
hi DedeHai
your idea sounds like the method as the methode of the old token ring
technology. the battle about a possible new master should only occur,
if the existing master disappears. a new member of the cluster should
act as a slave, even if the "ID" - whatever this is - is designated for
a master role.
it was - and it is still - a big disaster, if two members of a network
have the same address.
kind regards
hans
Thanks for your answers.
@Sepp:
It certainly would be an elegant way, but the bus is represented by
cables between the devices. It would mean that instead of using a 3
conductor cable (and plug) I would have to use 4 more conductors for the
"select" signals.
@hans
As far as I understand the I2C protocol, a device can only pull the bus
lines to low, so a 0 always overwrites a 1 if two masters transmit at
the same time. so the one sending more zeroes will win the battle. The
hardware of the attiny24 has a data collision flag which is set when the
transmitted bit and the actual pin status are not the same. Like this it
should be possible to do what I want. But you are right about the
problem with two identical addresses.
Here are a few additional thoughts to that:
-another random number is generated (by reading a floating analog
input), representing a delay cycle. Each attiny waits until the delay is
up, then tries to transmit its address to the master. if a "start
condition" (meaning another device is using the bus) occurred during the
wait cycle (generates an interrupt) the device waits until a stop
condition occurs, then continues with the wait cycle. like this, the
risk of undetected data collisions can be minimized and two devices with
the same address can potentially be detected. however it is still
possible that two devices get the same addreass and the same delay time,
resulting again in an undetected slave.
-once the atmega has detected the slaves, their addresses can be stored
in eeprom, at the next startup a check byte can be sent out to all
slaves, if a slave does not get the check byte it will transmitt it's
address after this status check.
-To decrease the risk of having two slaves with the same address, 10
random bytes could be sent by each attiny, resulting in 80 random bits
that would have to be exactly the same on two (or more) attinys or a
collision could be detected, so the attiny then can detect that another
device (with the same address) is using the bus and then change its
address again. The more random bytes transmitted, the lower the risk of
having multiple devices with the same address. The downside with this is
that it uses up more time and you never can be 100% sure.
Any good ideas on how to make 100% sure two slaves do not have the same
address?
Why do you need 7? you only need 4 Wires for I2C, ChipSelect and GND.
Just the ATMEGA need 4 extra wires for controll the multiplexer IC, for
example the 74154N. Then the slaves just have to check this one wire to
activate there I2C inteface with the startup adress, and get a new
adress from the mega. After that, the mega count up the adress and the
multiplexer and write the next one to the tinys. No random adresses, and
you can store the slave adresses in the flash of the mega.
In the other case, deactivate the i2c interface and use the lines in I/O
state. Every slave try to pull down the data line first(after your
random time). To check up that the winning slave is the only one, they
read the clock line and pull it down after that. Then the mega goes in
master state and the slave use an standard adress. The master (mega)
send an new adress. After a while, the other slave wake up and retry.
But, for me, its realy undefined and tricky to use such a solution.