adafruit / Adafruit_Blinka

Add CircuitPython hardware API and libraries to MicroPython & CPython devices
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux
MIT License
444 stars 328 forks source link

MCP2221 slow i2c, possible latency #603

Open studiostephe opened 1 year ago

studiostephe commented 1 year ago

I'm having trouble getting adequate i2c speed with the MCP2221.

According to the datasheet:

The I2C/SMBus Master module has the following capabilities: • sending/receiving data at a multitude of bit rates, up to 400 kbps

But interacting with i2c devices seems to be rate limited by something. For example, in my testing I am only able to write to my connected devices ~125 times per second. I think this is an order of magnitude slower than the expected performance but I could be wrong.

Critically, this forum post: MCP2221A has 30ms of latency per write seems to indicate there is no such latency when using the MCP2221 Command Line Interface provided my Microchip. Unfortunately that tool seems to be windows only, so I cannot test it myself (on a Mac).

This is my first time using GitHub so please forgive me!

caternuson commented 1 year ago

What is the device being written to? How many bytes are sent for each write to the device?

studiostephe commented 1 year ago

Here's my results from a pca9685, which I think is sending 2 bytes but to be honest I'm not sure! Using this code:

start=time.time()
x=0
while time.time()-start < 1:
    pca.channels[15].duty_cycle = 0xFFFF
    x+=1
print('pca9685 updates in 1 second:', x)

I get this result- pca9685 updates in 1 second: 126

Using the same code setup with an aw95230- aw9523 updates in 1 second: 126

Interestingly, with a ht16k33 it takes the same amount of time to update one pixel as it does to update 64:

with matrix[0, 0] = 1

ht16k33 1 pixel updates in 1 second: 97

with matrix.image(img)

ht16k33 64 pixel updates in 1 second: 97
freemansoft commented 1 year ago

It takes 8 seconds to write "Hello\nCircuitPython" to a 16x2 I2C LCD via the MCP2221.

  1. Windows 11 desktop that has a 16x2 LCD Pi Plate attached to it over i2c.
  2. There are four wires coming off the LCD that was intended for a gen 1 raspberry pi. 5v, Gnd, SDA, SCL.
  3. Python program is running on the desktop with "Blinka"

You can see the wiring on this blog article

Program output Output

>>> start_hello = time.perf_counter()
>>> lcd.message = "Hello\nCircuitPython"
>>> end_hello = time.perf_counter()
>>> print("draw hello time: " + str(end_hello - start_hello))
draw hello time: 8.082552099999987

Source Code

import os
import board
import hid
import adafruit_character_lcd.character_lcd_rgb_i2c as character_lcd
import time

print(hid.enumerate())
device = hid.device()
device.open(0x04D8, 0x00DD)

start_connect = time.perf_counter()
# Modify this if you have a different sized Character LCD
lcd_columns = 16
lcd_rows = 2
# Initialise I2C bus.
i2c = board.I2C()
start_connect = time.perf_counter()
# Point the driver at the bus / device
lcd = character_lcd.Character_LCD_RGB_I2C(i2c, lcd_columns, lcd_rows)
end_connect = time.perf_counter()
print("conect time: " + str(end_connect - start_connect))

# I have the RGB backlit Adafruit device
lcd.clear()
# Set LCD color to red
lcd.color = [100, 0, 0]
# Print two line message
start_hello = time.perf_counter()
lcd.message = "Hello\nCircuitPython"
end_hello = time.perf_counter()
print("draw hello time: " + str(end_hello - start_hello))

The code is located in this Source repository https://github.com/freemansoft/CircuitPython-playground

freemansoft commented 1 year ago

I ran a test with the same PC, Python, and Blinka but a different LCD and I2C backpack and got a significantly different result. Probably 10 characters per second using:

truher commented 4 days ago

curious if anybody's working on this issue? i also notice very slow performance from MCP2221, which limits its utility.

BhupiMAD commented 4 days ago

I am also having the same issue. unable to capture accelerometer data at high speed. Barely reaching 44.5Hz frequency. Can someone from adafruit shed some light on this?