Bird
Raised Fist0
Embedded Cprogramming~10 mins

I2C acknowledge and NACK behavior in Embedded C - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - I2C acknowledge and NACK behavior
Start Condition
↓
Send 7-bit Address + R/W bit
↓
Wait for ACK from Receiver
↓
Continue
↓
Send/Receive Data
This flow shows how the I2C master sends an address and waits for an ACK from the slave. If ACK received, communication continues; if NACK, the master stops or retries.
Execution Sample
Embedded C
i2c_start();
i2c_write(address);
ack = i2c_wait_ack();
if (ack == 0) {
  i2c_write(data);
} else {
  i2c_stop();
}
This code sends a start, writes an address, waits for ACK, then writes data if ACK received; otherwise, it stops communication.
Execution Table
StepActionSignal SentACK/NACK ReceivedNext Action
1Send Start ConditionSTARTN/ASend Address
2Send Address + R/W bitAddress+R/WWaitingWait for ACK
3Wait for ACKAddress+R/WACK (0)Send Data
4Send Data ByteDataWaitingWait for ACK
5Wait for ACKDataACK (0)Continue or Stop
6Send Stop ConditionSTOPN/AEnd Communication
💡 Communication ends after sending STOP or if NACK received at any wait step.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4After Step 5Final
ackundefinedundefined0 (ACK received)undefined0 (ACK received)0
Key Moments - 2 Insights
Why does the master wait for an ACK after sending the address?
The master waits to confirm the slave received the address and is ready. If no ACK (NACK), the master knows the slave did not respond and stops communication (see execution_table step 3).
What happens if the master receives a NACK after sending data?
If the master receives a NACK after data, it means the slave cannot accept more data or an error occurred. The master should stop or retry (not shown in this trace but implied after step 5).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'ack' after step 3?
A1 (NACK received)
B0 (ACK received)
Cundefined
D-1 (error)
💡 Hint
Check the 'ACK/NACK Received' column at step 3 in execution_table.
At which step does the master send the STOP condition?
AStep 4
BStep 3
CStep 6
DStep 2
💡 Hint
Look at the 'Action' column for 'Send Stop Condition' in execution_table.
If the slave sends a NACK after the address, what should the master do next?
ASend STOP condition and end communication
BSend another address immediately
CContinue sending data
DIgnore and wait for ACK again
💡 Hint
Refer to concept_flow where NACK after address leads to STOP condition.
Concept Snapshot
I2C communication starts with a START condition.
Master sends 7-bit address + R/W bit.
Slave responds with ACK (0) or NACK (1).
ACK means continue; NACK means stop or retry.
Data bytes also require ACK from slave.
STOP condition ends communication.
Full Transcript
In I2C communication, the master begins by sending a START condition. Then it sends the 7-bit address plus a read/write bit. The slave must respond with an ACK signal (logic 0) to confirm it received the address. If the master receives an ACK, it continues by sending or receiving data bytes. Each data byte sent also requires an ACK from the slave. If the slave sends a NACK (logic 1) at any point, the master stops communication by sending a STOP condition. This process ensures both devices are synchronized and data is transferred correctly.

Practice

(1/5)
1. What does an ACK (Acknowledge) signal mean in I2C communication?
easy
A. The sender is requesting to resend the data
B. The receiver wants to stop communication immediately
C. The communication line is idle
D. The receiver successfully received data and is ready for more

Solution

  1. Step 1: Understand ACK meaning in I2C

    ACK means the receiver signals it has received the data correctly and is ready to continue.
  2. Step 2: Compare options with ACK meaning

    Only The receiver successfully received data and is ready for more matches this meaning; others describe stop or errors.
  3. Final Answer:

    The receiver successfully received data and is ready for more -> Option D
  4. Quick Check:

    ACK = Ready for more data [OK]
Hint: ACK means receiver says 'send more' [OK]
Common Mistakes:
  • Confusing ACK with NACK meaning
  • Thinking ACK means stop communication
  • Assuming ACK means error occurred
2. Which of the following code snippets correctly sends a NACK after reading the last byte in I2C using embedded C?
easy
A. i2c_read_byte(I2C1, ACK);
B. i2c_read_byte(I2C1, NACK);
C. i2c_write_byte(I2C1, NACK);
D. i2c_send_ack(I2C1);

