I am using I2C to communicate (i) with a RTC clock close to the Arduino (Mega), and (ii) via a relatively "long" wire (a 2m RJ45 cable), with an I/O expander chip (MCP23017), using 4K7 pullup resistors on SDA and SCL close to the MCP23017.
I experience some random mishaps: Port A of the device is configured as output. Every second as a test, I write a byte OutData = 255 to the GPIOA and thereafter read GPIOA to the variable OutData_actual.
I made a conditional print of OutData and OutData1, whenever they are different.
When this occurs, I experienced that I can only recover by doing a complete reset of the chip, and re-establishing then portA as output.
Every 1000 to 10000 reads, I get a difference (255 vs 0) , do thereafter a reset of the MCP23017 via a pin of the arduino connected the the reset pin of the MCP23017, re-establish portA as output, and continue.
[I made also the observation that upon this error, the OLATA register holds the correct value (255), while the read on GPIOA register is 0; also when measuring with a voltmeter (when an error has occurred), the voltage on the pins of portA are at zero.]
I assume that the problem might the cable length, because errors seem to appear more or less at random.
QUESTION: is there a simple way to REDUCE the speed of the I2C protocol in the wire library ?
(at this point, I am not willing to go with I2C buffers such as PCA9600, BUT I nevertheless need a robust read of the MCP23017 situated at a distance)
I've googled around a bit and found this: WireLibraryDetailedReference -- it says something about overwriting the default I2C clock frequency in master mode under the "begin()" topic.
Twisted wire cables are not the best thing for I2C because of there capacitance. So a flat cable will be better like a length of ribbon cable. Also you could try reducing the pull up resistor to 3K3 or 2K7.
SUB_QUESTION
Any idea if it is possible to modify the cyclic ratio of the I2C clock, using the wire lib ?
(to allow [at a given I2C clock frequency] a relative increase of the time in the " LOW' state with respect to the time in the 'HIGH' state ?
Grumpy_Mike:
Also you could try reducing the pull up resistor to 3K3 or 2K7.
I agree that changing the pullup resistors is definely to be tried. SUBQUESTION: What is the minimum value that can be safely tried ?
Grumpy_Mike:
Twisted wire cables are not the best thing for I2C because of there capacitance. So a flat cable will be better like a length of ribbon cable. Also you could try reducing the pull up resistor to 3K3 or 2K7.
I do not agree: twisting two wires does not change the characteristic distance separating the wire, hence twisting vs non-twisting is essentially expected to induce NO change in the capacitance.
Pulling some values from googling: the typical capacitance for a flat telephone wire is about 40pF/meter,
and the value for an RJ45 cable is about 46pF/meter.
I like also the availability of cheap ready-to-use cables fitted with connectors, and cheap mating connectors.
I do not agree: twisting two wires does not change the characteristic distance separating the wire, hence twisting vs non-twisting is essentially expected to induce NO change in the capacitance.
It does not change the distance separating the wire, but it does make the conductors longer for a given length of cable and therefore it does affect the capacitance of the cable.