# Noises on the I2C BUS

I am using stm32f407 and LM75 with I2C Bus serial communication. In this code, I am Using a lot of interrupts and etc.Sometimes I2C Can give a error I can accept this but I am uncomfortable with signals. There is only LM75 IC on the bus line and Rp is 4.7K ohm.

Sometimes I2C Bus give an BERR Error or I2C Status stuck busy or i2c bus line stay zero volt.

How can I fix the signal? Or is it normal?

I have tried 10pf capacitors between ground and scl and between ground and sda. But signals are same.

There are oscilloscope views below

Photo1: I2CBUS Diagram

Photo2: 1MHZ speed I2CBUS

Photo3: 100KHZ speed I2CBUS

Photo4: 400KHZ speed I2CBUS

Photo5: PROPS

Photo6: I2C ROUTES

Photo7: Ground and Supply noises(Channel 1:MCU Ground, Channel 2:MCU Supply)

• Are you using breadboard? Mar 13, 2017 at 10:53
• Do you have a good ground connection on your scope probes? Those look like artifacts. Mar 13, 2017 at 10:54
• Can you provide the PCB layout, and a photo of the board with your probes connected? Code might be useful too. My suspicion is that the artifacts and ringing you're seeing on the scope are part of the test setup. Mar 13, 2017 at 11:04
• Chupacabras, This is user board .mostly smd component Mar 13, 2017 at 11:38
• Can you post a photo of the system you're testing? Mar 13, 2017 at 12:06

I would guess that the ringing on the falling edge is a measurement artifact (The black crocodile clip leads that come with scope probes are EVIL), but apart from that:

1MHz is very, very fast for I2C, especially with that relatively high pull up value. Are you sure your I2C slaves devices (all of them, not just the one you are trying to address) are capable of meeting timing at that rate?

Your 100kHz waveform looks fine to me, and your 400kHz one is not horrible (But I might take the pull up resistors down to 2.2k or so).

I would second the note about the LM75 being a little bit lockup happy, and would note that a bus reset like the one demonstrated elsewhere is a good idea at boot time as otherwise you can end up with the bus peripheral state machine not matching the processors idea of bus state, very annoying when trying to use a debugger.

My instinctive response to I2C is that I will happily do the extra routing to use SPI instead if I have any choice, so much less annoying from a software perspective (Also a noise and immunity perspective).

Having now seen the extra photos, the ringing on the falling edge is almost certainly mostly does to the length of the scope ground lead and not really present, and the waveforms are fine at 100k, and mostly ok at 400k (2.2k pull ups will make both fine), your remaining problems are probably software.

There are 2 different problems:
1. noise
2. you are getting errors in communication

I try to answer the second one:
Try to use resistors with lower values, like 2.2k instead of 4.7k. Do not use capacitors for SDA or SCL lines. Use lower I2C frequency than 1MHz, you are probably getting errors not because of noise, but because too high frequency (according to first photo the rising edge is too slow to use 1MHz).

The noise could be caused by many things. Most likely long wires (parasitic inductance), not very good grounding, etc.

You show three different SCL clock frequencies in your scope shots. In two of the shots the SCL duty cycle is not 50% like it should be. In the cases of the SCL not having 50% duty cycle the slow rise time is a real problem. The LM75 is a 100KHz device so the SCL clock to clock time should be no more than 10usec. The SCL low time should be close to 5usec and the high time should be as close to 5usec as possible by lowering the value of your pullup resistors as others have already recommended.

The LM75 temperature sensor is notoriously susceptible to getting locked up when there are protocol violations on the I2C interface which in your case is most likely due to the poor clock duty cycle or too high of clock frequency.

If you intend to stay with the LM75 it is essential that you implement an I2C bus recovery routine that you execute at startup or whenever you see that the I2C bus is giving errors due to being hung. Here is a sample I2C recovery routine that I use in my code. (This is coded for PIC-32 so you will have to translate the concept to your MCU environment and tool set).

//
//
// function to temporarily disable the I2C port and the run sequence to
// unstuck any slave devices that may be hung in read mode waiting for an
// ACK to come. this recovery sequence consists of a start, >9 clocks and a
// stop. This is followed again with another start/stop sequence that permits
// state machine logic reset in most slave peripheral chips
//

void i2c_recovery(void)
{
uint32_t loop;

// Disable I2C0 controller to free the I/O pins
PLIB_I2C_Disable(I2C_ID_2);
i2c_dly();

i2c_start();
// let SDA be able to go high
PLIB_PORTS_PinDirectionInputSet(PORTS_ID_0, PORT_CHANNEL_A, PORTS_BIT_POS_3);   // set SDA2 hig-z (input mode)
i2c_dly();

// loop to make at least 9 clocks
for (loop = 0; loop < 9; loop++)
{
// let SCL go high by pullup
PLIB_PORTS_PinDirectionInputSet(PORTS_ID_0, PORT_CHANNEL_A, PORTS_BIT_POS_2);   // set SCL2 hig-z (input mode)
i2c_dly();
// pull SCL back low
PLIB_PORTS_PinClear(PORTS_ID_0, PORT_CHANNEL_A, PORTS_BIT_POS_2);               // set SCL2 low output
PLIB_PORTS_PinDirectionOutputSet(PORTS_ID_0, PORT_CHANNEL_A, PORTS_BIT_POS_2);  // set SCL2 low-z output driver
i2c_dly();
}
i2c_stop();

// run a start stop sequence. this performs a state machine reset
// in most slave i2c devices
i2c_start();
i2c_stop();
i2c_dly();

// re-enable  I2C0 controller
PLIB_I2C_Enable(I2C_ID_2);
}