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

Comment on Wire.read() reference: "slave may send less than requested" is misleading #893

Open
Koepel opened this issue Feb 16, 2021 · 2 comments
Labels

Comments

@Koepel
Copy link

Koepel commented Feb 16, 2021

In the documentation of Wire.read() is this example:

#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  Wire.requestFrom(2, 6);    // request 6 bytes from slave device arduino/Arduino#2

  while(Wire.available())    // slave may send less than requested
  {
    char c = Wire.read();    // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}

The comment "slave may send less than requested" is misleading.
Some might think that they have to wait for the rest of the bytes to arrive. Some might think that the Slave can decide to send less bytes, even when there was no bus error.

It is however inherit to the I2C protocol that the Slave can not send less or more than requested. If the Slave stops sending data, then the SDA will stay high and the Master will read 0xFF. The Master will continue to read all the bytes and does not know that the 0xFF is not valid data from the Slave. When reading data from a Slave, the Master provides the SCL clock signal, the ACK between the data bytes and the STOP at the end. The Slave has no way to influence that.

@matthijskooijman
Copy link
Collaborator

Agreed. It's not essentially wrong to say the "slave may send less than requested", but as you said, any extra bytes read are just going to be 0xff, or whatever the slave did decide to send, and checking Wire.available() is not going to tell you how much bytes were actually sent (there really is no way to detect this at all from the master).

So, what would be the proposed change here? Simply drop that comment? Or can you suggest an alternative that actually helps to understand? Or should there be a section in the documentation around this example that explains how this works for I²C?

@Koepel
Copy link
Author

Koepel commented Feb 16, 2021

It should be as simple as possible. Perhaps the next sketch can be simpler ?

My opinion is: If I ask for 6 oranges from my fridge, and it gives me 6 oranges, then it is okay.

#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop()
{
  int n = Wire.requestFrom(2, 6);  // request 6 bytes from slave device arduino/Arduino#2
  if (n == 6)                      // 6 bytes received ?
  {
    for (int i=0; i<6; i++)
    {
      char c = Wire.read();        // get a byte as character
      Serial.print(c);             // print the character
    }
  }
  delay(500);
}

@per1234 per1234 transferred this issue from arduino/Arduino Jul 17, 2022
@per1234 per1234 added the bug label Jul 17, 2022
@per1234 per1234 changed the title [Documentation] comment "slave may send less than requested" is misleading. Comment on Wire.read() reference: "slave may send less than requested" is misleading Jul 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants