Skip to content

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

Open
@Koepel

Description

@Koepel

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.

Activity

matthijskooijman

matthijskooijman commented on Feb 16, 2021

@matthijskooijman
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

Koepel commented on Feb 16, 2021

@Koepel
Author

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);
}
transferred this issue fromarduino/Arduinoon Jul 17, 2022
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[/+] on Jul 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @matthijskooijman@per1234@Koepel

        Issue actions

          Comment on `Wire.read()` reference: "slave may send less than requested" is misleading · Issue #893 · arduino/reference-en