Open jabrena opened 7 years ago
Hi @jabrena,
if(lseek(gyro_direct_fd, 0x42, SEEK_SET)==-1)
make the next read (or write) starting from 0x42 (the register of CruizCore Accumalated Angle LSB).
Die("lseek(gyro_direct_fd, 0x42, SEEK_SET)==-1");
If anything goes wrong kill the program explaining why (AFAIR my Die also interpreted errno)
if(read(gyro_direct_fd, (char*)(&val), 2)!=2)
read 2 bytes to the memory location pointed by the addresss of val. This happens to be both LSB (0x42) and MSB (0x43).
Die("gyro_direct fd\n");
if anything goes wrong kill the program explaining why.
read
is a C function that just reads a block of memory to the location pointed by some pointer. The location here is &val
which is address of val
.
The cast to (char*)
is not needed here. read
expects pointer to void*
and every pointer can be cast implicitly to void*
. I suppose I did the cast out of habbit (with meaning - interpret as block of memory of bytes).
If you are interested you should probably be reading the code in ev3dev-mapping-modules which was written with more consideration than here. Here the intention was proof-of-concept (code as quickly as possible to get the result).
Hi @bmegli, do you know what is the meaning of LSB & MSB? Once you have both values, do you do some calculus with them?
Cheers
do you know what is the meaning of LSB & MSB
LSB - Least Significant Byte MSB - Most Significant Byte
Once you have both values, do you do some calculus with them?
Apart from loading them in the correct order for Little Endian machine, into U2 signed short integer interpreted memory block, no.
I am quite happy to answer any questions but...
... this code was written before @dlech pointed out that you can achieve the same result by changing the mode of the sensor in ev3dev/ev3dev/issues/445:
When initiating a message using the direct attribute, we are not in an interrupt context, so we can initiate the I2C message directly without queuing it, which is why it appears to work faster. The same effect can be achieved by setting the mode.
So you can just change the mode of the sensor to ANGLE
and use the value0
which does practically the same as above mentioned code does (that is - blocking read on demand).
Not to have misunderstanding here the equivalent of the above code is:
ANGLE
whenever you want to read the valuevalue0
Like I said this is not the code you should be learning from, unless you want to have it the hard way (for some reason).
Hi @bmegli,
I will put in context. I am trying to solve a problem with the sensor in EV3G: https://github.com/ilovenetruinos/ev3g-odometry/issues/28 https://github.com/ilovenetruinos/ev3g-odometry/issues/29
so, I am not using the ev3dev platform and this is the situation. With the visual environment, it is not possible to reset the sensor block for a second turn and now I am learning to do a reverse engineering of the block to get the accumulative gyro rate and reset when I need.
So, you are reading the registers:
LSB - Least Significant Byte, 0x42 MSB - Most Significant Byte, 0x43
https://en.wikipedia.org/wiki/Least_significant_bit https://en.wikipedia.org/wiki/Most_significant_bit
Reading the docs, maybe I found the key point:
The inertial sensors in the CruizCore XG1300L are factory calibrated and the measurements provided in the form of signed short integers (16 bits or two bytes).
I am trying to learn how to read 2 bytes about the register 0x42, 0x43 and later calculate this calculus from docs:
ANGLE = (MSB_256 + LSB) / 100 [degrees](0x42, 0x43) RATE = (MSB_256 + LSB) / 100 [degrees/second](0x44, 0x45)
Many thanks for the notes.
Cheers
Hi @bmegli if you prefer, we could continue the issue in your latest repo if you prefer. :)
Cheers
@jabrena,
So, you are reading the registers: LSB - Least Significant Byte, 0x42 MSB - Most Significant Byte, 0x43
LSB/MSB - I mean Least/Most Significant Byte (not bit)
A 2 byte integer will have 2 bytes MSB and LSB
ANGLE = (MSB * 256 + LSB) / 100 degrees
MSB * 256 is MSB * 2^8 which is MSB shifted 8 bits left
If you add LSB to MSB shifted by 8 bits left you get 2 byte integer value regardless of your architecture (little endian/big endian, that is regardless of order in which your machine stores bytes of multibyte numbers).
This is just like splitting ordinary (not binary) number up to 999 999 into two parts with 3 digits. To recover the value you would multiply the MSB value by 1000 (10^3) and add LSB value, so for example for 999 888 it would be 999 888=999*1000 + 888.
In binary it's the same, you just multiply by 2 to some power instead of 10 to some power (2^8=256 shifts by one byte left).
With CruizCore it is U2 encoding (Two's complement) so unless you store the calculation result in 16 bit (2 byte) signed integer which is also U2 encoded be carefull with the sign.
So:
ANGLE = (MSB * 256 + LSB) / 100 degrees
this is equivalent to what I am doing by just reading data to correct memory area.
Divided by 100 becuase this is precission with which CruizCore gives data (eg. 18000 for 180 degrees).
So yes, if you have means to read the 2 bytes with I2C from EV3G you can get the accumated angle with this calculus.
if you prefer, we could continue the issue in your latest repo if you prefer
Not really, it all is somewhat off topic so this forgotten and abandonded repository is even better
Hehehe
Hi mate,
What is the purpose of this function:
In the block, you read the register for Accumulated Angle LSB, but what is the purpose of that lines:
Cheers