📖 Scenario: You have a temperature sensor connected to your Arduino using the I2C communication protocol. You want to read the temperature data from the sensor and display it on the Serial Monitor.
🎯 Goal: Build a simple Arduino program that reads temperature data from an I2C sensor and prints the temperature value to the Serial Monitor.
📋 What You'll Learn
Use the Wire library to communicate over I2C
Initialize the I2C communication in the setup() function
Read two bytes of data from the sensor at I2C address 0x48
Combine the two bytes into a temperature value
Print the temperature value to the Serial Monitor
💡 Why This Matters
🌍 Real World
Reading sensor data over I2C is common in projects like weather stations, home automation, and robotics.
💼 Career
Understanding I2C communication and sensor data reading is essential for embedded systems and hardware programming jobs.
Progress0 / 4 steps
1
Setup I2C communication and sensor address
Include the Wire.h library and create a constant byte variable called sensorAddress with the value 0x48.
Arduino
Hint
Use #include <Wire.h> to include the I2C library. Define sensorAddress as const byte sensorAddress = 0x48;.
2
Initialize I2C and Serial communication
In the setup() function, start the I2C communication with Wire.begin() and start Serial communication at 9600 baud with Serial.begin(9600).
Arduino
Hint
Use Wire.begin() to start I2C and Serial.begin(9600) to start serial communication.
3
Read two bytes from the sensor
In the loop() function, request 2 bytes from the sensor using Wire.requestFrom(sensorAddress, 2). Then read the first byte into highByte and the second byte into lowByte using Wire.read().
Arduino
Hint
Use Wire.requestFrom(sensorAddress, 2) to ask for 2 bytes. Use Wire.read() twice to get each byte.
4
Calculate temperature and print it
Combine highByte and lowByte into an integer called temperature by shifting highByte 8 bits left and OR with lowByte. Then print "Temperature: " followed by temperature and " C" to the Serial Monitor.
Arduino
Hint
Shift highByte left by 8 bits and OR with lowByte to get temperature. Use Serial.print and Serial.println to show the temperature.
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
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.
Step 2: Differentiate from other functions
Reading or writing data happens after initialization; Wire.begin() does not perform these actions.
Final Answer:
To initialize the I2C communication bus -> Option A
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
Step 1: Recall the correct Wire library function
The function to request bytes from an I2C device is Wire.requestFrom(address, quantity).
Step 2: Match the syntax with the options
Only Wire.requestFrom(0x40, 2); uses the correct function name and parameters.
Final Answer:
Wire.requestFrom(0x40, 2); -> Option C
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
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.
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
Step 1: Check the sequence of I2C functions
The code sends a command but never calls Wire.requestFrom() to ask for data before reading.
Step 2: Understand Wire.read() usage
Wire.read() only returns data after Wire.requestFrom() has been called and data is available.
Final Answer:
Wire.read() is called without requesting data first -> Option B
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?
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.
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.
Final Answer:
the snippet with fracPart * 0.01 -> Option D
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 unknownstrongwhile earning +1 Grip toward your certificate.