📖 Scenario: You have a Raspberry Pi connected to a temperature sensor via the I2C bus. You want to read the temperature data from the sensor and display it.
🎯 Goal: Build a Python program that reads temperature data from an I2C sensor and prints the temperature value.
📋 What You'll Learn
Use the smbus2 library to communicate over I2C
Read data from the sensor's I2C address 0x48
Read the temperature register at address 0x00
Convert the raw data to a temperature value in Celsius
Print the temperature value
💡 Why This Matters
🌍 Real World
Reading sensor data over I2C is common in home automation, weather stations, and robotics projects where Raspberry Pi collects environmental data.
💼 Career
Understanding I2C communication and sensor data reading is important for embedded systems developers, IoT engineers, and hardware interfacing roles.
Progress0 / 4 steps
1
Set up I2C bus and sensor address
Import the SMBus class from the smbus2 library. Create a variable called bus that opens I2C bus number 1. Create a variable called sensor_address and set it to 0x48.
Raspberry Pi
Hint
Use from smbus2 import SMBus to import. Then create bus = SMBus(1) for I2C bus 1. Set sensor_address = 0x48 as the sensor's I2C address.
2
Set the register address to read temperature
Create a variable called temp_register and set it to 0x00, which is the register address for temperature data on the sensor.
Raspberry Pi
Hint
The temperature register is usually at address 0x00. Create temp_register = 0x00.
3
Read raw temperature data from the sensor
Use the bus.read_word_data method with sensor_address and temp_register to read the raw temperature data. Store the result in a variable called raw_temp.
Raspberry Pi
Hint
Use raw_temp = bus.read_word_data(sensor_address, temp_register) to read the raw data.
4
Convert raw data and print temperature
Convert the raw_temp value to Celsius by swapping bytes and dividing by 256. Store the result in temperature_celsius. Then print the temperature with print(f"Temperature: {temperature_celsius:.2f} °C").
Raspberry Pi
Hint
The sensor sends data in little endian, so swap bytes first. Then divide by 256 to get Celsius. Finally, print with print(f"Temperature: {temperature_celsius:.2f} °C").
Practice
(1/5)
1. What is the main purpose of using the I2C protocol on a Raspberry Pi when working with sensors?
easy
A. To communicate with multiple sensors using unique addresses
B. To increase the Raspberry Pi's processing speed
C. To power the sensors directly from the Raspberry Pi
D. To store sensor data permanently on the Raspberry Pi
Solution
Step 1: Understand I2C communication basics
I2C allows multiple devices to connect using unique addresses on the same bus.
Step 2: Identify the role of I2C with sensors
The Raspberry Pi uses I2C to talk to sensors by addressing each one uniquely.
Final Answer:
To communicate with multiple sensors using unique addresses -> Option A
Quick Check:
I2C = Multiple devices, unique addresses [OK]
Hint: I2C uses addresses to talk to many devices [OK]
Common Mistakes:
Thinking I2C increases processing speed
Confusing communication with power supply
Assuming I2C stores data permanently
2. Which Python library is commonly used on Raspberry Pi to read data from an I2C sensor?
easy
A. pygame
B. smbus
C. matplotlib
D. requests
Solution
Step 1: Recall common Python libraries for hardware
For I2C communication on Raspberry Pi, the smbus library is standard.
Step 2: Eliminate unrelated libraries
pygame is for games, matplotlib for plotting, requests for web requests, so they don't fit.
Final Answer:
smbus -> Option B
Quick Check:
Python I2C library = smbus [OK]
Hint: Use smbus for I2C sensor communication [OK]
Common Mistakes:
Choosing pygame or matplotlib for sensor reading
Confusing web libraries with hardware libraries
3. Given this Python code snippet reading from an I2C sensor, what will be printed?
import smbus
bus = smbus.SMBus(1)
address = 0x48
value = bus.read_byte_data(address, 0x00)
print(value)
medium
A. The string 'value' printed literally
B. An error because SMBus(1) is invalid
C. The I2C address 0x48 printed as decimal
D. The byte value stored at register 0x00 of device 0x48
Solution
Step 1: Understand the code's function
The code reads one byte from register 0x00 of the device at I2C address 0x48.
Step 2: Identify the output of print(value)
It prints the numeric byte value read from that register, not the address or a string.
Final Answer:
The byte value stored at register 0x00 of device 0x48 -> Option D
Quick Check:
read_byte_data returns register byte value [OK]
Hint: read_byte_data reads register value, not address [OK]
Common Mistakes:
Thinking SMBus(1) is invalid (it's correct for Raspberry Pi)
Confusing address with data value
Expecting string output instead of number
4. What is wrong with this code snippet for reading I2C sensor data?
import smbus
bus = smbus.SMBus(0)
address = 0x40
data = bus.read_byte_data(address, 0x01)
print(data)
medium
A. read_byte_data requires three arguments, missing one
B. The address 0x40 is invalid for I2C devices
C. SMBus(0) is incorrect; Raspberry Pi usually uses bus 1
D. print(data) should be print(bus.read_byte_data)
Solution
Step 1: Check SMBus bus number
On Raspberry Pi, I2C bus 1 is standard; bus 0 is usually invalid or unused.
Step 2: Verify other code parts
Address 0x40 is valid, read_byte_data takes two arguments, and print(data) is correct.
Final Answer:
SMBus(0) is incorrect; Raspberry Pi usually uses bus 1 -> Option C
Quick Check:
Use SMBus(1) on Raspberry Pi [OK]
Hint: Use SMBus(1) for Raspberry Pi I2C bus [OK]
Common Mistakes:
Using SMBus(0) instead of SMBus(1)
Thinking I2C addresses like 0x40 are invalid
Misunderstanding read_byte_data arguments
5. You want to read temperature data from a sensor at I2C address 0x5A which stores temperature in two registers: 0x07 (MSB) and 0x08 (LSB). How do you correctly combine these bytes to get the temperature value in Python?
hard
A. temp = (bus.read_byte_data(0x5A, 0x07) << 8) | bus.read_byte_data(0x5A, 0x08)
B. temp = bus.read_byte_data(0x5A, 0x07) + bus.read_byte_data(0x5A, 0x08)
C. temp = bus.read_byte_data(0x5A, 0x08) << 8 | bus.read_byte_data(0x5A, 0x07)
D. temp = bus.read_byte_data(0x5A, 0x07) * bus.read_byte_data(0x5A, 0x08)
Solution
Step 1: Understand byte order for temperature
MSB is the high byte, so shift it left by 8 bits to make space for LSB.
Step 2: Combine MSB and LSB correctly
Use bitwise OR to combine shifted MSB with LSB for full 16-bit value.