What is I2C communication used for in embedded systems?
I2C is a communication protocol used to connect multiple devices using just two wires: one for data (SDA) and one for clock (SCL). It allows microcontrollers to read from or write to sensors and other peripherals.
Click to reveal answer
beginner
In I2C, what does the 'read' operation mean?
A 'read' operation means the microcontroller requests data from a device on the I2C bus. The device sends back the requested data over the data line.
Click to reveal answer
intermediate
What are the two main steps to read data from an I2C device?
1. Send the device address with a write flag to specify the register to read from. 2. Send the device address with a read flag to receive the data from that register.
Click to reveal answer
intermediate
Why do you send the device address twice when reading data from an I2C device?
The first time is to tell the device which register you want to read (write mode). The second time is to actually read the data from that register (read mode).
Click to reveal answer
intermediate
What is a common function prototype to read data from an I2C device in embedded C?
int i2c_read(uint8_t device_addr, uint8_t register_addr, uint8_t *data, size_t length); This function reads 'length' bytes from 'register_addr' of the device at 'device_addr' into the buffer 'data'.
Click to reveal answer
What are the two wires used in I2C communication?
ASDA and SCL
BTX and RX
CMOSI and MISO
DCLK and DATA
✗ Incorrect
I2C uses SDA (data line) and SCL (clock line) for communication.
When reading data from an I2C device, what do you send first?
AStart condition only
BDevice address with read flag
COnly the register address
DDevice address with write flag
✗ Incorrect
You first send the device address with the write flag to specify the register to read.
What does the microcontroller receive during an I2C read operation?
ADevice address again
BAcknowledgment only
CData from the device
DClock signal
✗ Incorrect
During a read operation, the microcontroller receives data from the device.
Why is the device address sent twice in an I2C read?
ATo confirm device presence
BFirst to set register, second to read data
CTo reset the device
DTo end communication
✗ Incorrect
The first address with write flag sets the register, the second with read flag reads data.
Which of these is a typical return value for a successful I2C read function?
A0
B-1
C255
DNULL
✗ Incorrect
A return value of 0 usually means success in embedded C functions.
Explain the step-by-step process to read a byte from an I2C device register.
Think about how you tell the device what to read and then how you get the data.
You got /7 concepts.
Describe why I2C uses two wires and how data and clock signals work together during reading.
Imagine a conversation where one person talks and the other listens in time.
You got /5 concepts.
Practice
(1/5)
1. What is the main purpose of reading data from an I2C device in embedded C?
easy
A. To send commands to the device only
B. To get sensor or hardware information from the device
C. To reset the device hardware
D. To format the device memory
Solution
Step 1: Understand I2C device communication
I2C devices often provide sensor or hardware data that the program needs to read.
Step 2: Identify the purpose of reading data
Reading data means fetching information like sensor values, not sending commands or resetting.
Final Answer:
To get sensor or hardware information from the device -> Option B
Quick Check:
Reading I2C = Getting device data [OK]
Hint: Reading I2C means fetching data from device [OK]
Common Mistakes:
Confusing reading with sending commands
Thinking reading resets the device
Assuming reading formats memory
2. Which of the following is the correct way to declare a buffer to read 4 bytes from an I2C device in embedded C?
easy
A. int buffer[1];
B. int buffer = 4;
C. char buffer;
D. char buffer[4];
Solution
Step 1: Understand buffer declaration for byte storage
To store multiple bytes, we need an array of chars (bytes) of size 4.
Step 2: Check each option
char buffer[4]; declares a char array of size 4, suitable for 4 bytes. Others are either single variables or wrong types.
Final Answer:
char buffer[4]; -> Option D
Quick Check:
Buffer for 4 bytes = char array size 4 [OK]
Hint: Use char array for byte buffers [OK]
Common Mistakes:
Using single char instead of array
Using int for byte buffer
Declaring wrong array size
3. Given this code snippet, what will be the value of result after reading 2 bytes from the I2C device?
uint8_t buffer[2];
int result = i2c_read(device_addr, reg_addr, buffer, 2);
Assume i2c_read returns 0 on success and -1 on failure.
medium
A. 0
B. -1
C. 2
D. Undefined
Solution
Step 1: Understand i2c_read return values
The function returns 0 if the read was successful, -1 if it failed.
Step 2: Analyze the code snippet
The code reads 2 bytes and stores in buffer. If successful, result = 0.
Final Answer:
0 -> Option A
Quick Check:
Success return = 0 [OK]
Hint: i2c_read returns 0 on success [OK]
Common Mistakes:
Assuming return is number of bytes read
Confusing success with failure codes
Ignoring return value meaning
4. Identify the error in this code snippet for reading 1 byte from an I2C device:
uint8_t data;
int status = i2c_read(device_addr, reg_addr, &data, 1);
if (status = 0) {
process(data);
}
medium
A. Using assignment (=) instead of comparison (==) in if condition
B. Incorrect buffer type for reading data
C. Missing initialization of device_addr
D. Wrong number of bytes requested
Solution
Step 1: Check the if condition syntax
The condition uses single '=' which assigns 0 instead of comparing.
Step 2: Understand effect of assignment in if
Assignment returns 0 (false), so process(data) never runs even on success.
Final Answer:
Using assignment (=) instead of comparison (==) in if condition -> Option A
Quick Check:
Use '==' for comparison in if [OK]
Hint: Use '==' to compare, not '=' in conditions [OK]
Common Mistakes:
Confusing '=' and '==' in if statements
Ignoring return status check
Not using address-of operator for buffer
5. You want to read 3 bytes from an I2C device register and combine them into a 24-bit integer. Which code snippet correctly reads and combines the data?
uint8_t buf[3];
int status = i2c_read(device_addr, reg_addr, buf, 3);
uint32_t value = ???;
hard
A. value = buf[0] | (buf[1] << 8) | (buf[2] << 16);
B. value = (buf[2] << 16) | (buf[1] << 8) | buf[0];
C. value = (buf[0] << 16) | (buf[1] << 8) | buf[2];
D. value = buf[0] + buf[1] + buf[2];
Solution
Step 1: Understand byte order for 24-bit integer
Assuming buf[0] is most significant byte, shift it left by 16 bits.
Step 2: Combine bytes with bitwise OR
Shift buf[1] by 8 bits, add buf[2] as least significant byte.
Step 3: Check each option
value = (buf[0] << 16) | (buf[1] << 8) | buf[2]; correctly combines bytes in big-endian order. Others mix order or sum bytes incorrectly.
Final Answer:
value = (buf[0] << 16) | (buf[1] << 8) | buf[2]; -> Option C
Quick Check:
Shift and OR bytes for 24-bit value [OK]
Hint: Shift bytes by 16, 8, 0 bits and OR [OK]
Common Mistakes:
Mixing byte order
Adding bytes instead of bitwise OR
Not shifting bytes correctly
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.