Is there a way in software to reset the i2c bus?

Just wondering if there is a simple command that can easily do this.

What do you mean by reset? Is there a fault condition on the bus? What is generating it, the master or the slave? Have you tried to clock through the fault? If you just want to reset the i2c peripheral of the arduino, you can set the i2c control register (TWCR) to zero and call Wire.begin().

TWCR = 0;
Wire.begin();

Thanks Ill try that . The slave stops receiving and sending.

I know its only I2c failing because I have LEDs in both the requestEvent and receiveEvent functions . That is the only "fault" condition. The communication stops anywhere from 1 hours to 4 hours of error free communication.
Other functions in the Arduino slave loop work fine. I have to bring rst on the slave low which resets the program and then I lose all of my function states . I messed around changing clock timing but nothing has changed no matter what I've done yet.

What kind of Slave is it ? An Arduino board ? Can you show the full sketch of the Slave ? How long are the wires ? Do you use a cable ? Is there a voltage mismatch for the I2C bus ?
I have so many of those questions, perhaps I can combine them into one question: "What you done to make the I2C bus so bad ?".

Kopel I appreciated and laughed at "What you done to make the I2C bus so bad".

  1. The slave is a Nano the master is a NodeMCU 12E .
  2. The length and cable is 12 inch push in wires.
  3. No conversion module between the 3.3volt NodeMCU and 5V nano ( didnt think I needed it but now...)

One note : TWRC = 0; causes a "was not declared in scope" error on the NodeMCU it doesn't cause this error on the Nano. However it DOES NOT seem to reset the i2c bus as suggested.

'I2C Bus reset' simply means (to me) -- the execution of the following lines to bring the I2C Bus at the 'Idle State' provided there is no hardware fault in the bus as regards to shorting of the bus wires together or with GND.

Wire.beginTransmission(slaveAddress);
byte busStatus = Wire.endTransmission();
if(busStatus != 0x00)
{
    //Bus fault or slave fault
}

buckstucky:
One note : TWRC = 0; causes a "was not declared in scope" error on the NodeMCU it doesn't cause this error on the Nano. However it DOES NOT seem to reset the i2c bus as suggested.

It is TWCR for TWI Bus Control Register and valid for UNO and NANO having ATmega328P/AVR MCU.

Seperate wires or a real cable ? Please do not use a cable.

I suppose that is a 16 MHz 5V Arduino Nano ? Then it requires at least 3.5V for a valid high on the I2C bus. I suggest to use a voltage level converter.

The NodeMCU uses a software I2C implementation. Does that library support when a Slave holds the SCL low ?

Can you show the sketch of the Slave ? Some use Serial functions, while-loops, delay() functions in the onRequest or onReceive handler, that is terribly wrong. Perhaps you forgot to use the "volatile" keyword. And so on.

This might be a combination of 10 or more issues, and you have to fix all them.

Thank you Kopel , you bring import points I will implement, maybe when I do this I will not need a reset !

LightuC, the TWRC =0 is now working on the Nano !!! This is good.

The longer you wait to show the sketch of the Slave, the worse the code probably is :’(

buckstucky:
Thank you Kopel , you bring import points I will implement, maybe when I do this I will not need a reset !

LightuC, the TWRC =0 is now working on the Nano !!! This is good.

It is TWCR and ‘not TWRC’; TWCR stands for ‘TWI Bus Control Register’.

Hi,
Have you got the gnd of the two controllers connected?

Check if both controllers have built in pullup resistors on the I2C lines?

Tom.. :slight_smile:

TomGeorge:
Check if both controllers have built in pullup resistors on the I2C lines?

Is it not enough for one controller to have I2C Bus pull-ups?

GolamMostafa:
Is it not enough for one controller to have I2C Bus pull-ups?

I would think if one is 3V3 and the other 5V, possibly.
Tom.. :slight_smile:

TomGeorge:
I would think if one is 3V3 and the other 5V, possibly.
Tom… :slight_smile:

No, it doesn’t work that way. You can either pull the bus to 3.3V or to 5V, but not both. Well, technically you can, but then your bus voltage will be around 4.15V (assuming two equal pull-up resistors).

My code is using "TWCR =0; " (no matter what Ive written here, LOL)

Here is the i2c slave functions:

// function that executes whenever data is received from master
void receiveEvent(int howMany) {
    byte c = Wire.read(); 
    rcmd=c;
  
rec_stat =((rec_stat)^1);
//Serial.println(" ");
//digitalWrite( ledPin9, digitalRead( ledPin12 ) ^ 1 ); //
}  

// function that executes whenever data is requested from master
void requestEvent() {
 i2cSimpleWrite(slave_data);            // Send the Master the sensor data

 xmt_stat =((xmt_stat)^1);
}

What are rec_stat and xmt_stat ? Single byte variables, or more ? Are they volatile ? Are they used in the Arduino loop() ? What is the function i2cSimpleWrite() ? Show the rest of the sketch !

The Serial.println() is commented out, but you should never use Serial functions in the onReceive or onRequest handler.