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

No need to wait after Wire.requestFrom(). #3

Closed
Koepel opened this issue Jan 18, 2021 · 9 comments
Closed

No need to wait after Wire.requestFrom(). #3

Koepel opened this issue Jan 18, 2021 · 9 comments

Comments

@Koepel
Copy link

Koepel commented Jan 18, 2021

Hi, I noticed that you wait with a timeout after a Wire.requestFrom(). It is in five files.
However, there is no such thing as waiting for data, with or without a timeout. That is a myth.
Explanation: Common-mistakes#1

If you want to return -1 when the I2C devices was not found (or if there was a I2C bus problem), then you can do this:

  // Request 2 bytes from CMPS10
  Wire.requestFrom(_i2cAddress , TWO_BYTES);

  // Check if the same amount of bytes was received as was requested
  if( Wire.available() != TWO_BYTES)
    return -1;

Written in a shorter and nice way:

  // Request 2 bytes from CMPS10
  auto n = Wire.requestFrom(_i2cAddress , TWO_BYTES);
  if( n != TWO_BYTES)
    return -1;

Or in a short and ugly way:

  if( Wire.requestFrom(_i2cAddress , TWO_BYTES) != TWO_BYTES) return -1;
@pwesson
Copy link
Owner

pwesson commented Jan 23, 2021

Thank you Koepel for saying. I see you have mentioned this before back in 2016.
sparkfun/SparkFun_MMA8452Q_Arduino_Library#5

@pwesson pwesson closed this as completed Feb 14, 2021
@Koepel
Copy link
Author

Koepel commented Feb 14, 2021

There is not a single Wire-compatible library or faster processor, where the Wire.requestFrom() returns before everything is received. That is not possible. Nothing appears later. Not a single byte on earth did ever appear later for as long as the Wire library exists.

I don't know why the change failed, perhaps a timing issue.

When the sensor is disconnected, your timeout prevents that the sketch halts. This issue is therefor not a real "bug", it is about code that is not needed.

@pwesson
Copy link
Owner

pwesson commented Feb 14, 2021

It would be good to have this script working without the timeout. https://www.roboticboat.uk/Teensy/Teensy40/BNO080b.html
The Teensy is communicating with an 32-bit ARM Cortex M0+ on the BNO080 Inertial Measurement Unit (IMU). The Cortex is probably up to something.

@pwesson pwesson reopened this Feb 15, 2021
@pwesson
Copy link
Owner

pwesson commented Feb 16, 2021

There is not a single Wire-compatible library or faster processor, where the Wire.requestFrom() returns before everything is received.

So are you saying the online Arduino help documentation is wrong? https://www.arduino.cc/en/Reference/WireRead
That states "// slave may send less than requested". I believe you say this will never happen?

@Koepel
Copy link
Author

Koepel commented Feb 16, 2021

Yes, it's wrong.

When the I2C device is not connected at all, then Wire.available() returns zero.
When the hardware detected a bus collision, then Wire.available() returns zero. In theory, the Wire.available() could return the number of valid bytes before the bus collision did occur. However, at this moment the Wire.available() returns a zero.

It is inherit to the I2C protocol that when a Master reads a number of bytes from a Slave, then the Slave can do nothing to send less or more bytes. Therefor that comment is at least misleading.

That is why my advice for Wire.requestFrom() is: "It is therefor better to first check for errors and if there are no errors, then read all the bytes".
When you look at my first post of the issue, you see that I check if the same number of bytes was received as was requested. Then I know that everything was okay.

You might try to see what happens when you search with this: https://www.google.com/search?q=site%3Agithub.com+%22no+need+to+wait%22.

@Koepel
Copy link
Author

Koepel commented Feb 16, 2021

I have made an issue for the documentation: arduino/reference-en#893

@pwesson
Copy link
Owner

pwesson commented Feb 16, 2021

Koepel some scripts that gave the idea of waiting are here. https://www.robot-electronics.co.uk/htm/arduino_examples.htm#CMPS12/11%20I2C

The CMPSs should be fine - so I'm updating the code. But the BNO080 still has issues.

Does the I2C wire library allow time stretching?

@Koepel
Copy link
Author

Koepel commented Feb 16, 2021

I know there are many bad examples.

The Arduino Wire library supports clock pulse stretching, otherwise an Arduino board as a I2C Slave would not work.
Communicating with a BNO080 is communicating with a processor. Sometimes a Master with a very fast processor can send a command or register address and directly request data, and the Slave is not ready for that yet. In that case just 1 ms delay is often enough. Sometimes a sensor needs a lot of time to perform a command.

The code should work in the first place and it is not a real bug. You can keep it as it is and add comment to the header.

Thank you for testing and notifying that is not longer worked. That means this issue is the same as this one at Sparkfun: sparkfun/SparkFun_BNO080_Arduino_Library#3

@pwesson
Copy link
Owner

pwesson commented Feb 17, 2021

Library updated.

@pwesson pwesson closed this as completed Feb 17, 2021
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