I2C Port Scan code not responding as expected


#1

Hey @Eric hope you’re doing well. Had a quick question.

I’m working with a customer and he has a Bluz module installed in one of our products. He was having some trouble so I wanted to have him run some I2C port scan code to make sure the I2C IC on our board was being properly recognized by the Bluz module. He and I are both seeing the same results with the I2C scan code though. It seems Wire.endTransmission() is always returning 0 even if no I2C device is present. The industry standard for I2C general call allows the application to run code like this to determine what devices are present on the I2C bus:

unsigned long scanInterval = 10000;
unsigned long lastScan;

void setup() {
    Wire.begin(); 
}

void loop() {
    //Required for Bluz
    System.sleep(SLEEP_MODE_CPU);
    
    //Only scan I2C port every 10 seconds
    if(millis() > lastScan + scanInterval){
        lastScan = millis();
        bool devicesFound = false;
        //Create string to hold information to be published to Particle event.
        String newDevices = "Devices at: ";
        //Step through all 127 possible I2C addresses to scan for devices on the I2C bus.
        for(int i = 1; i < 128; i++){
            //Make a general call to device at the current address to see if anything responds.
            Wire.beginTransmission(i);
            byte status = Wire.endTransmission();
            if(status == 0){
                //Device found so append it to our device list event string
                newDevices.concat(i);
                newDevices.concat(", ");
                devicesFound = true;
            }
        
        }
        if(devicesFound){
            //Serial.println(newDevices);
            Particle.publish("New Devices", newDevices);
        }else{
            //Serial.println("No Devices Found");
            Particle.publish("New Devices", "No Devices Found");
        }
    }
} 

This code does run correctly on a Photon but not on Bluz. Wire.endTransmission() always returns 0 which it should not if no device is present. Do you have any sort of work around for this?


#2

Looking quickly at our code and the Nordic I2C driver, it seems that end_transmision() won’t do much if there are no bytes to send. So could you send a byte to the device? That should allow us to then return an error code. Otherwise end_transmission() function probably won’t detect an error since it doesn’t send anything.


#3

Hi @Eric

Yeah, I can write a 0 before ending the transmission. Only issue with that is there may be I2C devices out there which respond to that as a command. None are coming to mind, but certainly possible.

I’ll give that a try and let you know.

Thanks,
Travis