¿Cómo leer datos de 5 bytes de un sensor con I2C usando la biblioteca de cables?

Esta es la primera vez que tengo que escribir mi propio código I2C. Recientemente diseñé una placa para usar con el sensor transmisor de presión KELLER OEM. Describen cómo hacerlo como se muestra a continuación en la hoja de datos.

https://download.keller-druck.com/api/download/VeMYAQBxgoSNjUSHbdnBTU/en/2017-10.pdf

ingrese la descripción de la imagen aquí

Así que estoy tratando de simular eso de la siguiente manera:

 uint64_t OEMPT::read_64bit()
{
    uint64_t data = 0;
    int i = 4;

    Wire.beginTransmission(ADDR<<1);
    Wire.write(0xAC);
    Wire.endTransmission();

    Wire.requestFrom((ADDR<<1)+1, 5);

    while(Wire.available())
    {
        data = (data | (Wire.read())<<(i*8));
        
        i--;
    }
    
    return data;

}

Lo que intento es esto:
al principio, la variable "datos" está básicamente en blanco. Cambio los datos entrantes cada vez que se llama a Wire.read(), y reduzco la cantidad que se cambia cada vez. Entonces, al principio se desplaza 4 bytes y al final no se desplaza en absoluto.

Tomé este código de Adafruit como referencia.

/**************************************************************************/
/*!
    @brief Reads two bytes from the specified register
    @param reg The address of the register to read from
    @return The two bytes read from the sensor starting at the given address
*/
/**************************************************************************/
int16_t Adafruit_ADXL345_Unified::read16(uint8_t reg) {
  if (_i2c) {

    Wire.beginTransmission((uint8_t)_i2caddr);

    i2cwrite(reg);

    Wire.endTransmission();

    Wire.requestFrom((uint8_t)_i2caddr, 2);

    return (uint16_t)(i2cread() | (i2cread() << 8));
 }

Realmente no sé si mi código funcionará o no y no puedo probarlo de inmediato en este momento, ya que estoy trabajando desde casa. ¿Hay un método común para hacer lo que estoy tratando de hacer? Apreciaría cualquier pensamiento o entrada.

¿Qué es ADDR? ¿Cómo se llenan los datos de Wire.requestFrom((ADDR<<1)+1, 5);? ¿Hay un retraso entre la solicitud de la muestra y la lectura de la muestra? ¿Ficha de datos?
@StainlessSteelRat la ADDR es la dirección I2C, por defecto es 0x40. Pero lo dejo abierto ya que no soy el usuario final de este código. Pueden tener múltiples dispositivos con diferentes ADDR. La clase que estoy escribiendo debería poder cubrirlos todos.
@StainlessSteelRat Los datos no se completan allí. Se rellena a continuación en el ciclo while. Acabo de proporcionar un enlace a toda la hoja de datos. La solicitud simplemente envía al dispositivo esclavo una solicitud de lectura. Luego capturo la respuesta en el bucle while. Supuse que la biblioteca wire.h se encarga del tiempo, ya que el código de Adafruits tampoco incluye declaraciones de tiempo.

Respuestas (1)

Wire se encarga del bit de lectura/escritura internamente. Simplemente pase un ADDR de 7 bits sin cambiar.

Y sí, el patrón de uso común es leer un byte a la vez y desplazar el acumulador.

Aunque en su caso normalmente no empaquetaría los cinco bytes en un uint64, sino que tendría tres variables separadas (uint8_t status, uint16_t P, uint16_t T).

Recomiendo escribir funciones auxiliares: read_uint8(), read_uint16(), etc.

Ese iba a ser mi comentario!
Gracias, eso me aclaró :)