Community
cancel
Showing results for 
Search instead for 
Did you mean: 
TKirv1
New Contributor II
1,797 Views

Read uint32_t value from four 8-bit registers using MRAA I2C class

Jump to solution

I am wondering how I can use the mraa I2C class to correctly read a uint32_t value from four consecutive 8-bit registers. The data is stored in the registers 0x22,0x23,0x24, and 0x25 in the i2c integral frame described here https://pixhawk.org/modules/px4flow PX4FLOW Smart Camera - Pixhawk Flight Controller Hardware Project

This is what I have tried

mraa::I2c* flow;

flow = new mraa::I2c(1);

flow->address(0x42);

uint32_t dt_flow;

for (int i=0; i<100; i++) {

dt_flow = (uint32_t)flow->readWordReg(0x22) | (uint32_t)flow->readWordReg(0x24) << 16 ;

printf("dt_flow = %d\n",dt_flow);

usleep(100000)

}

The value is time, in microseconds, since the last I2C readout, but dt_flow remains constant throughout all the iterations, when it should be changing on each loop.

I assume

(uint32_t)flow->readWordReg(0x22) | (uint32_t)flow->readWordReg(0x24) << 16

is not the correct way to read the words and combine them, but I don't know what else to try. Also I would eventually like to be able to convert the uint32_t value into a float value in terms of seconds.

Any help would be much appreciated!

-Thomas

1 Solution
NNath3
New Contributor II
85 Views

In the code you provided, you are only reading the 32-bit timer.

I was looking at the link you posted for the device, and it may be that the timer resets when you read the actual data, not the timer itself. I.e., their definition of "i2c readout" is specifically reading registers 0x00-0x15, rather than "any i2c register read".

So try this instead:

...

uint8_t bytebuffer[22];

flow->readBytes(0x00, bytebuffer, 22); // this should get the timer counting, or you can move it into the loop to time the individual transactions...

for(I=0 ; I < 100 ; I++) {

flow->readBytes(0x22, bytebuffer, 4);

dt_flow = ((uint32_t)bytebuffer[3])<<24 | ((uint32_t)bytebuffer[2])<<16 | ((uint32_t)bytebuffer[1])<<8 | (uint32_t)bytebuffer[0];

printf(...)

sleep(...)

}

...

Thanks,

View solution in original post

5 Replies
NNath3
New Contributor II
85 Views

Try something like this instead:

...

uint8_t bytebuffer[4];

for(i=0 ; i < 100 ; i++) {

flow->readBytesReg(0x22, bytebuffer, 4);

dt_flow = ((uint32_t)bytebuffer[0])<<24 | ((uint32_t)bytebuffer[1])<<16 | ((uint32_t)bytebuffer[2])<<8 | (uint32_t)bytebuffer[3];

printf(...)

usleep(...)

}

From your description, you're trying to read from 4 8-bit registers, not 1 32-bit register, and definitely not 2 16-bit registers. Also, this implementation will be slightly more efficient since you only make one call into MRAA and it keeps the bus going rather than stopping and restarting (even if the 16-bit reads would work).

Thanks,

NNath3
New Contributor II
86 Views

In the code you provided, you are only reading the 32-bit timer.

I was looking at the link you posted for the device, and it may be that the timer resets when you read the actual data, not the timer itself. I.e., their definition of "i2c readout" is specifically reading registers 0x00-0x15, rather than "any i2c register read".

So try this instead:

...

uint8_t bytebuffer[22];

flow->readBytes(0x00, bytebuffer, 22); // this should get the timer counting, or you can move it into the loop to time the individual transactions...

for(I=0 ; I < 100 ; I++) {

flow->readBytes(0x22, bytebuffer, 4);

dt_flow = ((uint32_t)bytebuffer[3])<<24 | ((uint32_t)bytebuffer[2])<<16 | ((uint32_t)bytebuffer[1])<<8 | (uint32_t)bytebuffer[0];

printf(...)

sleep(...)

}

...

Thanks,

View solution in original post

idata
Community Manager
85 Views

Hi Thomas,

 

 

Do you still need assistance with this thread?

 

 

-Sergio

 

TKirv1
New Contributor II
85 Views

I think I have figured it out,

Thanks!

-Thomas

idata
Community Manager
85 Views

Hi Thomas,

Thank you for letting us know you managed to resolve this issue and thank you nniles for helping out in this case. We encourage you to remain involved in the community.

Happy holidays!

-Sergio

 

Reply