Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read_i2c_block_data very slow #108

Open
arcadeperfect opened this issue Mar 21, 2024 · 0 comments
Open

read_i2c_block_data very slow #108

arcadeperfect opened this issue Mar 21, 2024 · 0 comments

Comments

@arcadeperfect
Copy link

I am trying to send data from an rp2040 to a raspberry pi via i2c. I am using Arduino on the rpi2040 and python on the raspberry pi.

The use case is similar to that of a midi controller; the data bandwidth doesn't need to be particularly high but the latency and frequency need to be fast.

The following, in which I request one byte at a time works well, with very fast throughput, meaning it is printing hundreds of bytes per second. I suspect the bottleneck is actually the print, even though it's inducing the overhead of a new request for every single byte:

Aruino:

#include <Wire.h>

const int ADDRESS = 0x08;      // I2C address
volatile int tenBitValue = 0;  // 10-bit value
volatile byte val = 0;         // 8-bit value to be transmitted

void setup() {
  Serial.begin(115200);
  Wire.begin(ADDRESS);
  Wire.setClock(400000);  // Set I2C clock speed to 400kHz
  Wire.onRequest(sendData);
}

void loop() {
  tenBitValue = analogRead(A0);  // Example: read value from analog pin A0
  val = map(tenBitValue, 0, 1023, 0, 255);
  Serial.println(val);
}

void sendData() {
  Wire.write(val);  // Send the 8-bit value
}

Python:

import smbus

device_address = 0x08

while True:
	print(bus.read_byte(device_address))

However I need more than one byte. The following, in which I use the block_data function and specify 2 bytes, and send 2 bytes from the arduino, is sending maybe 5 - 10 bytes a second which orders of magnitude slower than 1 byte at a time and won't work for my use case:

Arduino:

#include <Wire.h>

const int ADDRESS = 0x08;      // I2C address
volatile int tenBitValue = 0;  // 10-bit value
volatile byte val = 0;         // 8-bit value to be transmitted

void setup() {
  Serial.begin(115200);
  Wire.begin(ADDRESS);
  Wire.setClock(400000);  // Set I2C clock speed to 400kHz
  Wire.onRequest(sendData);
}

void loop() {
  tenBitValue = analogRead(A0);  // Example: read value from analog pin A0
  val = map(tenBitValue, 0, 1023, 0, 255);
  Serial.println(val);
}

void sendData() {
  Wire.write(val);  // Send the 8-bit value
  Wire.write(234);  // Send dummy data
}

Python:

import smbus

device_address = 0x08

while True:
	print(bus.read_i2c_block_data(device_address, 0, 2))
  • Printing from the main loop on rp2040 to the serial port of my dev machine happens at expected speed even when the i2c connection is active.
  • Printing from the actual callback in the arduino code rather than the arduino loop is exactly as slow as the data received by the python script, which makes sense since it's responding to requests.
  • Note that with 2 bytes it is much, much more than 2 times slower.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant