I am using a MCP23017 for additional IO’s. I have everything wired up and working correctly, but I do notice that over time (1-3 days), the MCP23017 IO’s don’t work anymore. Now I know there where some I2C issues on the Photon, but even with 4.4 I am still having these issues.
I also noticed that once I have issues with the MCP23017, that the Photon responds extremely slowly. For example, I am reading some pins from the Photon and based if they are HIGH, then I start flashing the RGB LED at an interval of 200 ms. When I have issues with the MCP23017, the RGB doesnt blink at 200 ms anymore, probably more like 1.5 seconds. Also at this state the Photon is slow to read the Photons IO. So starting the RGB blinking process is very delayed.
On my code, basically every loop() I am writing to the MCP23017 and telling it to set a pin HIGH or LOW. I was wondering if this is maybe causing the issue? That I am simply writing too much data to the I2C bus?? I added a 100 ms delay to the loop, and it does make it better, but only extends the days before the MCP23017 hangs again.
I’ve setup a spare Photon with a MCP23017 and a simple LED to see if I can replicate the issue, or if something else in my code might be causing this.
For the photon to be running slowly, it could be an interrupt that is firing often, slowing down the rest of the system. If you have any interrupt handlers in your code, try removing them to see if that helps.
I`ve tried running the this i2c code on my mcp23017 really fast on a rgb led.
And can see by flicking my head that each led is going on for a few milliseconds .
void loop() {
// To blink the LED, first we’ll turn it on…
digitalWrite(led2, HIGH);
mcp.digitalWrite(0, HIGH);
mcp.digitalWrite(8, LOW);
// We'll leave it on for 1 second...
delay(1);
// Then we'll turn it off...
digitalWrite(led2, LOW);
mcp.digitalWrite(0, LOW);
mcp.digitalWrite(8, HIGH);
// Wait 1 second...
delay(1);
}
About 230kHz. Much faster than 0.3.4 on the core, which ran at ca. 200Hz, so 3 orders of magnitude faster. (And this speed improvement will come to the core with the 0.4.5 release.)
Do you have a schematic of how the Photon connects to the MCP23017? I understand by the look of your project it might be something you might sell or commercialize, so mainly I want to see if your running the MCP23017 at 5v with a level shifter, 3.3 to 5v (no shifting) or 3.3v with direct connections.
I am trying to use the MCP23017 aswell and a few things that came to mind is
-Are you using the internal pull resistors on the MCP23017 or anything custom?
-Are you using a shifter? (i2c is a pretty annoying protocol with it's shifting)
For my circuit I plan on doing this
Photon running at 5.15v, (Logic at 3.3v), MCP running at 5.15v, level shifter from Adafruit specifically for I2C.(If this fails running optocouplers instead of the Adafruit. (PC817 x4)
or
External 3.3v PSU and running MCP23017 at 3.3 same supply as the Photon with a clean power supply. (Prob linear to prevent noise from switching sacrificing power savings....)
2.3.5 Both SDA and SCL maximum rise time (tr) violated when VDD_I2C bus
higher than ((VDD+0.3) / 0.7) V
Description
When an external legacy I2C bus voltage (VDD_I2C) is set to 5 V while the MCU is powered
from VDD, the internal 5-Volt tolerant circuitry is activated as soon the input voltage (VIN)
reaches the VDD + diode threshold level. An additional internal large capacitance then
prevents the external pull-up resistor (RP) from rising the SDA and SCL signals within the
maximum timing (tr) which is 300 ns in fast mode and 1000 ns in Standard mode.
The rise time (tr) is measured from VIL and VIH with levels set at 0.3VDD_I2C and
0.7VDD_I2C.
Workaround
The external VDD_I2C bus voltage should be limited to a maximum value of
((VDD+0.3) / 0.7) V. As a result, when the MCU is powered from VD
I’m running a test project which uses a mcp23017 and a mcp23008 , plus a i2c display and had no real problems , yet.
I power my mcp’s from 5v and connect the pull up resistors to 5v , and don’t use a level shifter.
The only thing a need to do is a wire.reset after the mcp.begins , if i don’t i get a system freeze when I send new code.