usefulsensors/person_sensor_arduino

Does not work, tries to read too many bytes from Wire library

jschrempp opened this issue · 7 comments

In person_sensor.h the size of person_sensor_results_t is 40 bytes.

The on line 82 you wait for that many bytes to be available from the Wire library.

if (Wire.available() != sizeof(person_sensor_results_t)) {

However, this reference https://www.arduino.cc/reference/en/language/functions/communication/wire/ says that the Wire library on Arduino will only read 32 bytes, "the rest are discarded".

It looks like I got it running on the Particle.io Argon by just reading 32 bytes. Of course this isn't good, but shows that this is the problem in your code.

If you think I'm correct, I'll submit a fix. But if I'm wrong about this, please let me know what should work.

Thanks for letting us know, and even diagnosing the issue!

It looks like we got lucky on the Arduino boards we've been testing with. I've ordered an Argon to reproduce the problem, it should hopefully arrive this week. I'm hoping the fix will just be reading 32 bytes, then 8 bytes, in two separate calls?

I'm unsure about other boards, but the Particle.io platform allows you to read more than 32 bytes (up to 512). Here's the code I got from them.

constexpr size_t I2C_BUFFER_SIZE = 40;

HAL_I2C_Config acquireWireBuffer() {
    HAL_I2C_Config config = {
        .size = sizeof(HAL_I2C_Config),
        .version = HAL_I2C_CONFIG_VERSION_1,
        .rx_buffer = new (std::nothrow) uint8_t[I2C_BUFFER_SIZE],
        .rx_buffer_size = I2C_BUFFER_SIZE,
        .tx_buffer = new (std::nothrow) uint8_t[I2C_BUFFER_SIZE],
        .tx_buffer_size = I2C_BUFFER_SIZE
    };
    return config;
}
void setup() {
  HAL_I2C_Config config = acquireWireBuffer();
  hal_i2c_init(HAL_I2C_INTERFACE1, &config);
  Wire.begin();

Then your code worked. (Although I did not use your "inline" qualifier, I moved the code into a separate .h/.cpp file set to debug it and that's what is working now.)
Jim

Great, thanks, that's very helpful! I'll dig in a bit more to see what cross-platform solutions exist too, but just knowing what the underlying issue is makes it a lot easier.

I've updated the code to read in chunks and confirmed it now works on an Uno. If you get a chance, could you take a look @jschrempp and confirm it works for you too? Thanks for your patience!

This new code worked on a Particle.io Argon running 3.3.0.

Great, thanks again @jschrempp!

Just to update this - I'm working with a new sensor that outputs a 256 byte packet, and the chunked reading code appears to produce incorrect results. In particular it just seems to repeat the first 32 bytes read from the sensor in every chunk, despite the third argument to Wire.requestFrom() being zero, which should mean continue from the last read position. This is on an Arduino Nano Sense BLE 33, I haven't had a chance to test on other boards.

I don't have time to dig deeply into at the moment, but I wanted to at least leave a trail of breadcrumbs for anyone else who hits this.