Bird
Raised Fist0
Arduinoprogramming~20 mins

Reading I2C sensor data in Arduino - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
I2C Sensor 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 sensor reading code?

Consider this Arduino code snippet that reads a byte from an I2C sensor at address 0x40. What will be printed on the Serial Monitor?

Arduino
Wire.begin();
Wire.beginTransmission(0x40);
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(0x40, 1);
int data = Wire.read();
Serial.println(data);
ACompilation error due to missing setup() and loop()
BPrints the byte value read from the sensor (e.g., 42)
CPrints 0 because Wire.read() returns 0 if no data
DRuntime error because Wire.requestFrom() is missing parameters
Attempts:
2 left
💡 Hint

Wire.requestFrom() asks the sensor for bytes, and Wire.read() reads them. The sensor returns a byte, which is printed.

🧠 Conceptual
intermediate
1:30remaining
Which I2C function initiates communication with a sensor?

In Arduino I2C communication, which function starts talking to a sensor device?

AWire.endTransmission()
BWire.requestFrom(address, quantity)
CWire.read()
DWire.beginTransmission(address)
Attempts:
2 left
💡 Hint

Think about which function tells the sensor you want to send data first.

🔧 Debug
advanced
2:30remaining
Why does this I2C sensor reading code always print -1?

Look at this Arduino code snippet. It always prints -1. Why?

Arduino
Wire.begin();
Wire.requestFrom(0x50, 1);
int val = Wire.read();
Serial.println(val);
AWire.begin() must be called inside loop() to work
BWire.read() returns -1 when the sensor address is wrong
CThe sensor was not told which register to read before requesting data
DSerial.println() cannot print integers from Wire.read()
Attempts:
2 left
💡 Hint

Think about what the sensor expects before sending data.

📝 Syntax
advanced
1:30remaining
Which option fixes the syntax error in this I2C code?

Find the option that fixes the syntax error in this Arduino I2C code snippet:

Wire.beginTransmission(0x68)
Wire.write(0x10);
Wire.endTransmission();
AAdd a semicolon after Wire.beginTransmission(0x68);
BReplace Wire.endTransmission() with Wire.endTransmission(1)
CAdd Wire.requestFrom(0x68, 1); after endTransmission()
DChange Wire.write(0x10) to Wire.write(0x10);
Attempts:
2 left
💡 Hint

Look carefully at missing punctuation in the code.

🚀 Application
expert
3:00remaining
How many bytes will be read by this I2C code snippet?

This Arduino code requests data from an I2C sensor. How many bytes will be read and printed?

Wire.beginTransmission(0x20);
Wire.write(0x01);
Wire.endTransmission();
Wire.requestFrom(0x20, 3);
while(Wire.available()) {
  Serial.print(Wire.read());
  Serial.print(",");
}
A3 bytes
B4 bytes
C0 bytes
D1 byte
Attempts:
2 left
💡 Hint

Check the number requested in Wire.requestFrom() and how many bytes are printed.

Practice

(1/5)
1. What is the main purpose of the Wire.begin() function in Arduino when reading I2C sensor data?
easy
A. To initialize the I2C communication bus
B. To read data from the sensor
C. To write data to the sensor
D. To close the I2C communication

Solution

  1. Step 1: Understand the role of Wire.begin()

    The Wire.begin() function sets up the Arduino to use the I2C bus, preparing it to communicate with I2C devices.
  2. Step 2: Differentiate from other functions

    Reading or writing data happens after initialization; Wire.begin() does not perform these actions.
  3. Final Answer:

    To initialize the I2C communication bus -> Option A
  4. Quick Check:

    Wire.begin() initializes I2C [OK]
Hint: Remember: begin() always starts communication [OK]
Common Mistakes:
  • Confusing Wire.begin() with reading or writing functions
  • Thinking Wire.begin() sends or receives data
  • Skipping Wire.begin() before communication
2. Which of the following is the correct syntax to request 2 bytes of data from an I2C device with address 0x40 using the Wire library?
easy
A. Wire.readFrom(0x40, 2);
B. Wire.request(0x40, 2);
C. Wire.requestFrom(0x40, 2);
D. Wire.getFrom(0x40, 2);

Solution

  1. Step 1: Recall the correct Wire library function

    The function to request bytes from an I2C device is Wire.requestFrom(address, quantity).
  2. Step 2: Match the syntax with the options

    Only Wire.requestFrom(0x40, 2); uses the correct function name and parameters.
  3. Final Answer:

    Wire.requestFrom(0x40, 2); -> Option C
  4. Quick Check:

    requestFrom(address, bytes) is correct [OK]
Hint: Use requestFrom() to get bytes from I2C device [OK]
Common Mistakes:
  • Using incorrect function names like request() or readFrom()
  • Mixing up parameter order
  • Forgetting to specify the number of bytes
3. Consider this Arduino code snippet reading two bytes from an I2C sensor:
Wire.requestFrom(0x50, 2);
if (Wire.available() >= 2) {
  byte highByte = Wire.read();
  byte lowByte = Wire.read();
  int value = (highByte << 8) | lowByte;
  Serial.println(value);
}
If the sensor sends bytes 0x01 and 0xF4, what will be printed?
medium
A. 500
B. 400
C. 5000
D. 256

Solution

  1. Step 1: Understand byte combination

    The code shifts the first byte (0x01) left by 8 bits and ORs it with the second byte (0xF4). This forms a 16-bit number.
  2. Step 2: Calculate the combined value

    0x01 << 8 = 0x0100 (256 decimal), 0xF4 = 244 decimal, sum = 256 + 244 = 500.
  3. Final Answer:

    500 -> Option A
  4. Quick Check:

    (0x01 << 8) + 0xF4 = 500 [OK]
Hint: Shift high byte 8 bits left, then OR with low byte [OK]
Common Mistakes:
  • Adding bytes without shifting
  • Mixing byte order (low byte first)
  • Printing raw bytes instead of combined value
4. This code tries to read a byte from an I2C sensor but does not work correctly:
Wire.begin();
Wire.beginTransmission(0x30);
Wire.write(0x00);
Wire.endTransmission();
byte data = Wire.read();
Serial.println(data);
What is the main problem?
medium
A. Wire.beginTransmission() address is wrong
B. Wire.read() is called without requesting data first
C. Wire.write() should be after Wire.read()
D. Wire.endTransmission() should be called twice

Solution

  1. Step 1: Check the sequence of I2C functions

    The code sends a command but never calls Wire.requestFrom() to ask for data before reading.
  2. Step 2: Understand Wire.read() usage

    Wire.read() only returns data after Wire.requestFrom() has been called and data is available.
  3. Final Answer:

    Wire.read() is called without requesting data first -> Option B
  4. Quick Check:

    Must requestFrom() before read() [OK]
Hint: Always requestFrom() before reading data [OK]
Common Mistakes:
  • Calling Wire.read() without requestFrom()
  • Misunderstanding beginTransmission() purpose
  • Not checking if data is available before reading
5. You want to read temperature data from an I2C sensor that sends two bytes: the first byte is the integer part, the second byte is the fractional part in hundredths (e.g., 25 and 75 means 25.75°C). Which code snippet correctly reads and prints the temperature as a float?
hard
A. Wire.requestFrom(0x48, 2); if (Wire.available() >= 2) { byte intPart = Wire.read(); byte fracPart = Wire.read(); float temp = intPart + fracPart / 100; Serial.println(temp); }
B. Wire.requestFrom(0x48, 2); if (Wire.available() >= 2) { byte fracPart = Wire.read(); byte intPart = Wire.read(); float temp = intPart + fracPart / 100.0; Serial.println(temp); }
C. Wire.requestFrom(0x48, 2); byte intPart = Wire.read(); byte fracPart = Wire.read(); float temp = intPart + fracPart * 100; Serial.println(temp);
D. Wire.requestFrom(0x48, 2); if (Wire.available() >= 2) { byte intPart = Wire.read(); byte fracPart = Wire.read(); float temp = intPart + fracPart * 0.01; Serial.println(temp); }

Solution

  1. Step 1: Confirm correct byte order and availability check

    The sensor sends integer part first, then fractional part. The code must check availability before reading both bytes.
  2. Step 2: Calculate temperature correctly

    Fractional part is in hundredths, so divide by 100 or multiply by 0.01. Wire.requestFrom(0x48, 2); if (Wire.available() >= 2) { byte intPart = Wire.read(); byte fracPart = Wire.read(); float temp = intPart + fracPart * 0.01; Serial.println(temp); } uses fracPart * 0.01, which is correct and clear.
  3. Final Answer:

    the snippet with fracPart * 0.01 -> Option D
  4. Quick Check:

    Check availability, read int then frac, multiply frac by 0.01 [OK]
Hint: Check data availability and multiply fraction by 0.01 [OK]
Common Mistakes:
  • Reading bytes in wrong order
  • Not checking Wire.available() before reading
  • Multiplying fraction by 100 instead of dividing
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