Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Library Dev for XRP IMU for Gyro Sensor #1

Open
scspaeth opened this issue Apr 18, 2024 · 8 comments
Open

Library Dev for XRP IMU for Gyro Sensor #1

scspaeth opened this issue Apr 18, 2024 · 8 comments

Comments

@scspaeth
Copy link

I tried to add the MicroBlocks program that you requested as an attachment to this issue. GitHub refused to accept it because they don't support that file type. I'll try another way.

@scspaeth
Copy link
Author

GP Scripts
depends 'PicoW-XRP_v1.1'

spec 'r' 'LSM6DSOX_gyro' 'LSM6DSOX _' 'auto' 10
to LSM6DSOX_gyro i2c_get_block {
comment 'LSM6DSOX is an i2c device that senses acceleration and gyroscopic motion.
This block takes an i2c_get_block with address and register parameters
described in the datasheet.
IMUs in this family are used on other platforms so Acc data are part of the basic sensors library.
Gyroscopes are less frequently used on platforms so we need this Gyro library.
The LSM6DSOX has additional functions but they are not developed in this library.'
local 'val' 0
val = i2c_get_block
if (val >= 128) {
val = (val - 256)
} else {
val = val
}
if (val < -127) {
val = -127
}
val = ((val * 200) / 127)
return val
}

script 1271 103 {
comment 'LSM6DSOX https://www.st.com/en/mems-and-sensors/lsm6dsox.html'
comment 'XRP''s solder jumper IMU_ADR controls the IMU address.
Default value is 0X6B (107). NOTE: differs from the Clue address which is 0X6A.0X
Can be changed semi-permanently to 0X6A by cutting the jumper.
Ref: https://docs.sparkfun.com/SparkFun_XRP_Controller/hardware_overview/#solde6B'
comment '23-10-11: verified that these scripts work for reading Clue Acc and Gyr.
Determined that XRP uses the alternate IMU address(107).
Substituted the XRP_IMU_adr and tested scripts for both Acc and Gyr
Did not work for either Acc or Gyr.
Tried using the H/L alternate registers. Neither of them worked.'
comment 'Try getting accXRaw data out and only get 0 responses.
Then set the accelerometer device register 0x10 to 0x80 for 1660 Hz rate
Try to get accXRaw data out after initializing.
Success for Clue but not for XRP with a RPiPicoW vm!
Switched vm to Pico.ed and now it works for getting IMU data
but other XRP functions that work for PicoW.vm no longer work.
TODO: need to create a XRP.vm that leaves the PicoW functionality intack
and accomodates the pin assignments for the IMU that Pico.ed uses. '
comment '23-10-13:
i2c get device reports error codes indicating no i2c devices connected.
Found pin assignments for XRP i2c are sda:19, scl: 18. Clue uses a different pair
So it makes sense that (i2c get device) won''t find data from the IMU.
These i2c pin assignments are made in the platform specific vm firmware:
https://bitbucket.org/john_maloney/smallvm
/src/88d530121f450a22cb4c42cd593b243dd6a5b923/vm/sensorPrims.cpp#lines-23:27
Coincidentally, the designers of the Electfreaks pico-ed board chose the same pair of pins
for their design. So, I am testing the possibility that using the pico-ed firmware will make it possible
to read the XRP''s IMU. Of course, other functions of the XRP will not work properly but I will know
whether it is worth the time and effort to create a platform specific firmware for the XRP.
Result: YES the pico-ed firmware allows Microblocks to address the XRP''s IMU and
pull acc and gyro data from it.
With success in getting data out of the IMU, I now have confidence to create the platform specific
vm using PlatformIO. I took an existing vm and simply tried to build it and load onto bare RPiPico-W.
Commented out the m5stack+ envioronment because it gave error messages for non-conformance.
Needed to save the file to get PlatformIO to accept my changes.
Results: pico-w SUCCESS 00:04:34.951
The OSX finder complained that the device was removed unexpectedly.
The Microblocks IDE connected to the board and ran the [set user LED (Or)] as intended! '
}

script 1332 783 (i2cGet XRP_IMU_adr (hexToInt '2_'))

script 458 2085 {
to LSM6DSOX_gyro i2c_get_block {}
}

