- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
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,
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
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,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
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,
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
Hi Thomas,
Do you still need assistance with this thread?
-Sergio
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
I think I have figured it out,
Thanks!
-Thomas
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
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

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page