Bird
Raised Fist0
Arduinoprogramming~20 mins

I2C scanner sketch in Arduino - Practice Problems & Coding Challenges

Choose your learning style10 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.

Practice

(1/5)
1. What is the main purpose of an I2C scanner sketch in Arduino programming?
easy
A. To reset the Arduino board automatically
B. To detect and list all devices connected on the I2C bus
C. To send data to all I2C devices simultaneously
D. To measure voltage levels on the I2C pins

Solution

  1. Step 1: Understand the role of I2C scanner

    An I2C scanner checks each possible address on the I2C bus to find connected devices.
  2. Step 2: Identify the main function

    The main function is to detect and list all devices so you know which addresses are in use.
  3. Final Answer:

    To detect and list all devices connected on the I2C bus -> Option B
  4. Quick Check:

    I2C scanner = device finder [OK]
Hint: I2C scanner finds devices by checking addresses [OK]
Common Mistakes:
  • Thinking it sends data to devices
  • Confusing it with board reset functions
  • Assuming it measures electrical signals
2. Which of the following is the correct way to start the I2C communication in an Arduino I2C scanner sketch?
easy
A. Wire.begin();
B. Wire.start();
C. Wire.init();
D. Wire.connect();

Solution

  1. Step 1: Recall the Wire library initialization

    The Wire library uses Wire.begin(); to start I2C communication.
  2. Step 2: Check other options

    Functions like Wire.start();, Wire.init();, and Wire.connect(); do not exist in the Wire library.
  3. Final Answer:

    Wire.begin(); -> Option A
  4. Quick Check:

    Start I2C with Wire.begin() [OK]
Hint: Use Wire.begin() to start I2C communication [OK]
Common Mistakes:
  • Using non-existent Wire functions
  • Confusing with other library methods
  • Omitting Wire.begin() causing no communication
3. Consider this snippet from an I2C scanner sketch:
for (byte address = 1; address < 127; address++) {
  Wire.beginTransmission(address);
  byte error = Wire.endTransmission();
  if (error == 0) {
    Serial.print("Device found at 0x");
    Serial.println(address, HEX);
  }
}

What will this code print if devices are found at addresses 8 and 42?
medium
A. Device found at 0x8\nDevice found at 0x2A
B. Device found at 0x08\nDevice found at 0x2A
C. Device found at 0x08\nDevice found at 0x42
D. Device found at 0x8\nDevice found at 0x42

Solution

  1. Step 1: Understand the address printing format

    The code prints the address in hexadecimal using Serial.println(address, HEX);. Hex 8 is '8', hex 42 decimal is '2A'.
  2. Step 2: Check leading zeros

    Since Serial.println() with HEX does not pad zeros, 8 prints as '8', 42 prints as '2A'.
  3. Final Answer:

    Device found at 0x8\nDevice found at 0x2A -> Option A
  4. Quick Check:

    Hex 8 = 8, Hex 42 = 2A [OK]
Hint: Hex print does not add leading zeros by default [OK]
Common Mistakes:
  • Assuming leading zeros appear automatically
  • Confusing decimal 42 with hex 42
  • Expecting uppercase letters always
4. You wrote this I2C scanner code but it never finds any devices:
for (byte address = 0; address <= 127; address++) {
  Wire.beginTransmission(address);
  byte error = Wire.endTransmission();
  if (error == 0) {
    Serial.print("Found device at ");
    Serial.println(address, HEX);
  }
}

What is the likely problem?
medium
A. Wire.endTransmission() must be called twice
B. Address 0 is reserved and should not be scanned
C. The loop should start from 1, not 0
D. Serial.print() cannot print HEX values

Solution

  1. Step 1: Check the address range in the loop

    The I2C valid addresses range from 1 to 127. Starting at 0 is invalid and may cause issues.
  2. Step 2: Understand scanning addresses

    Starting from 1 avoids reserved addresses and ensures proper scanning.
  3. Final Answer:

    The loop should start from 1, not 0 -> Option C
  4. Quick Check:

    Scan addresses 1 to 127 [OK]
Hint: Start scanning from address 1, not 0 [OK]
Common Mistakes:
  • Including address 0 which is reserved
  • Calling Wire.endTransmission() multiple times unnecessarily
  • Thinking Serial.print() can't print HEX
5. You want to modify an I2C scanner sketch to skip addresses where Wire.endTransmission() returns 4 (other error) and print a summary count of devices found at the end. Which code snippet correctly implements this?
hard
A. int count = 0; for (byte addr = 1; addr < 128; addr++) { Wire.beginTransmission(addr); byte error = Wire.endTransmission(); if (error == 0) { Serial.print("Device at 0x"); Serial.println(addr, HEX); count++; } else if (error == 4) { count--; } } Serial.print("Total devices: "); Serial.println(count);
B. int count = 0; for (byte addr = 0; addr <= 127; addr++) { Wire.beginTransmission(addr); byte error = Wire.endTransmission(); if (error == 0) { Serial.print("Device at 0x"); Serial.println(addr, HEX); count++; } else if (error == 4) { break; } } Serial.print("Total devices: "); Serial.println(count);
C. int count = 0; for (byte addr = 1; addr < 127; addr++) { Wire.beginTransmission(addr); byte error = Wire.endTransmission(); if (error == 0) { Serial.print("Device at 0x"); Serial.println(addr, HEX); count++; } else if (error == 4) { Serial.println("Error 4 at address " + addr); } } Serial.print("Total devices: "); Serial.println(count);
D. int count = 0; for (byte addr = 1; addr < 127; addr++) { Wire.beginTransmission(addr); byte error = Wire.endTransmission(); if (error == 0) { Serial.print("Device at 0x"); Serial.println(addr, HEX); count++; } else if (error == 4) { continue; } } Serial.print("Total devices: "); Serial.println(count);

Solution

  1. Step 1: Set correct address range and initialize count

    The loop must scan addresses 1 to 126 (less than 127). Initialize count to zero before loop.
  2. Step 2: Handle error 4 by skipping and count devices found

    If error is 0, print address and increment count. If error is 4, skip with continue to avoid stopping the scan.
  3. Step 3: Print total devices after loop

    After scanning, print the total count of devices found.
  4. Final Answer:

    Code snippet A correctly implements the requirements -> Option D
  5. Quick Check:

    Skip error 4 with continue, count devices [OK]
Hint: Use continue to skip error 4 and count devices found [OK]
Common Mistakes:
  • Using break instead of continue on error 4
  • Starting loop at 0 instead of 1
  • Decreasing count on error instead of skipping
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard