I2C - Broadcast to find Slaves present on Bus

Hello,

Basically as the title suggests, I am trying to determine if sending a broadcast on i2c (as described how to do it on Nick Gammons website) will be suitable to determine which slaves are present on the Bus, so I can then disables sections of code so they are not processed due to the slave not being present and therefore not relevant.

This message was sent to Nick directly over PM, however as he mentioned in his reply, it is more suitable for the forum so learning is captured for all.

@Nick - you mentioned something about an I2C Scanner, also on your website. I will try and find that and have a read. I was under the impression that if a slave device is not present on the bus, then the master would be blocked as it would be waiting constantly for a slave to reply, and there is no timeout in the library? I thought this was the case anyway, however it may all be false.

Like what you said in the PM, sending out something on this Scanner to requres the 'type' or something similar from the slaves, and each slave will reply saying "Im an ADC board" or whatever, then that would be very very handy indeed. I could do all sorts of things with a reference list of slaves and their function.... hmmm the possibilities.

Regards James

Here is the scanner, there are others by other authors:

// I2C Scanner
// Written by Nick Gammon
// Date: 20th April 2011

#include <Wire.h>

void setup() {
  Serial.begin (115200);
  Serial.println ();
  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;
  
  Wire.begin();
  for (byte i = 1; i < 120; i++)
  {
    Wire.beginTransmission (i);
    if (Wire.endTransmission () == 0)
      {
      Serial.print ("Found address: ");
      Serial.print (i, DEC);
      Serial.print (" (0x");
      Serial.print (i, HEX);
      Serial.println (")");
      count++;
      } // end of good response
     delay (5);  // give devices time to recover
  } // end of for loop
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");
}  // end of setup

void loop() {}

I was under the impression that if a slave device is not present on the bus, then the master would be blocked as it would be waiting constantly for a slave to reply, and there is no timeout in the library?

Not at all. There is a small period after each byte is transmitted when the master waits for the slave to pull the SDA line low (the documentation is a bit unclear how long that is, but I read it to be one bit-length). If there is no slave at that address there is nothing to pull the line low, and thus a NAK (negative acknowledge) is effectively generated.

A quick test shows that the scanner completed in 135 mS (if I turned the delay in the code down from 5 to 1). Thus basically the time was almost all spent in the delay routine. If you get rid of the delay altogether it finishes in 15 mS. I don’t know if the delay is needed, I put it there for safety. In any case even with a 5 mS delay the whole scan is over in half a second.

Just run the test on a “bare” Arduino and you will see that it completes quickly.

You are the man, thank you very much.

That is going to be extremely useful.

I will post a new topic with my project this evening if I get time, with pictures etc of each of the boards made so far. You will soon see the relevance this scanner code will have on the project. I had no idea I2C was capable of doing this, it is great.

Thanks again

James

Bonjour Nick,

Thank you for sharing this nice and compact sketch.

I was using something complicated: this is far more elegant :)

Best regards,

There is a small period after each byte is transmitted when the master waits for the slave to pull the SDA line low (the documentation is a bit unclear how long that is, but I read it to be one bit-length).

The slave device has to pull the SDA line low on the ninth SCL clock cycle or it generates the NAK.

Nick...nice sketch.

Sketch works great. After increasing my I2C bus speed to 400 from the standard 100, I had issues with my DS1307. Looking at the datasheet it states the max I2C speed it supports is 100, which is a little annoying. I couldnt see the device on the bus using this code and it got me doubting my circuit, however there isnt much that can really go wrong with the circuit to this chip. Changed bus back to 100 however problem remains. I must have a bad chip. Very handy to diagnose problems though, as its plain to see what is talking and what isnt.

I have put a slightly modified version of this in the setup routine of my project, which prints to the serial port on startup. Works a treat, and with the Adum1250ARZ isolation/Hot Swap I2C chips I have on each board, I can plug and unplug boards on the fly, and it all runs smooth as silk.

Thanks again James

WanaGo: After increasing my I2C bus speed to 400 from the standard 100, I had issues with my DS1307. Looking at the datasheet it states the max I2C speed it supports is 100, which is a little annoying. I couldnt see the device on the bus using this code and it got me doubting my circuit, however there isnt much that can really go wrong with the circuit to this chip. Changed bus back to 100 however problem remains. I must have a bad chip.

Why a bad chip, if it only claims to support 100? Anyway, check your pull-up resistors. You can see from the oscilloscope screenshots on my web site page that something like a 4.7K resistor is needed to get a nice sharp edge on the clock and data lines.

Hi Nick

Neither 100 or 400 worked, the device isnt showing up on the scanner at all.

Pullups are fine, they are 1.5k. I was going to use 2.2k's however I didnt have any in my box of bits. I also have an EEPROM on the same board and that works perfectly fine, and the processor doing the scanning is on this board too. I have had this chip working on another board, however that board was disassembled to make this new revision. I may have cooked it somehow, or damaged the crystal maybe... I have a spare so I will try that tonight.

1.5k pull ups seems to work correctly over 6 boards, each with the isolation chips on them. I can only guess some part of the DS1307 or crystal are not working. I have checked the connections, no dry joints etc and wiring is correct.

Cheers James

Hi Dear I am working on communication between arduino boards one of them is master and others are slaves so we have to transmit clock data read by master fron ds1307 and transmit to slave device through i2c bus so please help me to creating code for this communication.

what is broadcast device? How it works?

A broadcast is a signal that when set on the I2C bus triggers all devices on the bus to give some signal back.

It is like yelling in a room "anybody here?"

And that everyone yells back "I am"

I run this code to find my PCA9685, but the code didn't return anything!

Does than mean my chip is broken?