On 2/9/20 7:19 μ.μ., Martin Peach wrote:
On Tue, Sep 1, 2020 at 1:19 PM Alexandros <adrcki@gmail.com> wrote:
The MAX_I2C_BUF_SIZE macro in pii2c.c is set to 64, but still when I try
to send 64 bytes to a slave Teensy, only 32 go through, the rest 32 are
all 0s. Raising this value to an even greater number, like 128 (which is
something I would like to implement), gives similar results. The same
behavior occurs whether I set the I2C address as an argument to the
object, or if I pass it through the "write" message.

I checked the code and couldn't find where this occurs. I added this:

`post("%d", x->x_xferbuf[i-1]);`

to line 348 to make sure the bytes are stored in the object's buffer,
and they do get stored properly. The only place I found they end up in
is a "write()" function, called in line 293, inside the pii2c_writer()
function. I guess this function is from one of the header files included
in the object, as I couldn't find it in the code.

Long story short, is it possible to send more than 32 bytes over I2C in
the Pi? I really like [pii2c], and since wiringPi is now deprecated, I'd
like to stick to this object.

It seems to be an issue with the kernel driver. Whoever wrote it got
it into thieir head that there was a 32-byte limit. I found this
discussion:
https://stackoverflow.com/questions/25982525/why-i2c-smbus-block-max-is-limited-to-32-bytes
The same thing happens in Arduino, but there you can edit Wire.h to
get bigger messages.
I guess it will be fixed eventually.
Meanwhile, do you really need to use I2C? SPI is much faster and has
no limit to the message size. I also made a [pispi] external...
I find in general it's easier to plug an arduino into the pi to do
realtime stuff.

Martin

Plugging an Arduino straight into the Pi is surely an easier solution, but what I'm trying to do is for a more complex setup. There's already a Teensy connected to the Pi over serial and I want to be able to control more micro-controllers without definitely knowing the exact number of them. For such a case I2C is probably the best solution as it uses the same 2 pins for any number of connected devices on the same bus, whereas SPI needs at least three pins for a one-direction communication, plus an additional pin for each additional slave.

In the link you posted, in the answer there's this chunk of code:

```
i2c_write
(int file, int address, int subaddress, int size, char *data) {

    char buf[size + 1];               // note: variable length array
    ioctl(file, I2C_SLAVE, address);  // real code would need to check for an error
    buf[0] = subaddress;              // need to send everything in one call to write
    memcpy(buf + 1, data, size);      // so copy subaddress and data to a buffer 
    write(file, buf, size + 1); 
}
```
and the OP says this worked, where in the OP he mentions he needs to 
send 189 bytes. I don't really understand this bit of code, but I do see
these functions (ioctl() and write()) are used in your code as well. In
the worst case scenario I'll go with 32 bytes... I'll definitely check 
your [pispi] object though, I really like your work for interfacing Pd 
with peripherals!