How to disable clock-stretching on the I2C protocol?

Hello Gentleman,
I am trying to make arduino(slave) communicate with another microchip(master) over the I2C protocol.

Master is sending a request for data from its slave(arduino) and expecting a response.

in the top image you can see such communication between two arduinos, both of which support the so-called clock-starching, i.e. the slave is keeping SCL LOW while it is preparing the response.

Clock Stretching - the Slave is allowed to hold the clock line low until it is ready to give out the result. The Master must wait for the clock to go back to high before continuing with its work.

Unfortunately the other chip ( that will be used as a master ) does not support this clock-starching and expects a reply immediately. Is there any way I could make arduino respond immediately after getting the request?

Thanks :slight_smile:

Is there any way I could make arduino respond immediately after getting the request?

When the request comes in, it should trigger an interrupt on the Arduino - the OnRequest one - that you should have supplied an interrupt handler for.

It is your responsibility to supply the reply immediately - for some reasonable definition of "immediately".

PaulS:
When the request comes in, it should trigger an interrupt on the Arduino - the OnRequest one - that you should have supplied an interrupt handler for.

It is your responsibility to supply the reply immediately - for some reasonable definition of “immediately”.

Thanks for the tip. My slave code looks like this

// NANO COM 9 SLAVE

#include <Wire.h>

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
}


void requestEvent() {
  Wire.write("555");
}

void loop() {}

I am not sure what needs to be done for it to respond imminently…

Doesn't that code respond in a timely enough fashion?

Does that code even compile? Wire.write() doesn't take a string, does it?

Doesn't that code respond in a timely enough fashion?

No, it skips basically 2-3 SCL cycles.

Does that code even compile? Wire.write() doesn't take a string, does it?

Seems that it does take a sting fine.

But I got a suggestion that it might be because of the "TWINT flag" set wrong. now googling about it. any ideas how it is set?

You can load the outgoing buffer on the slave before it gets the request from the master. Usually I2C is so slow that the slave does have time to load the buffer with the requested data in between the bits of the I2C protocol.

You have to dig down to find out what else is happening that's preventing it from responding in time.

Hi, I am facing the exactly same problem. The master chip does not support I2C clock stretching when communicate with a arduino uno as a i2c slave. The communication will work when I set the master clock below 83KHz. I can't modify the code on master side, so is there any suggestion for my work?

monticle:
The communication will work when I set the master clock below 83KHz.

So why is this not a solution to your problem?

Post your code too. Use the full (or preview) editor to get the </> button to properly embed code in your post.

in the top image you can see such communication between two arduinos, both of which support the so-called clock-starching, i.e. the slave is keeping SCL LOW while it is preparing the response.

By definition, in a TWI Bus, a Master is the device that generates the SCL (clock) pulses as many as needed. The slave can modulate only the SDA line to mark ACK or NACK. |500x210

GolamMostafa: By definition, in a TWI Bus, a Master is the device that generates the SCL (clock) pulses as many as needed. The slave can modulate only the SDA line to mark ACK or NACK.

Then you're reading the wrong definition. Go back and read it again. Search for the words "clock stretching".

GolamMostafa:
The slave can modulate only the SDA line to mark ACK or NACK.

First hit on Google for "i2c clock stretching":

Then you're reading the wrong definition. Go back and read it again.

|500x92

I stand educated on the issue that TWI slaves can stretch the SCL!

The following setup between two UNO works in Master-Slave arrangement.

Figure-1: Two UNo in Master-Slave Network

When K1 is just pressed, the Master makes a request to the Slave to send ‘some data’; the slave sends 555 which appears on LCDM.

Program Codes for Master:

#include<Wire.h>
#include<LiquidCrystal.h>
LiquidCrystal lcd(A0, A1, 8, 9, 10, 11);

#define slave2Address 0b0001000
void setup()            
{
  Wire.begin();
  lcd.begin(20, 4);
  lcd.setCursor(0, 0);
  lcd.print("AUST");   //prompt msg for Master
  pinMode(2, INPUT_PULLUP);

while(digitalRead(2) !=LOW)
  ;
Wire.requestFrom(slave2Address, 32);

lcd.setCursor(0, 3);
  byte x = Wire.read();
  byte y = Wire.read();
  byte z = Wire.read();
  byte x1 = Wire.read();
  lcd.write(x);
  lcd.write(y);
  lcd.write(z);   //Master receives 555 from slave
  
}

void loop() 
{
  
}

Program Codes for Slave

#include<Wire.h>
#include<LiquidCrystal.h>
LiquidCrystal lcd(A0, A1, 8, 9, 10, 11);

#define slave2Address 0b0001000

void setup()            
{
  Wire.begin(slave2Address);
  lcd.begin(20, 4);
  lcd.setCursor(0, 0);
  lcd.print("AUSTUniv");   //prompt msg for Slave

  Wire.onRequest(mySendHandler);
}

void loop() 
{
  
}

void mySendHandler()
{
  lcd.setCursor(0, 3);
  lcd.print("Fine!");
  Wire.write("555");   //sending 555 to Master
}

Operating procedures
1. Let us build as per Fig-1.
2. Upload programs for the Master, and for the Slave.
3. Reset both the UNOs. The Prompt messages should be there.
4. Press K1.
5. LCDS shows: Fine!, and LCDM shows: 555.