script 454 96 {
comment 'Open the Graph Display.
Start this script.
Change the pitch, roll and yaw to see responses as scaled angular velocities.'
'_xrp_init_pins'
XRP_IMU_adr = (hexToInt '6B')
sayIt 'Setting IMU adr Clue:6A, XRP:6B'
waitMillis 1000
i2cSet XRP_IMU_adr (hexToInt '10') (hexToInt '80')
sayIt 'Initializing the gyro registers of the IMU'
waitMillis 1000
comment 'Reference: https://www.st.com/resource/en/datasheet/lsm6dsl.pdf p.61

Try getting gyrXRaw data out and only get 0 responses.
Then set the accelerometer/gyro device register 0x11 to 0x80 for 1660 Hz rate
Try to get gyrXRaw data out after initializing.
Success! The initialization activates the gyro data registers for XY and Z
Now I need to understand the scaling algorithm to get positive and negative angular velocities out.'
i2cSet XRP_IMU_adr (hexToInt '11') (hexToInt '80')
comment 'Plot gyrX,Y,Z of the XRP IMU'
repeat 1000 {
printIt (LSM6DSOX_gyro (i2cGet XRP_IMU_adr (hexToInt '23'))) (LSM6DSOX_gyro (i2cGet XRP_IMU_adr (hexToInt '25'))) (LSM6DSOX_gyro (i2cGet XRP_IMU_adr (hexToInt '27')))
waitMillis 100
}
}

script 477 812 {
comment 'Historical development and credit to prior work:'
comment 'John Maloney provides an algorithm for transforming accel raw data
into MB tilts:
https://bitbucket.org/john_maloney/smallvm/
src/1d8e7b664850a1fcd41f88e5900a57f947f6c994/vm/sensorPrims.cpp
?at=master#lines-692
He uses the short form of an if else statement.

x = (condition) ? (value_if_true) : (value_if_false);
https://cplusplus.com/forum/beginner/32292/#msg174367

I may be able to construct an equivalent expression in MB.

Yes, apparently so. I created the equivalent script in MB to the C++ in Maloney.
It produces gyrX patterns similar to what I expect for typical gyro data.
TODO: Reflect on this experiment and consolidate and improve it for sharing.'
repeat 1000 {
gyrXRaw = (i2cGet XRP_IMU_adr (hexToInt '23'))
gyrXCal = gyrXRaw
if (gyrXCal >= 128) {
gyrXCal = (gyrXCal - 256)
} else {
gyrXCal = gyrXCal
}
if (gyrXCal < -127) {
gyrXCal = -127
}
gyrXCal = ((gyrXCal * 200) / 127)
printIt gyrXCal
waitMillis 100
}
return gyrXCal
}

@scspaeth
Copy link
Author

Let me know if you'd prefer another option.

@scspaeth
Copy link
Author

Yet another representation:

XRPGyroLibDev

@scspaeth
Copy link
Author

Previous pic did not include all scripts in the file:
XRPGyroLibDev

@r-owen
Copy link
Owner

r-owen commented Apr 18, 2024

This all looks great. Thank you very much!

@scspaeth
Copy link
Author

I'm looking forward to using your work. Thank you.

@r-owen
Copy link
Owner

r-owen commented Apr 18, 2024

It works! Here is my simplified version.

module 'XPRGyro'
author SCSpaeth
version 1 0 
description 'Read XRP LSM6DSOX gyroscope rates'

spec ' ' 'read_gyro_speed' 'read_gyro_speed'
spec 'r' 'scale_gyro_speed' 'scale gyro raw speed _' 'num' 10


to read_gyro_speed {
    comment 'Open the Graph Display.
Start this script.
Change the pitch, roll and yaw to see responses as scaled angular velocities.'
    local 'XRP_IMU_addr' (hexToInt '6B')
    comment 'Set the accelerometer/gyro device register 0x11 to 0x80 for 1660 Hz rate
        This activates the gyro data registers for X, Y and Z.
        Reference: https://www.st.com/resource/en/datasheet/lsm6dsl.pdf p.61'
    i2cSet XRP_IMU_addr (hexToInt '11') (hexToInt '80')
    comment 'Plot gyrX,Y,Z of the XRP IMU'
    repeat 300 {
        printIt (
            scale_gyro_speed (i2cGet XRP_IMU_addr (hexToInt '23'))) (
            scale_gyro_speed (i2cGet XRP_IMU_addr (hexToInt '25'))) (
            scale_gyro_speed (i2cGet XRP_IMU_addr (hexToInt '27'))
        )
        waitMillis 100
    }
}

to scale_gyro_speed speed {
    comment 'Scale raw LSM6DSOX gyroscope speed data (to what units?).
Valid raw speed values are between 0 and 255, inclusive,
with the following unusual subranges:
* 0-127 represents positive values 0 through 127,
* 128-255 represents negative values -128 through -1.'
    comment 'Handle negative values.'
    if (speed >= 128) {
        speed = (speed - 256)
    }
    comment 'Scale the result to unknown units'
    speed = ((speed * 200) / 127)
    return speed
}

@scspaeth
Copy link
Author

I'm pleased to see that this helped your work. I'll try to find time for some testing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants