Bird
Raised Fist0
Arduinoprogramming~10 mins

I2C scanner sketch in Arduino - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - I2C scanner sketch
Start setup
↓
Initialize I2C bus
↓
For each address 1 to 127
↓
Try to communicate
↓
Print address
↓
Next address
↓
End loop
↓
Print done
The sketch initializes the I2C bus, then tries to communicate with each possible device address from 1 to 127. If a device responds, it prints the address. After checking all, it prints done.
Execution Sample
Arduino
void setup() {
  Wire.begin();
  Serial.begin(9600);
  for (byte address = 1; address < 128; address++) {
    Wire.beginTransmission(address);
    byte error = Wire.endTransmission();
    if (error == 0) {
      Serial.println(address);
    }
  }
  Serial.println("Done");
}

void loop() {
  // Empty loop
}
This code scans all I2C addresses and prints those where a device responds.
Execution Table
StepAddressWire.beginTransmission(address)Wire.endTransmission() resultCondition (error==0)ActionOutput
11Start transmission to 1No device (error=4)FalseNo print
22Start transmission to 2No device (error=4)FalseNo print
33Start transmission to 3Device found (error=0)TruePrint address3
44Start transmission to 4No device (error=4)FalseNo print
.....................
126126Start transmission to 126No device (error=4)FalseNo print
127127Start transmission to 127No device (error=4)FalseNo print
128End loop---Print "Done"Done
💡 Loop ends after checking address 127; 'Done' printed to signal completion.
Variable Tracker
VariableStartAfter 1After 2After 3...After 127Final
addressN/A123...127Loop ends
errorN/A440...4N/A
Key Moments - 3 Insights
Why do we start scanning from address 1 and not 0?
Address 0 is reserved for general call in I2C, so scanning starts from 1 as shown in execution_table rows 1 and 2.
What does error code 0 mean in Wire.endTransmission()?
Error 0 means a device acknowledged the address, so the condition error==0 is true and the address is printed (see execution_table row 3).
Why do we print 'Done' after the loop?
'Done' signals the scan finished checking all addresses, as shown in the last row of execution_table.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the error code when a device is found at address 3?
A4
B1
C0
D255
💡 Hint
Check the 'Wire.endTransmission() result' column at step 3 in execution_table.
At which address does the loop stop scanning?
A126
B127
C128
D1
💡 Hint
Look at the 'address' variable in variable_tracker and the last rows in execution_table.
If a device responded at address 5, what would happen in the execution_table?
Aerror would be 0 and address 5 would be printed
Berror would be 4 and no print
Cloop would stop immediately
Daddress 5 would be skipped
💡 Hint
Refer to how address 3 is handled in execution_table row 3.
Concept Snapshot
I2C Scanner Sketch
- Initialize I2C bus with Wire.begin()
- Loop addresses 1 to 127
- Use Wire.beginTransmission(address) and Wire.endTransmission()
- If endTransmission returns 0, device found
- Print found address
- Print 'Done' after scanning all
Useful to detect connected I2C devices.
Full Transcript
This I2C scanner sketch starts by initializing the I2C bus and serial communication. It then loops through all possible I2C addresses from 1 to 127. For each address, it tries to start a transmission and ends it to check if a device responds. If the response error code is 0, it prints the address to the serial monitor. After checking all addresses, it prints 'Done' to signal the scan is complete. This helps find which devices are connected on the I2C bus.

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