Learn Arduino with Olympia Circuits
Learn Arduino
  • Home
    • Get Started
    • How to Use This Site
  • Electronics
    • The Basics
    • Electricity Flows like Water
    • Electronic Components
    • The Arno Board
  • Programming
    • The Basics
    • setup and loop Blocks
    • Variables and Arrays
    • Connecting with the Pins
    • Flow Control >
      • if Statement
      • Loops
      • Delays
    • Functions
    • Serial Communication
    • USB
    • Some Thoughts
  • Projects
    • Projects 1 >
      • 1.01: Blink
      • 1.02 Blink x2
      • 1.03 Blink Faster
      • 1.04 LED Chase!
      • 1.05 Wait To Blink
      • 1.06 Blink a Little Faster Now
      • 1.07 LED Fade
      • 1.08 RGB Blink
      • 1.09 Change RGB Color with SW1
      • 1.10 Fade RGB Colors
      • 1.11 Reaction Time Game
    • Projects 2 >
      • 2.01 Hello World
      • 2.02 Talk Back
      • 2.03 ASCII Values
      • 2.04 Ski Game
      • 2.05 Demonstration of the String Object
    • Projects 3 >
      • 3.01 Read the Potentiometer
      • 3.02 ASCIIbet Soup
      • 3.03 Potentiometer sets LED Brightness
      • 3.04 Potentiometer Sets Blink Rate
      • 3.05 LED Chase, Part II
    • Projects 4 >
      • 4.01 Bringing the Piezo to Life
      • 4.02 Controlling the Piezo with a Function
      • 4.03 Piezo C Major
      • 4.04 Piezo Greensleaves
      • 4.05 Piezo Metronome
      • 4.06 Piezo as an Input
      • 4.07 Piezo as an Input 2
      • 4.08 Metronome II
      • 4.09 Piezo Playback
      • 4.10 Piezo Fireworks
      • 4.11 Piezo Mosquito
    • Projects 5 >
      • 5.01 The Phototransistor
      • 5.02 Light and Sound
      • 5.03 Light and Sound II
    • Projects 6 >
      • 6.01 EEPROM
      • 6.02 I2C Address Scan
      • 6.03 Read the I2C Temperature Sensor
      • 6.04 High Temperature Alarm
    • Projects 7 >
      • 7.01 Arno Phone Home
      • 7.02 Keyboard Alphabet
      • 7.03 Move Mouse
      • 7.04 Draw Squares
    • Special Projects >
      • Bike Light Demo
  • References
    • Arno Pin Key
    • Arno Schematic
    • Project Index

Project 6.02: I2C Address Scan

I2C is a protocol that allows integrated circuits (ICs) to communicate with one another.  Multiple ICs can be connected to a single bus as long as they have different addresses.  In this project, we go through the list of possible addresses (1 through 120) to see when the temperature sensor IC on the Arno board responds.  This sketch is useful when you create your own circuits to check that the ICs on the I2C bus are working properly.  Upload the project to the Arno, open the serial monitor, and then press SW1 to see the results.

Concepts: HEX  vales, I2C communication, Wire library

Circuits:
  • Circuit 2
  • Circuit 8


  • Select Sketch

    ///////////////////////////////////////////////////
    //Project I2C Address Scan
    int count = 0;
    int SW1 = 1;
    void setup() {
    Serial.begin (9600);
    Wire.begin();
    pinMode(SW1,INPUT);
    }
    void loop(){
    Serial.println(Press SW1 to scan.);
    while(digitalRead(SW1)==HIGH){
    }
    count = 0;
    //loop through possible addresses
    for (int i = 1; i < 120; i++)
    {
    Wire.beginTransmission (i);
    //returns 0 if device found
    if (Wire.endTransmission () == 0)
    {
    Serial.print (Adsress Found: );
    Serial.println (i);
    Serial.print ( (0x);
    Serial.print (i, HEX);
    Serial.println ());
    count++;
    }
    delay (5);
    } // end of for loop
    Serial.println (Done.);
    Serial.print (Found );
    Serial.print (count);
    Serial.println ( device(s).);
    }
    ///////////////////////////////////////////////////

    At the beginning of the program, we tell the compiler to include the Wire library, which brings in I2C capabilities:

    #include <Wire.h>

    The wire library doesn’t automatically create an instance of the Wire class, so we create one in the setup() block:

      Wire.begin();

    On entering the loop() block we wait until SW1 is pressed:

      Serial.println("Press SW1 to scan.");

      while(digitalRead(SW1)==HIGH){

      }

    Once SW1 is pressed, we reset the variable count to begin counting how many devices respond on the I2C bus:

      count = 0;

    Next, we enter a loop to go through possible addresses:

      //loop through possible addresses

      for (int i = 1; i < 120; i++)

      {

    We query the I2C bus using the wire.beginTransmission function.  The function’s argument is the I2C address:

    Wire.beginTransmission (i);

    If there’s an I2C device with the address on the bus, it will respond with an acknowledgement bit.  The wire.endTransmission returns a value of 0 if an acknowledgement bit was received. It returns a different value if an error occurred.

        if (Wire.endTransmission () == 0)

        {

    When we get a response, we print the address to the serial monitor:

          Serial.print ("Address Found: ");

          Serial.println (i);

    In many cases, the datasheet for an I2C device will give its address as a hexadecimal number.  The hexadecimal system is a base-16 number system, versus the typical base-10 system.  In the hexadecimal system, we count up to 16 before moving into the next digit (the 16 digits are 0 – 9 then a, b, c, d, e, and f). Hexadecimal numbers are often written with the prefix ‘0x’.  We use the HEX argument is the Serial.print command to output the hexadecimal value of i.

    Serial.print (" (0x");

          Serial.print (i, HEX);

          Serial.println (")");

    We finish the if block by incrementing count since we found a device on the bus:

          count++;

        }

    After looping through all possible addresses, we send our report to the serial monitor:

      Serial.println ("Done.");

      Serial.print ("Found ");

      Serial.print (count);

      Serial.println (" device(s).");

    Back to Projects 6

    Copyright Olympia Circuits LLC 2014. All Rights Reserved.