Bird
0
0
Arduinoprogramming~20 mins

I2C scanner sketch in Arduino - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
🎖️
I2C Scanner Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
Predict Output
intermediate
2:00remaining
What is the output of this I2C scanner sketch?
Consider this Arduino I2C scanner sketch. What will it print to the Serial Monitor when no I2C devices are connected?
Arduino
#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial);
  Serial.println("I2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices = 0;

  Serial.println("Scanning...");

  for(address = 1; address < 127; address++ ) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
      nDevices++;
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);
}
A
I2C Scanner
Scanning...
No I2C devices found
B
I2C Scanner
Scanning...
I2C device found at address 0x00  !
done
C
I2C Scanner
Scanning...
I2C device found at address 0x7F  !
done
D
I2C Scanner
Scanning...
Error: Bus busy
Attempts:
2 left
💡 Hint
Think about what happens when no devices respond to the I2C address scan.
Predict Output
intermediate
2:00remaining
What is the output if a device is connected at address 0x3C?
Using the same I2C scanner sketch, what will the Serial Monitor show if a device is connected at address 0x3C?
Arduino
#include <Wire.h>

void setup() {
  Wire.begin();
  Serial.begin(9600);
  while (!Serial);
  Serial.println("I2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices = 0;

  Serial.println("Scanning...");

  for(address = 1; address < 127; address++ ) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0) {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
      nDevices++;
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);
}
A
I2C Scanner
Scanning...
I2C device found at address 0x03  !
done
B
I2C Scanner
Scanning...
I2C device found at address 0x3C  !
done
C
I2C Scanner
Scanning...
No I2C devices found
D
I2C Scanner
Scanning...
I2C device found at address 0x7E  !
done
Attempts:
2 left
💡 Hint
Check the address range and how the address is printed in hexadecimal.
🧠 Conceptual
advanced
2:00remaining
Why does the scanner skip address 0x00 and 0x7F?
In the I2C scanner sketch, the for loop scans addresses from 1 to 126. Why does it skip 0x00 and 0x7F?
ABecause 0x00 and 0x7F are broadcast addresses that always respond with an error.
BBecause 0x00 and 0x7F are invalid addresses that cause the Arduino to reset.
CBecause 0x00 is the general call address and 0x7F is reserved for future use, so scanning them can cause errors or unexpected behavior.
DBecause 0x00 and 0x7F are used for SPI communication, not I2C.
Attempts:
2 left
💡 Hint
Think about special reserved addresses in the I2C protocol.
🔧 Debug
advanced
2:00remaining
What error does this modified I2C scanner code produce?
This code snippet is a modified I2C scanner. What error will it cause when compiled or run? #include void setup() { Wire.begin(); Serial.begin(9600); Serial.println("I2C Scanner"); } void loop() { byte error, address; int nDevices = 0; Serial.println("Scanning..."); for(address = 0; address <= 127; address++) { Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("Device at 0x"); Serial.println(address, HEX); nDevices++; } } delay(5000); }
ACompilation error: 'address' variable overflow due to using byte type with 0 to 127 range
BRuntime error: Wire.endTransmission() returns unexpected error for address 0 and 127
CCompilation error: missing semicolon after Serial.println statement
DNo error, but scanning address 0 and 127 may cause unexpected device responses
Attempts:
2 left
💡 Hint
Check the address range and the data type used for address variable.
🚀 Application
expert
3:00remaining
How to modify the I2C scanner to detect multiple devices and print their addresses in ascending order?
You want to modify the I2C scanner sketch to store all found device addresses in an array and then print them sorted ascending after scanning completes. Which code snippet correctly implements this?
A
byte devices[127]; int count = 0;
for(byte address=1; address&lt;127; address++) {
  Wire.beginTransmission(address);
  if(Wire.endTransmission() == 0) {
    devices[count++] = address;
  }
}
for(int i=0; i&lt;count-1; i++) {
  for(int j=i+1; j&lt;count; j++) {
    if(devices[j] &lt; devices[i]) {
      byte temp = devices[i]; devices[i] = devices[j]; devices[j] = temp;
    }
  }
}
for(int i=0; i&lt;count; i++) {
  Serial.print("0x"); Serial.println(devices[i], HEX);
}
B
byte devices[127]; int count = 0;
int compare(const void *a, const void *b) {
  return (*(byte*)a - *(byte*)b);
}
for(byte address=1; address&lt;127; address++) {
  Wire.beginTransmission(address);
  if(Wire.endTransmission() == 0) {
    devices[count++] = address;
  }
}
qsort(devices, count, sizeof(byte), compare);
for(int i=0; i&lt;count; i++) {
  Serial.print("0x"); Serial.println(devices[i], HEX);
}
C
byte devices[127]; int count = 0;
for(byte address=1; address&lt;127; address++) {
  Wire.beginTransmission(address);
  if(Wire.endTransmission() == 0) {
    devices[count++] = address;
  }
}
for(int i=0; i&lt;count; i++) {
  Serial.print("0x"); Serial.println(devices[i], HEX);
}
// No sorting
D
byte devices[127]; int count = 0;
for(byte address=1; address&lt;127; address++) {
  Wire.beginTransmission(address);
  if(Wire.endTransmission() == 0) {
    devices[count++] = address;
  }
}
std::sort(devices, devices + count);
for(int i=0; i&lt;count; i++) {
  Serial.print("0x"); Serial.println(devices[i], HEX);
}
Attempts:
2 left
💡 Hint
Arduino C++ does not support std::sort by default. qsort requires a function declared before use.