Electronic – arduino – I2C slave not acknowledging consistently

arduinoembeddedi2c

I'm trying to communicate with a Cypress CapSense module, model CY8CMBR3106S. During initial testing, I used Cypress's CY3240-I2USB USB-I2C bridge, which works perfectly. I then moved to an Arduino for prototyping of my own application. However, I cannot seem to get the Arduino to communicate reliably with the CapSense controller. Using the I2C scanner sketch found here, the Arduino discovers the CapSense controller perhaps once out of every 40 or so attempts.

In an attempt to debug this, I scoped the bus using both the Cypress USB-I2C bridge and the Arduino. I found that the controller always gives an ACK with the Cypress bridge, and almost never generates an ACK with the Arduino. However, other than the different voltages and clock rates (which I have played around with to no avail), I cannot seem to find any major differences between the frames sent from the two different sources which would explain the inconsistent ACKs.

At this point, I am at something of a loss–any advice would be much appreciated. Thanks!

Here are a few scope captures–note that channels 1 and 2 are SCL and SDA, respectively.

Successful communication using Cypress bridge (note ACK after 8th clock pulse)
enter image description here

Failed communication using Arduino (note lack of ACK)
enter image description here

Very rare successful communication using Arduino
enter image description here

Best Answer

As discussed in the comments above, the solution in this case was to increase the frequency of the I2C transmissions.

Per the datasheet, the Cypress CapSense controller gives a NACK on the first I2C transaction after waking into the active state. As @Roger Rowland noted, after around 340 ms of inactivity on the bus, the controller goes into a low-power state. Since my transmissions were spaced further apart than this timeout, each transmission would wake the device from the low-power state into the active state and receive a NACK. This problem is resolved by increasing the frequency of the transmissions to less than the timeout value, or by repeating a given transmission back-to-back until an ACK is received.