Wire library for I2C in Arduino - Time & Space Complexity
When using the Wire library for I2C communication, it's important to understand how the time to send or receive data changes as the amount of data grows.
We want to know how the time cost grows when we send more bytes over I2C.
Analyze the time complexity of the following code snippet.
#include <Wire.h>
void sendData(byte address, byte* data, int length) {
Wire.beginTransmission(address);
for (int i = 0; i < length; i++) {
Wire.write(data[i]);
}
Wire.endTransmission();
}
This code sends a list of bytes to a device over I2C using the Wire library.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop that calls
Wire.write()for each byte. - How many times: Exactly
lengthtimes, once per byte to send.
As the number of bytes to send increases, the number of write operations grows the same way.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 writes |
| 100 | 100 writes |
| 1000 | 1000 writes |
Pattern observation: The time grows directly in proportion to the number of bytes sent.
Time Complexity: O(n)
This means the time to send data grows linearly with the number of bytes you send.
[X] Wrong: "Sending more bytes takes the same time as sending just one byte."
[OK] Correct: Each byte requires a separate write operation, so more bytes mean more time spent sending.
Understanding how communication time grows with data size helps you write efficient code and explain your reasoning clearly in technical discussions.
"What if we buffered all bytes first and sent them in one call? How would the time complexity change?"
Practice
Wire.begin() function in Arduino's Wire library?Solution
Step 1: Understand the role of Wire.begin()
TheWire.begin()function sets up the Arduino as a master or slave on the I2C bus and starts the communication.Step 2: Differentiate from other Wire functions
Functions likeWire.beginTransmission()andWire.requestFrom()handle sending and receiving data, not initialization.Final Answer:
To initialize the I2C bus and join the I2C network -> Option DQuick Check:
Wire.begin() starts I2C communication [OK]
- Confusing Wire.begin() with data sending functions
- Using Wire.beginTransmission() to start communication
- Thinking Wire.begin() sends or receives data
Solution
Step 1: Identify the function to start transmission
Wire.beginTransmission(address)is used to begin sending data to the device at the given address.Step 2: Check other options for correctness
Wire.requestFrom()is for receiving data,Wire.send()is deprecated, andWire.start()does not exist.Final Answer:
Wire.beginTransmission(0x3C); -> Option BQuick Check:
Use Wire.beginTransmission(address) to send data [OK]
- Using Wire.requestFrom() to send data
- Using deprecated Wire.send() instead of Wire.write()
- Trying to use non-existent Wire.start() function
Wire.begin(); Wire.beginTransmission(0x50); Wire.write(0x01); Wire.endTransmission(); Wire.requestFrom(0x50, 1); int data = Wire.read(); Serial.println(data);
Solution
Step 1: Analyze the code flow
The code initializes I2C, sends one byte (0x01) to device 0x50, then requests 1 byte back from the same device.Step 2: Understand Wire.read() behavior
Wire.read()reads the byte received from the device. It does not return the sent byte but the device's response.Final Answer:
Prints the byte received from device at 0x50 -> Option AQuick Check:
Wire.read() returns received data, not sent data [OK]
- Assuming Wire.read() returns the sent byte
- Thinking Wire.read() returns 0 by default
- Confusing Wire.write() and Wire.read() roles
Wire.begin(); Wire.beginTransmission(0x40); Wire.write(0x10); Wire.requestFrom(0x40, 1); Wire.endTransmission(); int val = Wire.read();
Solution
Step 1: Check the order of I2C functions
Wire.endTransmission()must be called to end sending data before requesting data withWire.requestFrom().Step 2: Identify the incorrect sequence
The code callsWire.requestFrom()beforeWire.endTransmission(), which is incorrect and causes communication errors.Final Answer:
Calling Wire.requestFrom() before Wire.endTransmission() -> Option AQuick Check:
End transmission before requesting data [OK]
- Swapping the order of endTransmission and requestFrom
- Forgetting to call endTransmission() after beginTransmission()
- Calling Wire.read() without data available
Solution
Step 1: Understand how to receive data with Wire.requestFrom()
Wire.requestFrom(address, quantity)requests bytes from the device. ThenWire.read()reads each byte.Step 2: Check the correct sequence for reading data
OnlyWire.requestFrom()is needed to receive data.Wire.beginTransmission()andWire.endTransmission()are for sending data, not receiving.Final Answer:
Wire.requestFrom(0x68, 3); for (int i = 0; i < 3; i++) { data[i] = Wire.read(); } -> Option CQuick Check:
Use requestFrom() then read() in loop to get bytes [OK]
- Using beginTransmission() when only reading data
- Calling endTransmission() after requestFrom()
- Reading data before requesting it
Ready to prove it?
Pass the test and this pattern moves unknown
