LSM9DS1 A 9 degree of freedom Inertial Navigation Chip #934
Replies: 50 comments
-
Posted at 2016-11-30 by ClearMemory041063 LSM9DS1 Finally the board arrived a week later than expected. I also ordered an ESP32 board which required using a for profit shipping company instead of the post office for some reason. They shipped it from Colorado to Chicago and then mailed it to the suburbs. Problems encountered when implementing the I2C interface:
Notice the var x=this.address.
The values returned are in two’s compliment.
There is quite a bit of discussion on the web about reading the temperature.
The readall function:
Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-11-30 by @gfwilliams Great - thanks for posting up! Could your timeout error have been from doing something like:
That's a common 'gotcha' in JS, since |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-01 by ClearMemory041063 So far the Arduino code for the LSM9DS1 has been ported to Espruino, but to make it really useful it should be worked into module form.
The optional options are outlined in the attached file options.js.
The code that calls the init function uses an option object containing only the options we wish to change.
The output of the substitutions made in the init function:
Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-02 by @gfwilliams This looks great - thanks! Looks like it could be ready to publish as a module soon? You could put |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-02 by ClearMemory041063 Hi @gordon. It’s tempting to go to module on this project but it’s not quite ready for that as yet. There are a number of functions that have yet to be translated. The most important one being the gyroscope calibration function. There are interrupt functions that would be difficult to use with the Sparkfun board but could be of use with the more expensive Adafruit board that brings forth the interrupt pins. As to the topic of modules, I’m looking at a module within a module design for the final product.
See attached file: aTestLSM9DS1_a.js
A module one level up:
Invoke TestM1
Invoke TestM2
Some useful resource links on the topic of using IMU sensors:
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-04 by ClearMemory041063 LSM9DS1 4 Dec 2016
Once calibrated using calls to the read accelerometer and read gyro functions with the FIFO produce an unreasonable variation in the at rest gyro readings. This variation is greatly reduced by using the FIFO in continuous mode, even limiting the FIFO to 2 samples. My hypothesis is that without the FIFO the values returned contain incomplete samples. To use the FIFO in continuous mode:
The magnetometer calibration function acquires 128 readings and for each axis determines the maximum and minimum reading, and then averages these two values to produce the zero offset value for each axis. These values are stored on the chip using a call to the magOffset function.
Attached is the code as of today. I hope to incorporate changes that will reflect the issues discussed. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-04 by ClearMemory041063 Problem posting the file. Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-05 by @gfwilliams Thanks! Yeah, calibrating is a real pain. I've even noticed with the Pucks that if you bring a magnet too close (<2cm from the case) then it can partially magnetise something on the Puck and you have to recalibrate! For working out the heading, have you come across I really quick hack would be something like this:
But I guess to do it properly you want to do it better than the nearest 90 degrees :) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-05 by ClearMemory041063 That's a cool hack. What we call Q&D (quick and dirty). Using the accelerometer readings gx, gy, gz
Acceleration -0.000249863 0.003465652 1.000553131 -0.014308162 0.198456693 |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-05 by ClearMemory041063 Tab made it post so I'll try again
Preview takes out the spaces that I tried to make the headings line up. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-06 by @gfwilliams If you treat your stuff like code (with the three backticks) then you should be able to get it to appear a bit better (I changed it above). I think it's just a typo, but you wrote
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-06 by ClearMemory041063 NormalizeG.js
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-06 by ClearMemory041063 Now working for all 8 quadrants.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-11 by Eduard I am trying to use LSM9DS1 with JavaScript. My setup is Sparkfun LSM9DS1 connected to Arduino, and then connected via Serial port to a laptop. I have node.js on a laptop. I tried Johnny-five, but it does not support LSM9DS1. Your code seems to be the only JavaScript code for that IMU. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2016-12-11 by ClearMemory041063 Hi Eduard. The Sparkfun site has C code for Arduino. This JavaScript code is under development at the moment. I plan to post some revisions in a few days. Currently I'm using a Pico with Espruino. I have not tested it on other versions of hardware. It seems plausible that it would run on other hardware running Espruino that has I2C interface. Defining the I2C pins would be the first item on a list of things to get the code running on different hardware running Espruino. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-07 by ClearMemory041063 Converting the Raw Magnetometer Counts to Calibrated Engineering UnitsThe ideal caseThree magnetometer sensors place on three orthogonal axis X, Y and Z. The real world magnetometer chipEach axis has to have an offset value applied to the raw counts to obtain a zero. Some math:Let X, Y and Z be the raw readings obtained from the magnetometer. Let R = sqrt ( X2 ^2 + Y2^2 + Z2^2), and Collect some calibration data using the Magtest.js code.Start the program and point each axis of the magnetometer toward the North magnetic pole. Finding the zero offsets and calibration valuesThe raw data are then pasted into the spreadsheet X, Y , and Z columns.
The X1 etc. columns have to be copied and pasted such that each XYZ sample is calculated. raw-offset
The formula view: raw-offset
The calculation range in Cells K8 and L7 have to be adjusted to fit the data range.
We start with the offsets in B3 ,B4, and B5 set to zero and the calibration values
The Solver function of Excel (part of the analysis tool pack add in) is used to find the offsets and calibration coefficients.
Apply solver once again this time minimizing cell L8 by changing cells
I use the Descriptive Statistics function in the analysis tool pack to analyze the X2, Y2, Z2, and R values.
Additional measures that may be applied is to remove data that produces an R value more than two standard deviations from the average R, and then recalculate the calibration values. Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-10 by ClearMemory041063 Elimination of data outside of 2 standard deviationsThe following cell formulas were used to flag data with R > Ravg + 2* Standard Deviation, data with R < Ravg – 2 *Standard Deviations. Addif combines the two test. Sort is a copy of sort but pasting the values.
The statistics before and after culling points
Compare the Range of the R and R culled items. The calibration constantsMag8Gauss 30Apr2017
Next using the calibrations. Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-10 by ClearMemory041063 Applying the CalibrationsThere are 4 values to be applied to 3 axis, for each scale and for the magnetometer, accelerometer and the gyroscope sensors. A data structure for the magnetometer calibration values
Code to apply the calibration values
Applying the Use calibration function
Listing the scales
An Output Sample
Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-10 by ClearMemory041063 Code to Read the Gyroscope and Accelerometer Using the FIFOThe Gyroscope ODR (Output Data Rate) Also Controls the Accelerometer ODR if it is On.
By setting it to 0 (Off) the Accelerometer is controlled by
Producing this output:
Changing the gyro ODR to non zero
Produces this output:
Some NotesG is Gyro X,Y ,and Z raw counts. A= Accelerometer X,Y, and Z raw counts. Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-11 by @gfwilliams Thanks for posting this! There's an internal FIFO? That could really help with power efficiency in some devices - in Puck.js for instance I have to wake it up every time a reading is received. It'd be great to be able to wake up only every so often and drain the FIFO. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-11 by ClearMemory041063 @gordon |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-12 by ClearMemory041063 Accelerometer/Gyroscope BitsUsed as input to AGread and AGwrite functions. General Control BitsBOOTReboot memory content. Default value: 0 (0: normal mode; 1: reboot memory content)
BDUBlock data update. Default value: 0 (0: continuous update; 1: output registers not updated until MSB and LSB read) H_LACTIVEInterrupt activation level. Default value: 0 PP_ODPush-pull/open-drain selection on the INT1_A/G pin and INT2_A/G pin. SIMSPI serial interface mode selection. Default value: 0 IF_ADD_INCRegister address automatically incremented during a multiple byte access with a BLEBig/Little Endian data selection. Default value 0 SW_RESETSoftware reset. Default value: 0 DRDY_mask_bitData available enable bit. Default value: 0 I2C_DISABLEDisable I2C interface. Default value: 0 ST_GAngular rate sensor self-test enable. Default value: 0 ST_XLLinear acceleration sensor self-test enable. Default value: 0 Gyro Configuration BitsSLEEPGGyroscope sleep mode enable. Default value: 0 ODR_GGyroscope output data rate selection. Default value: 000 Table 46
Table 47.
FS_GGyroscope full-scale selection. Default value: 00 BW_GGyroscope bandwidth selection. Default value: 00 G_INT_SELINT selection configuration. Default value: 00 (Refer to Figure 28) G_OUT_SELOut selection configuration. Default value: 00 (Refer to Figure 28) G_LP_modeLow-power mode enable. Default value: 0 G_HP_ENHigh-pass filter enable. Default value: 0 HPCF_GGyroscope high-pass filter cutoff frequency selection. Default value: 0000 Table 52
SignX_GPitch axis (X) angular rate sign. Default value: 0 SignY_GRoll axis (Y) angular rate sign. Default value: 0 SignZ_GYaw axis (Z) angular rate sign. Default value: 0 Orient_GDirectional user orientation selection. Default value: 000 REF_GReference value for gyroscope’s digital high-pass filter (r/w). Accelerometer BitsDec_XLDecimation of acceleration data on OUT REG and FIFO. Default value: 00 Zen_XLAccelerometer’s Z-axis output enable. Default value: 1 Yen_XLAccelerometer’s Y-axis output enable. Default value: 1 Xen_XLAccelerometer’s X-axis output enable. Default value: 1 ODR_XLOutput data rate and power mode selection. default value: 000 Table 68
FS_XLAccelerometer full-scale selection. Default value: 00 BW_SCAL_ODR_XLBandwidth selection. Default value: 0
BW_XLAnti-aliasing filter bandwidth selection. Default value: 00 HR_XLHigh resolution mode for accelerometer enable. Default value: 0 Table 71
DCF_XLAccelerometer digital filter (high pass and low pass) cutoff frequency selection: the bandwidth FDS_XLFiltered data selection. Default value: 0 HPIS1_XLHigh-pass filter enabled for acceleration sensor interrupt function on Interrupt. Default Temperature BitsFIFO_TEMP_ENTemperature data storage in FIFO enable. Default value: 0 FIFO Control BitsFIFO_ENFIFO memory enable. Default value: 0 STOP_ON_FTHEnable FIFO threshold level use. Default value: 0 FIFO_TEMP_ENTemperature data storage in FIFO enable. Default value: 0 FMODEFIFO mode selection bits. Default value: 000 Table 84
FTHFIFO threshold level setting. Default value: 0 0000 FIFO StatusFTHstatusFIFO threshold status. OVRN 0FIFO overrun status. FSS 0Number of unread samples stored into FIFO.
Interrupt Control BitsSLEEP_ON_INACT_ENGyroscope operating mode during inactivity. Default value: 0 ACT_THSInactivity threshold. Default value: 000 0000 ACT_DURInactivity duration. Default value: 0000 0000 AOI_XLAND/OR combination of accelerometer’s interrupt events. Default value: 0 D66-direction detection function for interrupt. Default value: 0 ZHIE_XLEnable interrupt generation on accelerometer’s Z-axis high event. Default value: 0 ZLIE_XLEnable interrupt generation on accelerometer’s Z-axis low event. Default value: 0 YHIE_XLEnable interrupt generation on accelerometer’s Y-axis high event. Default value: 0 YLIE_XLEnable interrupt generation on accelerometer’s Y-axis low event. Default value: 0 XHIE_XLEnable interrupt generation on accelerometer’s X-axis high event. Default value: 0 XLIE_XLEnable interrupt generation on accelerometer’s X-axis low event. Default value: 0 THS_XL_XX-axis interrupt threshold. Default value: 0000 0000 THS_XL_YY-axis interrupt threshold. Default value: 0000 0000 THS_XL_ZZ-axis interrupt threshold. Default value: 0000 0000 WAIT_XLWait function enabled on duration counter. Default value: 0 DUR_XL6Enter/exit interrupt duration value. Default value: 000 0000 INT1_IG_GGyroscope interrupt enable on INT 1_A/G pin. Default value: 0 INT1_IG_XLAccelerometer interrupt generator on INT 1_A/G pin. Default value: 0 INT1_FSS5FSS5 interrupt enable on INT 1_A/G pin. Default value: 0 INT1_OVROverrun interrupt on INT 1_A/G pin. Default value: 0 INT1_FTHFIFO threshold interrupt on INT 1_A/G pin. Default value: 0 INT1_BootBoot status available on INT 1_A/G pin. Default value: 0 INT1_DRDY_GGyroscope data ready on INT 1_A/G pin. Default value: 0 INT1_DRDY_XLAccelerometer data ready on INT 1_A/G pin. Default value: 0 INT2_INACTInactivity interrupt output signal. Default value: 0 INT2_FSS5FSS5 interrupt enable on INT2_A/G pin. Default value: 0 INT2_OVROverrun interrupt on INT2_A/G pin. Default value: 0 INT2_FTHFIFO threshold interrupt on INT2_A/G pin. Default value: 0 INT2_DRDY_TEMPTemperature data ready on INT2_A/G pin. Default value: 0 INT2_DRDY_GGyroscope data ready on INT2_A/G pin. Default value: 0 INT2_DRDY_XLAccelerometer data ready on INT2_A/G pin. Default value: 0 IG_XL 0, IG_XL2 0Accelerometer interrupt output signal. Default value: 0 IG_G 0, IG_G2 0Gyroscope interrupt output signal. Default value: 0 INACT 0, INACT2 0Inactivity interrupt output signal. Default value: 0 BOOT_STATUS 0, BOOT_STATUS2 0Boot running flag signal. Default value: 0 TDA 0, TDA2 0Temperature sensor new data available. Default value: 0 GDA 0, GDA2 0Gyroscope new data available. Default value: 0 XLDA 0, XLDA2 0Accelerometer new data available. Default value: 0 IA_GGyro Interrupt active. Default value: 0 ZH_GGyro Yaw (Z) high. Default value: 0 ZL_GGyro Yaw (Z) low. Default value: 0 YH_GGyro Roll (Y) high. Default value: 0 YL_GGyro Roll (Y) low. Default value: 0 XH_GGyro Pitch (X) high. Default value: 0 XL_GGyro Pitch (X) low. Default value: 0 IA_XLAccelerometer Interrupt active. Default value: 0. ZH_XLAccelerometer's Z high event. Default value: 0 ZL_XLAccelerometer's Z low event. Default value: 0 YH_XLAccelerometer's Y high event. Default value: 0 YL_XLAccelerometer's Y low event. Default value: 0 XH_XLAccelerometer's X high event. Default value: 0 XL_XLAccelerometer's X low. event. Default value: 0 Latest version of the LSM9DS1.js module is attached. If you need a way to cool your coffee or tea and need to stretch here is a different kind of project.
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-15 by ClearMemory041063 Calibrating the AccelerometerThe procedure is similar to the magnetometer calibration but several things are done differently.
We need a way to signal the program that the sensor is positioned and ready to acquire some data.With WebIDE this can be achieved by reassigning the console with the setConsole() function.
The attached file CollectAGdata.js combines the above menu program with AGtest1.js to produce a program that collects 32 samples and wait for a carriage return. The sensor can be repositioned and the next setting can be collected by pressing return. When finished type any character followed by a return to exit the program. The data are then copied from the WebIDE left pane and pasted nto a .CSV file. Some example output:
The data are then pasted in a spreadsheet similar to the one used for the magnetometer and the twelve calibration values are calculated. Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-16 by ClearMemory041063 The Accelerometer and Gyroscope CalibrationsAccelerometer May12 2017 2g scale using average RCulled Range = 2230.842
Accelerometer May12 2017 2g scale using target valueCulled Range = 2159.087
Gyroscope May12 2017 245deg per s.Offsets Only as I’m not set up to spin the sensor and collect data.
See attached files Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-19 by ClearMemory041063 AGmagtest1.jsThe attached program AGmagtest.js uses the LSM9DS1.js module and the preceding calibrations to produce data in engineering units. The variable autocalc controls the type of units displayed.//autocalc 0=raw, 1=raw-offset, 2 Engineering Units In the function setupAG() the gyro ODR determines if gyro data are available.W.AGwrite(W.REGval.ODR_G,1);//do gyro and acceleration Here is sample output with autocalc=2 and ODR_G=1M magnetometer values are in Gauss,
Changing ODR_G to 0 produces:
Attachments: |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-19 by @allObjects ...I expected you to put the sensor onto the stirling engine fly wheel... a centered / balanced puck and sensor would work to measure the RPM. ;-) |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-20 by ClearMemory041063 Now that's an interesting idea. The flywheel shaft is 10mm long with a crank on each end, so there's not much room for the Puck. Perhaps a photo interrupter with a tab on the flywheel would be easier for RPM sensing. |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-20 by ClearMemory041063 Correction to AGMagtest1The index values were corrected in the displayAg() function when set to display Accelerometer and Magnetometer values. AGMagtest2.js is attached. Adding the Rodrigues.js module to level the compassThe background for this module is described here: The basic idea is to take the accelerometer readings and determine the vector transformation needed to level the compass. This is done with the function A=FF.Setup(AA,[0,0,1]); where FF is an instance of Rodrigues. The tilt angle theta is then available and subsequent calls to the function BB=FF.RotVector(t) will transform other vectors (magnetometer) into level coordinates.
Changing W.AGwrite(W.REGval.ODR_G,0);//do acceleration only produces the following output:
|
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-21 by @allObjects Why would you use a I know hat this pattern is typical for connecting devices. But in this case, it is just a transformer, isn't? To return a constructor function in a require, just set the exported object to it: If you want to stick with the pattern, you can return |
Beta Was this translation helpful? Give feedback.
-
Posted at 2017-05-23 by ClearMemory041063 Thanks for the input @allObjects |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Posted at 2016-11-21 by ClearMemory041063
TestLSM9DS1.js
21 Nov 2016
Using a Pico 1v88
I’m starting work on an I2C driver for the Sparkfun 9DoF Sensor Stick
https://www.sparkfun.com/products/13944
3-axis Magnetometer, Gyro and Accelerometer.
As a starting point I’ve downloaded the Arduino Library from
https://github.com/sparkfun/SparkFun_LSM9DS1_Arduino_Library
The board is scheduled to arrive tomorrow. The attached Espruino code has been derived from the Arduino library. TestLSM9DS1.js
A few functions related to the I2C have been stubbed until the board arrives and testing can begin. Additional functions beyond the basics have yet to be added.
Any suggestions on writing the stubbed I2C functions are welcome.
The current output of the stubbed code:
Attachments:
Beta Was this translation helpful? Give feedback.
All reactions