Solution

  1. Step 1: Identify correct function to read with NACK

    To signal no more data is needed, the read function must be called with NACK.
  2. Step 2: Check options for correct usage

    i2c_read_byte(I2C1, NACK); uses i2c_read_byte with NACK, which is correct. Others either send ACK or write instead of read.
  3. Final Answer:

    i2c_read_byte(I2C1, NACK); -> Option B
  4. Quick Check:

    Read last byte with NACK to stop [OK]
Hint: Use read with NACK to stop reading last byte [OK]
Common Mistakes:
  • Using ACK instead of NACK after last byte
  • Calling write instead of read for NACK
  • Confusing function names for ACK/NACK
3. Consider this code snippet reading 3 bytes from an I2C device:
for (int i = 0; i < 3; i++) {
  data[i] = (i < 2) ? i2c_read_byte(I2C1, ACK) : i2c_read_byte(I2C1, NACK);
}
What is the purpose of sending NACK on the last byte?
medium
A. To request the device to resend the last byte
B. To acknowledge the last byte and continue reading
C. To indicate the master will stop reading after this byte
D. To reset the I2C bus immediately

Solution

  1. Step 1: Analyze the loop and ACK/NACK usage

    The loop reads 3 bytes; for first two bytes it sends ACK, for last byte it sends NACK.
  2. Step 2: Understand NACK meaning on last byte

    NACK signals the master will stop reading after this byte, telling the slave no more data is needed.
  3. Final Answer:

    To indicate the master will stop reading after this byte -> Option C
  4. Quick Check:

    NACK on last byte = stop reading [OK]
Hint: NACK on last byte means stop reading [OK]
Common Mistakes:
  • Thinking NACK requests resend
  • Assuming NACK resets bus
  • Confusing ACK and NACK roles
4. You wrote this code to read bytes from I2C but the slave device never stops sending data:
for (int i = 0; i < 4; i++) {
  data[i] = i2c_read_byte(I2C1, ACK);
}
What is the likely problem?
medium
A. You never sent NACK after the last byte to stop reading
B. You should use i2c_write_byte instead of i2c_read_byte
C. The loop should run 5 times instead of 4
D. You need to send a STOP condition before reading

Solution

  1. Step 1: Check ACK/NACK usage in the loop

    The code sends ACK for every byte read, never sending NACK to signal stop.
  2. Step 2: Understand effect of missing NACK

    Without NACK after last byte, slave keeps sending data, causing endless transmission.
  3. Final Answer:

    You never sent NACK after the last byte to stop reading -> Option A
  4. Quick Check:

    Missing NACK means no stop signal [OK]
Hint: Send NACK after last byte to stop slave [OK]
Common Mistakes:
  • Using ACK for all bytes including last
  • Confusing read and write functions
  • Ignoring need for STOP condition after read
5. You want to write a function that reads a variable number of bytes from an I2C device and properly sends ACK for all bytes except the last one, which should send NACK. Which code snippet correctly implements this behavior?
hard
A. for (int i = 0; i < length - 1; i++) { data[i] = i2c_read_byte(I2C1, ACK); } data[length - 1] = i2c_read_byte(I2C1, NACK);
B. for (int i = 0; i < length; i++) { data[i] = i2c_read_byte(I2C1, ACK); }
C. for (int i = 0; i < length; i++) { data[i] = i2c_read_byte(I2C1, NACK); }
D. data[0] = i2c_read_byte(I2C1, NACK); for (int i = 1; i < length; i++) { data[i] = i2c_read_byte(I2C1, ACK); }

Solution

  1. Step 1: Understand ACK/NACK pattern for multiple bytes

    All bytes except last must be read with ACK; last byte with NACK to stop.
  2. Step 2: Analyze each option

    for (int i = 0; i < length - 1; i++) { data[i] = i2c_read_byte(I2C1, ACK); } data[length - 1] = i2c_read_byte(I2C1, NACK); reads all but last byte with ACK, then last byte with NACK, correctly signaling stop. Others send wrong signals or in wrong order.
  3. Final Answer:

    for (int i = 0; i < length - 1; i++) { data[i] = i2c_read_byte(I2C1, ACK); } data[length - 1] = i2c_read_byte(I2C1, NACK); -> Option A
  4. Quick Check:

    ACK all but last, NACK last byte [OK]
Hint: Send NACK only on last byte read [OK]
Common Mistakes:
  • Sending NACK on all bytes
  • Sending ACK on last byte
  • Reading last byte first with NACK
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