0
\$\begingroup\$

This is my first time having to write my own I2C code. I recently designed a board for usage with KELLER OEM Pressure Transmitter Sensor. They describe how to do that as below in the datasheet.

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

enter image description here

So I am trying to simulate that as below:

 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;

}

What I am trying to is this :
In the beggining the variable "data" is basically blank. I shift the incoming data each time Wire.read() is called, and deacrease the amount it is shifted each time. So at first it is shifted 4bytes at the end it isnt shifted at all.

I took this Adafruit code as reference.

/**************************************************************************/
/*!
    @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));
 }

I dont really know wether my code will work or not and I cant test it right away in the moment as I am working from home. Is there a common method to do what I am trying to do? I would appriciate any thoughts or input.

\$\endgroup\$
3
  • \$\begingroup\$ What is ADDR? How does data get populated from Wire.requestFrom((ADDR<<1)+1, 5);? Is there a delay between asking for sample and reading sample? Datasheet? \$\endgroup\$ Aug 5, 2021 at 0:14
  • \$\begingroup\$ @StainlessSteelRat the ADDR ist the I2C Adress, it is by default 0x40. But I leave it open ended as I am not the end user of this code. They may have multiple devices with different ADDR. The class I am writing should be able to cover them all \$\endgroup\$
    – Emre Mutlu
    Aug 5, 2021 at 0:17
  • \$\begingroup\$ @StainlessSteelRat Data doesnt get populated there. It gets populated below in while loop. I just provided a link to the whole data sheet. The request just sends the slave device a request to read. Then I catch the response in the while loop. I was guessing the wire.h library takes care of the timing, since Adafruits code also doesnt include any timing statements. \$\endgroup\$
    – Emre Mutlu
    Aug 5, 2021 at 0:29

1 Answer 1

2
\$\begingroup\$

Wire takes care of the read/write bit internally. Just pass a 7-bit ADDR without shifting.

And yes, the common usage pattern is to read one byte at a time and shift the accumulator.

Although in your case you would normally not pack the five bytes into one uint64, but have three separate variables (uint8_t status, uint16_t P, uint16_t T).

I recommend writing helper functions: read_uint8(), read_uint16(), etc.

\$\endgroup\$
2
  • \$\begingroup\$ That was going to be my comment! \$\endgroup\$ Aug 5, 2021 at 0:43
  • \$\begingroup\$ Thanks, that cleared it out for me :) \$\endgroup\$
    – Emre Mutlu
    Aug 5, 2021 at 0:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.