Page 1 of 1

MCP23017 i2C very slow

Posted: Tue Apr 16, 2019 8:12 pm
by doglike
Hello,

I set up my ESP32 with a MCP23017 over i2C (400kHz) and got it working quite well with Adafruit-library. Everything is working as expected.

Then I did some simple measurement to check the HIGH-LOW switch speed and it is really dissapointing.
The code below for simply switching that pin HIGH takes 8,9ms!

Why is that so slow ?
Is this caused by i2C ?
Adafruit lib ?

Is it a better choice to take the MCP23S17 with SPI ?

PS: It doesn't make any difference when I put pull-ups on the SDA/SCL lines...

Thanks!

Code: Select all

		
uint32 timestamp = micros();
mcp.digitalWrite(pin, HIGH);
Serial.println( micros() - timestamp );

Re: MCP23017 i2C very slow

Posted: Wed Apr 17, 2019 2:29 am
by ESP_Sprite
FWIW, the Adafruit library does a read-modify-write operation which needs to read the data from the chip before writing it back with the bit you want changed. You could speed everything up by caching the last-written value, but that'd only net you a factor of 2-3 improvement... I'm not sure what causes the rest of the slowdown.

Re: MCP23017 i2C very slow

Posted: Wed Apr 17, 2019 10:58 am
by doglike
Yes, I also could figure that out.
There is another method available in the lib:
Adafruit_MCP23017::writeGPIOAB (writing all pins once)
That speeded up everything a bit, but that still takes ~3ms :(



PS: The i2C is running @400kHz of course

Re: MCP23017 i2C very slow

Posted: Thu Apr 18, 2019 7:21 am
by don01pf
I recently did some testing with both the I2C MCP23017 and the SPI MCP23S17, but with the esp8266 Lolin v3 board.

Reading a 8 bit port, 128*2(256 bytes) line size at 16-bits per pixel ... (SQCIF - https://en.wikipedia.org/wiki/Common_In ... ate_Format)

MCP23017 (700KHz) => 19+ ms
MCP23S17 (10MHz) => 2+ ms

Reading 128*2*96 (24576 bytes) SQCIF full 16-bit frame size
MCP23S17 (10MHz)=> approx 211+ ms

Edit: And by read port... I mean that is all it was doing in a tight loop.

Re: MCP23017 i2C very slow

Posted: Thu Apr 18, 2019 9:14 am
by doglike
Would you generally say, that it is better to take the SPI version ?

I did another test.
Instead of printing the time to console, I connected the switched pin of MCP to a interrupt pin of the ESP and count the pulses per second.
Result is 1000 pulses (rising+falling) per second, which means that the MCP is capable to switch the pin state within 1ms after the code line was executed.
Well, this is OK for my purposes, but generally I think this is still very slow...

Code: Select all


_uint32 volatile cntr = 0;
attachInterrupt(input_pin, intr, CHANGE)

void loop()
{
   mcp.writeGPIOAB(ON_value);
   mcp.writeGPIOAB(OFF_value);
   
   // + code for:
   // + print cntr every second to console...
   // + reset cntr to 0...
}

void intr()
{
  cntr++;
}

Re: MCP23017 i2C very slow

Posted: Thu Apr 18, 2019 10:19 am
by don01pf
SPI version is approximately 10x quicker than I2C, but needs an extra chip select line.

Have you tried running the MCP23017 faster than 400KHz?

Re: MCP23017 i2C very slow

Posted: Thu Apr 18, 2019 3:13 pm
by doglike
Yes, same results... (100kHz - 800kHz).
Faster then 800kHz didn't work at all, no idea way. According to the spec 1,7MHz should work.
Thanks for your support.

Re: MCP23017 i2C very slow

Posted: Tue Aug 11, 2020 6:40 am
by kissinno
doglike wrote:
Thu Apr 18, 2019 3:13 pm
Yes, same results... (100kHz - 800kHz).
Faster then 800kHz didn't work at all, no idea way. According to the spec 1,7MHz should work.
Thanks for your support.
800khz maxi could be due to your pull-up resistors applied to SDA and SLA.

Internal ESP32 pull-up are 30...80kOhm depending on manufacturers. For fast I2C, external 5kOhm pull-up will help a lot to achieve clean I2C levels which is mandatory for realible communication.