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.
Also quite simple: Programm an software SPI, and switch after sending the adresses to I2C.