I2C device discovery

I wrote a program for the Arduino to discover I2C deviced on the I2C bus.
The sketch is below the example of the output:

GAW_I2C_Discovery program

Scanning for I2C devices................................................................

------- I2C Device Table ----------
    0 1 2 3 4 5 6 7 8 9 A B C D E F 
0 : - - - - - - - - - - - - - - - - 
1 : - - - - - - - - - - - - - - - - 
2 : - X - X - - - - - - - - - - - - 
3 : - - - - - - - - - - - - - - - - 
4 : - - - - - - - - - - - - - - - - 
5 : - - - - - - - - - - - - - - - - 
6 : - - - - - - - - - - - - - - - - 
7 : - - - - - - - - - - - - - - - - 

'-' indicates: no device found at that address
'X' indicates: a device was found at that address

GAW_I2C_Discovery program ends
// ------------------------------------------------------------------------
// Program  : GAW_I2C_Discovery.ino
// Author   : Gerard Wassink
// Date     : July 2020
//
// Function : Discover addresses where an I2C device is found
//
// ------------------------------------------------------------------------
//            GNU LICENSE CONDITIONS
// ------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
// ------------------------------------------------------------------------
//        Copyright (C) 2020 Gerard Wassink
// ------------------------------------------------------------------------

#include <Wire.h>

#define MYLED LED_BUILTIN

void setup() {  

  int scan_error = 0;
  int addr = 0;
  int row = 0;
  int col = 0;
  
  char devices[16][16];
  char buf[80];
  
  Serial.begin(9600);                       // Start talkin'
  Serial.println("GAW_I2C_Discovery program");
  Serial.println();

  pinMode(MYLED, OUTPUT);                   // Built_in LED flashes for every address scanned
  
  Wire.begin();

// ------------------------------------------------------------------------
//                                    Check for the presence of I2C devices
//                                          and store the result in a table
// ------------------------------------------------------------------------
  Serial.print("Scanning for I2C devices");
  for (addr=0; addr<128; addr++) {          // loop through all 128 addresses
    row = addr / 16;
    col = (addr - (row * 16));
    Wire.beginTransmission(addr);           // probe device at address
    scan_error = Wire.endTransmission();    // do we get an error?
    if (scan_error == 0) {                  // no error
      devices[row][col] = 'X';
    } else {
      devices[row][col] = '-';
    }
    if ( ((addr/2)*2) == addr ) {
      Serial.print(".");
    }

    delay(5);                              // Flash the LED
    digitalWrite(MYLED, HIGH);              //  per address
    delay(5);                              //    to indicate
    digitalWrite(MYLED, LOW);               //      the program is still going
  }
  Serial.println();
  Serial.println();
  
// ------------------------------------------------------------------------
//                                            Print the header of the table
// ------------------------------------------------------------------------
  Serial.println("------- I2C Device Table ----------");
  Serial.print("    ");
  for (int i=0; i<16; i++) {
    if (i < 10) {
      Serial.print(toAscii(i));
      Serial.print(" ");
    } else {
      Serial.print(char('A' + (i-10)));
      Serial.print(" ");
    }
  }
  Serial.println();
    
// ------------------------------------------------------------------------
//                                                 Print the table contents
// ------------------------------------------------------------------------
  for (row=0; row<8; row++) {
    Serial.print(row);
    Serial.print(" : ");
    for (col=0; col<16; col++) {
      Serial.print(devices[row][col]);
      Serial.print(" ");
    }
    Serial.println();
  }
  Serial.println();
  
  Serial.println("'-' indicates: no device found at that address");
  Serial.println("'X' indicates: a device was found at that address");
  Serial.println();
  
// ------------------------------------------------------------------------
//     Give Serial the opportunity to finish it's job, then End the program
// ------------------------------------------------------------------------
  
  Serial.println("GAW_I2C_Discovery program ends");
  Serial.println();

  delay(100);
  exit(0);

}

// Read pins and display values
void loop() {
  // nothing to do here
}

Hi,

What advantages does your code have over the standard "i2c scanner" sketch?

PaulRB:
Hi,

What advantages does your code have over the standard "i2c scanner" sketch?

Hi, good question:

  • The form-factor looks like a program that I used on the Raspberry pi
  • It's output is way shorter and more neat then the 'standard I2C scanner'
  • I learned something instead of re-using ready made stuff

Gerard

PS: I will make the code more compact in a future version.