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

Data read over I2C becomes out of sync over a slower wireless network #303

Closed
IAmNickNack opened this issue Oct 18, 2023 · 1 comment
Closed

Comments

@IAmNickNack
Copy link
Contributor

I have come across a similar issue to #16 when using I2C via the GPIO socket implementation over a slow wireless network. I did not observe the problem when running the same code locally on the Pi via the loopback interface.

I observed that any payload was intermittently ignored when requesting multiple bytes over I2C and would be delivered as preamble prior to the next requested packet.

For example, the request for 25 bytes, made over a slow network returns zero bytes:

c.p.l.pigpio.impl.PiGpioSocketImpl       : [I2C::READ] -> [0]; Register [18]; I2C Block [25 bytes]; offset=0
c.p.l.pigpio.impl.PiGpioSocketBase       : [TX] -> CMD=I2CRI(67); P1=0; P2=18; P3=4; PAYLOAD=[0x19 00 00 00]
c.p.l.pigpio.impl.PiGpioSocketBase       : [RX] <- CMD=I2CRI(67); P1=0; P2=18; P3=25; PAYLOAD=[0x]
c.p.l.pigpio.impl.PiGpioSocketImpl       : [I2C::READ] <- HANDLE=0; SUCCESS=true; RESULT=25

... the subsequent request then returns the payload:

c.p.l.pigpio.impl.PiGpioSocketImpl       : [I2C::WRITE] -> [0]; Register [16]; I2C Block [2 bytes]; offset=0
c.p.l.pigpio.impl.PiGpioSocketBase       : [TX] -> CMD=I2CWI(68); P1=0; P2=16; P3=2; PAYLOAD=[0x00 00]
c.p.l.pigpio.impl.PiGpioSocketBase       : [RX] <- CMD=I2CRI(67); P1=0; P2=18; P3=25; PAYLOAD=[0x00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]
c.p.l.pigpio.impl.PiGpioSocketImpl       : [I2C::WRITE] <- HANDLE=0; SUCCESS=true; RESULT=25

On the other hand, the same request made via sockets when using the loopback interface returns the data as expected:

c.p.l.pigpio.impl.PiGpioSocketImpl       : [I2C::READ] -> [0]; Register [18]; I2C Block [25 bytes]; offset=0
c.p.l.pigpio.impl.PiGpioSocketBase       : [TX] -> CMD=I2CRI(67); P1=0; P2=18; P3=4; PAYLOAD=[0x19 00 00 00]
c.p.l.pigpio.impl.PiGpioSocketBase       : [RX] <- CMD=I2CRI(67); P1=0; P2=18; P3=25; PAYLOAD=[0x00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00]
c.p.l.pigpio.impl.PiGpioSocketImpl       : [I2C::READ] <- HANDLE=0; SUCCESS=true; RESULT=25

The problem appears to stem from PiGpioPacket#decode assuming that all the data for the packet, including the payload, is already available from the socket stream.

I have been able to solve this in a local build of pi4j which, rather than assuming all the bytes currently available, depending on the command (e.g. I2CRI, I2CRD) takes packets p3 value as a hint for the content length to expect.

This works for my I2C use cases. I don't have an SPI or serial project on the go at the moment, so have not been able to validate those cases.

@eitch
Copy link
Member

eitch commented Oct 24, 2023

Closing, as PR merged.

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

2 participants