Few definitions/ protocols of TWI Bus (aka I2C Bus) are:
1. Who is a Master?
The device that acquire TWI Bus by bring START and STOP conditions on the bus; it also generates SCL (clock) pulses to shift-in/shift-out data into/from a Slave.
2. What is an Active Slave?
It is a Slave device having capability of becoming a Master if necessary) as described in Step-1. An MCU like UNO can become an active Slave. Sensors/devices like MPU6050/24C512 are passive slaves.
3. Can two passive slaves work together without a Master?
No.
4. Can two active slaves work together with a Master?
Yes! One or both slaves can become a Master.
5. In what sense the Wire.requestFrom(arg1, arg2) is a looping/waiting/polling instruction?
During the execution if this instruction, the Master keeps waiting (stretches the SCL pulse) to receive the ACK signal from the Slave. After receiving the ACK signal, the Master generates as many SCL pulses as needed (determined by arg2) to read data bytes from the queued buffer of the Slave. The Master saves the received data bytes into a 32-byte wide FIFO type buffer. If the Slave has queued 2 bytes data and the arg2=3, the last data byte is meaningless.
In case the Slave fails to generate ACK signal, the Master will enter into endless loop from which only the Watchdog Timer or user defined timeout logic could bring it out.
bool i2cReady(uint8_t adr)
{
uint32_t timeout = millis();
bool ready = false;
while((millis() - timeout < 100) && (!ready) //100 ms timeout logic
{
Wire.beginTransmission(adr);
byte busStatus = Wire.endTransmission();
ready = (busStatus == 0x00)? true : false;
}
return ready;
}
6. In TWI Bus, it is very unlikely that a bus contention could happen resulting the loss of message. It is because every Master is required to acquire the Bus first and then begin communication. The bus ownership is achieved by making a Roll Call of the desired Slave and then checking the busStatus for 0x00.
do
{
Wire.beginTransmission(slaveAddress);
byte busStatus = Wire.endTransmission():
}
while (busStatus != 0x00);
Serial.println(busStatus);