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:
Concepts: HEX vales, I2C communication, Wire library
Circuits:
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).");
#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).");