-
Hi @allObjects I hope to get back to the leveling code once I've got a calibrate IMU to work with.
I think it should exist as a separate object from the IMU code so it can be applied to other systems.
As to the viability on your boat, that remains to be seen.
Using the accelerometer to level the magnetometer readings is subject to accelerations such as experienced when turning, or an airplane in a banked turn.
Thanks for your interest. -
Attached are two modules that implement an I2C interface with the LSM9DS1.
These modules should be placed in the modules directory of your WebIDE project.
The module slimLSM9DS1.js is tested by the program testslimLSM9DS1.js
The module calibrateLSM9DS1.js is tested by the program testcalibrateLSM9DS1.js and loads the slimLSM9DS1.js module as well. The test program performs the calibration that the Sparkfun code performed. Options to perform a more robust calibration are coded but not yet tested as this requires a menu system.
Several functions have been added to allow the scales, output data rate and filters to be changes on the accelerometer, gyro and magnetometer.
The calibrations in the attached code has not been performed on every scale of the three sensors. In the next development phase a menu program will allow a full calibration to be performed.
The moff, goff and aoff contain the zero offsets for each axis for each scale
The mres, gres and ares contain the scale factors for each axis for each scale
g=gyro, a= accelerometer, m= magnetometerthis.mScale=0;//0,1,2,3 index into mscale this.mscale=[ //the mres is the scale factor for each axis {scale:4,regvalue:0, mres:[0.000122,0.000122,0.000122], moff:[0,0,0] //zero offset in counts }, //// this.gScale=0;//0,1,2 index into gyroscale this.gyroscale=[ //the gres is the scale factor for each axis {scale:245,regvalue:0, gres:[245/32768.0,245/32768.0,245/32768.0], goff:[0,0,0] //zero offset }, //// this.aScale=0;//0,1,2,3 index into accelscale this.accelscale=[ //the ares is the scale factor for each axis {scale:2,regvalue:0, ares:[2/32768.0,2/32768.0,2/32768.0], aoff:[0,0,0] },
These structures along with autocalc variable determine the type of output. The following shows this for the accelerometer. Similar code is used for the magnetometer and gyro.
LSM9DS1.prototype.readAccel=function(){ var temp=this.xgReadBytes(Regs.OUT_X_L_XL, 6); var i; // Read 6 bytes, beginning at OUT_X_L_XL this.a[0]=this.twos_comp(temp[0],temp[1]); this.a[1]=this.twos_comp(temp[2],temp[3]); this.a[2]=this.twos_comp(temp[4],temp[5]); if (this.autoCalc>0){ for(i=0;i<3;i++) this.a[i] -= this.accelscale[this.aScale].aoff[i]; //this.aBiasRaw[i]; }//endif if (this.autoCalc>1){ for(i=0;i<3;i++) this.a[i]=this.a[i]*this.accelscale[this.aScale].ares[i]; }//endif };//end readAccel
-
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.
I have zero experience with the Johnny-five system. -
Now working for all 8 quadrants.
On to doing the rotations for the magnetometer vector to do final proof of concept.
Then to see if pre-multiplying the matrices (using Maxima) and using simpler code will work.
Finally how well will it work with data from the chip?
Didn't use atan2. used the abs(atan) and then the sign of the original x,y values to set the matrix rotation direction and the z value to control if the final matrix is needed. -
NormalizeG.js
NormalizeG.wxm
6 Dec 2016
Attached are two files that use matrix rotations on an xyz vector to produce a vector where x1=0,y1=0,z1= - sqrt(x^2+y^2+z^3)
It’s still need some work as the matrix direction values depend on the vector quadrant.
This is likely the result of computerizing the trig and algebra.
The goal is to use the matrices and accelerometer readings to level the magnetometer readings and produce a compass heading.
The file with the wxm extension can be opened using the Maxima software.
This allows an analytic derivation as well as a numerical one.
http://maxima.sourceforge.net/ -
Tab made it post so I'll try again
X Y Z atan2(z,x) atan2(z,y) Acceleration -0.000249863 0.003465652 1.000553131 -0.014308162 0.198456693 sin(theta) cos(theta) sin(phi) cos(phi) -0.000249725 0.999999969 0.003463716 0.999994001 X1 Y1 Z1 X2 Y2 Z2 -0.000249863 0.003715515 1.000552234 0.003215767 0.003715515 1.000546232
Preview takes out the spaces that I tried to make the headings line up.
Better examples to follow. -
That's a cool hack. What we call Q&D (quick and dirty).
Aran2 gives -180 to 180.
theta=atan2(z,x)
if(theta<0) theta+=360. Then theta ranges from 0 to 360
For the left handed axis on this chip theta= atan(-z/x)Using the accelerometer readings gx, gy, gz
theta = atan2(gz,gx), phi=atan2(gz,gy)
rotate around yaxis
x1=gx, y1=cos(theta)*gy-sin(theta)*gz, z1=sin(theta)*gy+cos(theta)*gz
the rotate around the xaxis
x2=cos(phi)*x1+sin(phi)*z1, y2=y1, z2=-sin(phi)*x1+cos(phi)*z1
At which point z2 should be -1. X2 and Y2 should be zero
If the rotations are them applied to the magnetometer readings the compass can be leveled.
Some gotchas:
May need a minus sign in the atan2(-a/b)
May need to rotate the opposite direction by changing the sign on the sin terms( +sin becomes -sin, and -sin becomes +sin)
I captured some data earlier this morning and did some of this in a spreadsheet. It looks like it works but I want to finish the mounting fixture and change the code to load the zero calibrations rather than recalibration on each run.X Y Z atan2(x/z) atan2(y/z)
Acceleration -0.000249863 0.003465652 1.000553131 -0.014308162 0.198456693
-
Here's another way Using Bonjour to find the IP dynamic address.
It works with an ESP8266 connected via serial to a Pico or original Espruino.
Does not currently work on an ESP8266 running Espruino, it would require a recompile of the firmware.
http://forum.espruino.com/conversations/293972/ -
-
LSM9DS1 4 Dec 2016
Some progress on the calibration functions has been made. There are some problems that need to be addressed.
The first item is the word calibration itself. The functions only address part of a full calibration, the zero point. The scale is not calibrated, but simply uses the advertised values from the data sheet.
The second item is the method used to determine the zero point. For this chip there are two different calibration functions. One calibrates the accelerometer/gyro and the other calibrates the magnetometer. Addressing the accelerometer/gyro function first.
The accelerometer/gyro calibration function for the LSM9DS1 chip makes use of the FIFO hardware. The function sets up the FIFO to read 32 samples each from the accelerometer and gyro, then it averages these values to find the zero offset. The accelerometer makes the assumption that the x-y plane is parallel to a level surface, and that the z-axis is on a plumb line. It doesn’t actually find a zero offset for the z-axis.
This can be corrected by doing the x-y calibration, reposition the chip so that either the x-z or y-z plane is level and finding the zero for the z-axis.
Of note is Figure 1 in the LSM9DS1 datasheet. Notice the dot on the chip is positioned differently for the magnetometer illustration. Also as drawn the axis directions are a left-hand coordinate system.
http://www.st.com/content/ccc/resource/technical/document/datasheet/1e/3f/2a/d6/25/eb/48/46/DM00103319.pdf/files/DM00103319.pdf/jcr:content/translations/en.DM00103319.pdf
A bug was found in the previous code that froze the gyro readings. The gyro sample rate has been added to fix the bug.this.gyro_scale = 245; this.gyro_sampleRate = 6; this.gyro_bandwidth = 0;
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:
// fifoMode // FIFO_OFF = 0, FIFO_THS = 1, FIFO_CONT_TRIGGER = 3, //FIFO_OFF_TRIGGER = 4, FIFO_CONT = 5 W.enableFIFO(true); W.setFIFO(5,10); // ( fifoMode ,length<32)
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.
I’m not sure if this method is of any value. I can imagine placing the chip inside a pair of A.C Helmholtz coils as one method. I finally performed a zero offset calibration manually.
I attached the chip to a cube. I placed the cube on a level non-magnetic surface (wood) with a wooden fence (think table saw) oriented North South. I zeroed the chip offsets using a call to the magOffset function. Then I collected six sets of data.- X-axis level and pointing North
- X-axis level and pointing South
- Y-axis level and pointing North
- Y-axis level and pointing South
- Z-axis level and pointing North
- Z-axis level and pointing South
Then I used a spreadsheet to find the maximum and minimum values in pairs of data sets and averaged them. For the X offset use sets 1 and 2, for Y sets 2 and 3 and finally for Z sets 5 and 6.
These offsets are then sent to the chip after initialization using the magOffset function.
If the chip is powered down the offset values are lost (volatile).
This procedure finally produced reasonable compass heading values when the x-y plane of the chip is level. Yet to address is the heading in 0 to 360 degrees instead of -180 to 180 degrees in the wrong direction. Also I hope to add the necessary rotation matrix math that gives the compass heading in any chip orientation.
Attached is the code as of today. I hope to incorporate changes that will reflect the issues discussed.
- X-axis level and pointing North
-
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.
https://www.sparkfun.com/products/13944
https://www.adafruit.com/product/2021As to the topic of modules, I’m looking at a module within a module design for the final product.
The lowest level module uses a table to initialize the chip and functions to read the data.var xgstack= [ { "address": 107, "sub": 16, "data": 0 }, { "address": 107, "sub": 17, "data": 0 }, { "address": 107, "sub": 18, "data": 0 }, { "address": 107, "sub": 30, "data": 58 }, { "address": 107, "sub": 19, "data": 0 }, { "address": 107, "sub": 31, "data": 56 }, { "address": 107, "sub": 32, "data": 160 }, { "address": 107, "sub": 33, "data": 0 } ]; var mstack= [ { "address": 30, "sub": 32, "data": 28 }, { "address": 30, "sub": 33, "data": 0 }, { "address": 30, "sub": 34, "data": 0 }, { "address": 30, "sub": 35, "data": 12 }, { "address": 30, "sub": 36, "data": 0 } ]; LSM9DS1.prototype.run=function(){ var i; // To verify communication, we can read from the WHO_AM_I register //of each device. Store those in a variable so we can return them. var mTest = this.mReadByte(Mags.WHO_AM_I_M);// Read the gyro var xgTest = this.xgReadByte(Regs.WHO_AM_I_XG);//Read the accel/mag var whoAmICombined = (xgTest << 8) | mTest; console.log("who= ",whoAmICombined); if (whoAmICombined != ((WHO_AM_I_AG_RSP << 8) | WHO_AM_I_M_RSP)) return 0; for(i=0; i<this.xgstack.length;i++){ console.log(this.xgstack[i].address, this.xgstack[i].sub,this.xgstack[i].data); this.i2c.writeTo(this.xgstack[i].address, this.xgstack[i].sub,this.xgstack[i].data); } for(i=0; i<this.mstack.length;i++){ console.log(this.mstack[i].address, this.mstack[i].sub,this.mstack[i].data); this.i2c.writeTo(this.mstack[i].address, this.mstack[i].sub,this.mstack[i].data); } return whoAmICombined; };
See attached file: aTestLSM9DS1_a.js
At the next level of module, which invokes the first level module, the init function parses the options and the begin function populates the xgstack and mstack arrays.
This mod level module uses more memory resources but allows the tweaking of the options. Once the user is satisfied with the tweak, the stacks and some other variables are copied and pasted into a new program that uses only the first module. This will reduce the memory usage in a final program.
A similar approach seems possible for adding the calibration and interrupt functions.
A lowest level module example//TestM1.js 1 Dec 2016 function LSM9DS1() { } LSM9DS1.prototype.add=function(){ this.a=1; this.b=20; console.log(this.a+this.b); }; // Create an instance of LSM9DS1 exports.connect = function() { return new LSM9DS1(); };
A module one level up:
/TestM2.js 1 Dec 2016 exports.connect = function() { var x= require("testm1").connect(); x.d=98; x.sub= function() { console.log(this.a-this.b); }; return x; };
Invoke TestM1
//tryTestM1.js 1 Dec 2016 var ads =require("testm1").connect(); ads.add();
Invoke TestM2
//tryTestM2.js 1 Dec 2016 var ads =require("testm2").connect(); ads.add(); console.log(ads.d); ads.sub();
Some useful resource links on the topic of using IMU sensors:
https://www.intorobotics.com/accelerometer-gyroscope-and-imu-sensors-tutorials/
http://tutorial.cytron.com.my/2012/01/10/measuring-tilt-angle-with-gyro-and-accelerometer/
Kalman filter simulation
https://www.cs.utexas.edu/~teammco/misc/kalman_filter/ -
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.
There are a lot of knobs on the virtual control panel for this chip. In the previous version any changes to the knobs needed to be edited in the LSM9DS1.prototype.init function.
Today the code is modified so that the knobs are initialized to default values and an optional set of options can be supplied to the LSM9DS1.prototype.init function.
This is accomplished by changing the init function to the followingLSM9DS1.prototype.init=function(options){ var i,j; for (i=0; i<3; i++){ this.gBias[i] = 0; this.aBias[i] = 0; this.mBias[i] = 0; this.gBiasRaw[i] = 0; this.aBiasRaw[i] = 0; this.mBiasRaw[i] = 0; } //process and changes from options if(typeof options === "undefined" ) console.log("options undefined"); if(typeof options !== "undefined"){ console.log("options defined"); for(i in options){ //console.log(options); if(options.hasOwnProperty(i)){ for(j in this){//LSM9DS1){ // console.log(i,j);//,options[i],LSM9DS1[j]); if(j==i){ console.log(i,j,options[i],this[j]); this[j]=options[i]; } } } } } };
The optional options are outlined in the attached file options.js.
For example to change the acceleration sample rate from 6 to 5 :// accel sample rate can be 1-6 // 1 = 10 Hz 4 = 238 Hz // 2 = 50 Hz 5 = 476 Hz // 3 = 119 Hz 6 = 952 Hz accel_sampleRate: 6,
The code that calls the init function uses an option object containing only the options we wish to change.
function start(){ I2C3.setup({ scl :A8, sda: B4} ); var W=new LSM9DS1(I2C3); var myoptions={ //make changes to basic configuration here xgAddress: 0x6B, mAddress: 0x1e, test: 1, accel_sampleRate: 5, }; W.init(myoptions); //W.init(); console.log(W.begin()); var nn=setInterval(function () { readall(W); }, 200); }
The output of the substitutions made in the init function:
>options defined xgAddress xgAddress 107 107 mAddress mAddress 30 30 test test 1 0 accel_sampleRate accel_sampleRate 5 6
-
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.
The pony express would have been faster.Problems encountered when implementing the I2C interface:
LSM9DS1.prototype.xgReadBytes=function(subAddress,count){ var dest= new Uint8Array(count); // console.log("xgReadBytes ",this.xgAddress, subAddress|0x80, dest, count); var x=this.xgAddress; this.i2c.writeTo(x, subAddress|0x80); dest=this.i2c.readFrom(x, count); // for(var i=0;i<count;i++)console.log(dest[i]); return dest; }; LSM9DS1.prototype.mReadBytes=function(subAddress,count){ // console.log("mReadBytes ",this.mAddress, subAddress|0x80,count); var x=this.mAddress; var dest=new Uint8Array(count); this.i2c.writeTo(x, subAddress|0x80); dest=this.i2c.readFrom(x, count); // for(var i=0;i<count;i++)console.log(dest[i]); return dest; };
Notice the var x=this.address.
If this.address was used in the this.i2c.ReadFrom() function timeout errors occurred.
I tried to create a simplified version of the problem but have not succeeded in reproducing the error.
For reads of multiple bytes bit 7 of the sub-address is set to 1.LSM9DS1.prototype.readAccel=function(){ var temp=this.xgReadBytes(Regs.OUT_X_L_XL, 6); // Read 6 bytes, beginning at OUT_X_L_XL this.ax=this.twos_comp(temp[0],temp[1]); this.ay=this.twos_comp(temp[2],temp[3]); this.az=this.twos_comp(temp[4],temp[5]); /* this.ax = (temp[1] << 8) | temp[0]; // Store x-axis values into ax this.ay = (temp[3] << 8) | temp[2]; // Store y-axis values into ay this.az = (temp[5] << 8) | temp[4]; // Store z-axis values into az */ if (_autoCalc) { ax -= aBiasRaw[X_AXIS]; ay -= aBiasRaw[Y_AXIS]; az -= aBiasRaw[Z_AXIS]; } }; LSM9DS1.prototype.twos_comp=function(low,high){ var t=(high << 8) | low; return(t & 0x8000 ? t - 0x10000 : t); };
The values returned are in two’s compliment.
LSM9DS1.prototype.readTemp=function(){ //void LSM9DS1::readTemp(){ // We'll read two bytes from the temperature sensor into temp var temp=this.xgReadBytes(Regs.OUT_TEMP_L, 2); // Read 2 bytes, beginning at OUT_TEMP_L // console.log("TT= ",temp[0].toString(16),temp[1].toString(16)); this.temperature = temp[1];//(temp[1] << 8) | temp[0]; //temperature = ((int16_t)temp[1] << 8) | temp[0]; //https://gist.github.com/jimblom/08b333892ee383d6e443 //temperature = (((int16_t) temp[1] << 12) | temp[0] << 4 ) >> 4; // Temperature is a 12-bit signed integer //var t= (((temp[1]^0xf)<<12)|temp[0])>>4; //this.temperature=(t & 0x8000 ? t - 0x10000 : t); };
There is quite a bit of discussion on the web about reading the temperature.
Having tried various solutions, I’m still not sure it is working properly.
The file TestLSM9DS1_d.js is attached.
Some sample output:Acceleration -0.0087890625 -0.09417724609 1.02032470703 Gyro -810 294 75 Magnetometer 1379 1413 -2029 Temperature 246 Level -0.49353282241 -5.27352997140 heading 44.30230651281 Acceleration -0.01861572265 -0.09045410156 1.02691650390 Gyro -605 283 41 Magnetometer 1425 1387 -2030 Temperature 246 Level -1.03853188194 -5.03380446489 heading 45.77422016492 Acceleration 0.00439453125 -0.08666992187 1.02276611328 Gyro -429 -248 8 Magnetometer 1385 1459 -2064 Temperature 246 Level 0.24618193820 -4.84371267720 heading 43.50951784922 Acceleration -0.00036621093 -0.08117675781 1.03289794921 Gyro -501 21 -87 Magnetometer 1373 1453 -2027 Temperature 246 Level -0.02031404967 -4.49371112382 heading 43.37847185456
The readall function:
function readall(W){ W.readAccel(); W.readGyro(); W.readMag(); W.readTemp(); var pirate=180.0/Math.PI; console.log("Acceleration ",W.ax/16384,W.ay/16384,W.az/16384); console.log("Gyro ",W.gx,W.gy,W.gz); console.log("Magnetometer ",W.mx,W.my,W.mz); console.log("Temperature ",W.temperature); console.log("Level", pirate*Math.atan2(W.ax,W.az),pirate*Math.atan2(W.ay,W.az)); console.log("heading",pirate*Math.atan2(W.mx,W.my)); }//end readall
-
-
-
If you are using Outlook for Email you need to manually poll your ISP to get the Email in a timely manner. Look for a Send/Receive All Folders button in Outlook.
From the Login side your have 3 choices. The Email choice is auto populated (or you enter it) and click to the next pop up box that asks for the authorization code. At this point look for the Email to get the code. You can also click to get a new auth-code if needed.
-
TestLSM9DS1.js
21 Nov 2016
Using a Pico 1v88I’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.TestLSM9DS1.js 21 Nov 2016 */ …… LSM9DS1.prototype.mReadByte=function(subAddress){ //uint8_t LSM9DS1::mReadByte(uint8_t subAddress) // return I2CreadByte(_mAddress, subAddress); console.log("mReadByte ",_mAddress, subAddress); return 0; }; LSM9DS1.prototype.xgReadByte=function(subAddress){ //uint8_t LSM9DS1::xgReadByte(uint8_t subAddress) //return I2CreadByte(_xgAddress, subAddress); console.log("xgReadByte ",_xgAddress, subAddress); return 0; }; ….. LSM9DS1.prototype.xgWriteByte=function(subAddress,data){ //void LSM9DS1::xgWriteByte(uint8_t subAddress, uint8_t data) ////I2CwriteByte(_xgAddress, subAddress, data); console.log("xgWriteByte ",_xgAddress, subAddress, data); }; …… LSM9DS1.prototype.mWriteByte=function(subAddress,data){ //// return I2CwriteByte(_mAddress, subAddress, data); console.log("mWriteByte ",_mAddress, subAddress, data); return 0; }; ….. LSM9DS1.prototype.xgReadBytes=function(subAddress,dest,count){ //void LSM9DS1::xgReadBytes(uint8_t subAddress, uint8_t * dest, uint8_t count){ //// I2CreadBytes(_xgAddress, subAddress, dest, count); console.log("xgReadByte ",_xgAddress, subAddress, dest, count); }; ….. LSM9DS1.prototype.readMag=function(){ //void LSM9DS1::readMag(){ var temp=Uint8Array(6); // We'll read six bytes from the mag into temp this.mReadBytes(Mags.OUT_X_L_M, temp, 6); // Read 6 bytes, beginning at OUT_X_L_M this.mx = (temp[1] << 8) | temp[0]; // Store x-axis values into mx this.my = (temp[3] << 8) | temp[2]; // Store y-axis values into my this.mz = (temp[5] << 8) | temp[4]; // Store z-axis values into mz }; LSM9DS1.prototype.mReadBytes=function(subAddress,dest,count){ //void LSM9DS1::mReadBytes(uint8_t subAddress, uint8_t * dest, uint8_t count){ ////I2CreadBytes(_mAddress, subAddress, dest, count); console.log("mReadBytes ",_mAddress, subAddress, dest, count); };
The current output of the stubbed code:
>15 mReadByte 30 15 xgReadByte 107 15 xgWriteByte 107 16 192 xgWriteByte 107 17 0 xgWriteByte 107 18 0 xgWriteByte 107 30 58 xgWriteByte 107 19 0 xgWriteByte 107 31 56 xgWriteByte 107 32 192 xgWriteByte 107 33 0 mWriteByte 30 32 28 mWriteByte 30 33 0 mWriteByte 30 34 0 mWriteByte 30 35 12 mWriteByte 30 36 0 0 xgReadByte 107 40 new Uint8Array(6) 6 xgReadByte 107 24 new Uint8Array(6) 6 mReadBytes 30 40 new Uint8Array(6) 6 Acceleration 0 0 0 Gyro 0 0 0 Magnetometer 0 0 0 187 LSM9DS1 { "i2c": I2C { "_options": { "scl": B6, "sda": B9 } }, "addr": 72, "gain": 2048, "gBias": [ 0, 0, 0 ], "aBias": [ 0, 0, 0 ], "mBias": [ 0, 0, 0 ], "gBiasRaw": [ 0, 0, 0 ], "aBiasRaw": [ 0, 0, 0 ], "mBiasRaw": [ 0, 0, 0 ], "commInterface": 0, "agAddress": 107, "mAddress": 30, "gyro_enabled": true, "gyro_enableX": true, "gyro_enableY": true, "gyro_enableZ": true, "gyro_scale": 245, "gyro_sampleRate": 6, "gyro_bandwidth": 0, "gyro_lowPowerEnable": false, "gyro_HPFEnable": false, "gyro_HPFCutoff": 0, "gyro_flipX": false, "gyro_flipY": false, "gyro_flipZ": false, "gyro_orientation": 0, "gyro_latchInterrupt": true, "accel_enabled": true, "accel_enableX": true, "accel_enableY": true, "accel_enableZ": true, "accel_scale": 2, "accel_sampleRate": 6, "accel_bandwidth": -1, "accel_highResEnable": false, "accel_highResBandwidth": 0, "mag_enabled": true, "mag_scale": 4, "mag_sampleRate": 7, "mag_tempCompensationEnable": false, "mag_XYPerformance": 3, "mag_ZPerformance": 3, "mag_lowPowerEnable": false, "mag_operatingMode": 0, "temp_enabled": true, "ax": 0, "ay": 0, "az": 0, "gx": 0, "gy": 0, "gz": 0, "mx": 0, "my": 0, "mz": 0 }
-
Thanks @luwar.
I did some trials using the following module code located in my local projects/modules directory/****************************************************************************** Starting to recode this for Espruino 11/30/2016 LSM9DS1_Registers.h SFE_LSM9DS1 Library - LSM9DS1 Register Map Jim Lindblom @ SparkFun Electronics Original Creation Date: April 21, 2015 https://github.com/sparkfun/LSM9DS1_Breakout This file defines all registers internal to the gyro/accel and magnetometer devices in the LSM9DS1. Development environment specifics: IDE: Arduino 1.6.0 Hardware Platform: Arduino Uno LSM9DS1 Breakout Version: 1.0 This code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round! Distributed as-is; no warranty is given. ******************************************************************************/ ///////////////////////////////////////// // LSM9DS1 Accel/Gyro (XL/G) Registers // ///////////////////////////////////////// var Regs={ ACT_THS:0x04, ACT_DUR:0x05, INT_GEN_CFG_XL: (0x06), INT_GEN_THS_X_XL: (0x07), INT_GEN_THS_Y_XL: (0x08), INT_GEN_THS_Z_XL: (0x09), INT_GEN_DUR_XL: (0x0A), REFERENCE_G: (0x0B), INT1_CTRL: (0x0C), INT2_CTRL: (0x0D), WHO_AM_I_XG: (0x0F), CTRL_REG1_G: (0x10), CTRL_REG2_G: (0x11), CTRL_REG3_G: (0x12), ORIENT_CFG_G: (0x13), INT_GEN_SRC_G: (0x14), OUT_TEMP_L: (0x15), OUT_TEMP_H: (0x16), STATUS_REG_0: (0x17), OUT_X_L_G: (0x18), OUT_X_H_G: (0x19), OUT_Y_L_G: (0x1A), OUT_Y_H_G: (0x1B), OUT_Z_L_G: (0x1C), OUT_Z_H_G: (0x1D), CTRL_REG4: (0x1E), CTRL_REG5_XL: (0x1F), CTRL_REG6_XL: (0x20), CTRL_REG7_XL: (0x21), CTRL_REG8: (0x22), CTRL_REG9: (0x23), CTRL_REG10: (0x24), INT_GEN_SRC_XL: (0x26), STATUS_REG_1: (0x27), OUT_X_L_XL: (0x28), OUT_X_H_XL: (0x29), OUT_Y_L_XL: (0x2A), OUT_Y_H_XL: (0x2B), OUT_Z_L_XL: (0x2C), OUT_Z_H_XL: (0x2D), FIFO_CTRL: (0x2E), FIFO_SRC: (0x2F), INT_GEN_CFG_G: (0x30), INT_GEN_THS_XH_G: (0x31), INT_GEN_THS_XL_G: (0x32), INT_GEN_THS_YH_G: (0x33), INT_GEN_THS_YL_G: (0x34), INT_GEN_THS_ZH_G: (0x35), INT_GEN_THS_ZL_G: (0x36), INT_GEN_DUR_G: (0x37) }; /////////////////////////////// // LSM9DS1 Magneto Registers // /////////////////////////////// var Mags={ OFFSET_X_REG_L_M: 0x05, OFFSET_X_REG_H_M: 0x06, OFFSET_Y_REG_L_M: 0x07, OFFSET_Y_REG_H_M: 0x08, OFFSET_Z_REG_L_M: 0x09, OFFSET_Z_REG_H_M: 0x0A, WHO_AM_I_M: 0x0F, CTRL_REG1_M: 0x20, CTRL_REG2_M: 0x21, CTRL_REG3_M: 0x22, CTRL_REG4_M: 0x23, CTRL_REG5_M: 0x24, STATUS_REG_M: 0x27, OUT_X_L_M: 0x28, OUT_X_H_M: 0x29, OUT_Y_L_M: 0x2A, OUT_Y_H_M: 0x2B, OUT_Z_L_M: 0x2C, OUT_Z_H_M: 0x2D, INT_CFG_M: 0x30, INT_SRC_M: 0x30, INT_THS_L_M: 0x32, INT_THS_H_M: 0x33 }; //////////////////////////////// // LSM9DS1 WHO_AM_I Responses // //////////////////////////////// var WHO_AM_I_AG_RSP=0x68; var WHO_AM_I_M_RSP=0x3D; ///////////////////////////////////////////// function LSM9DS1(i2c) { this.i2c = i2c; this.addr = 0x48; this.gain = 2048; } // Create an instance of LSM9DS1 exports.connect = function(i2c1) { return new LSM9DS1(i2c1); };
I invoke this experimental module using the following:
/* Test Module for the LSM9DS1 */ console.log(process.memory()); I2C1.setup({ scl :B6, sda: B9} ); var W=require("LSM9DS1").connect(I2C1); console.log(process.memory());
The output with No Module minification
>{ "free": 4565, "usage": 535, "total": 5100, "history": 0, "stackEndAddress": 536959408, "flash_start": 134217728, "flash_binary_end": 379112, "flash_code_start": 134234112, "flash_length": 393216 } { "free": 4535, "usage": 565, "total": 5100, "history": 0, "stackEndAddress": 536959408, "flash_start": 134217728, "flash_binary_end": 379112, "flash_code_start": 134234112, "flash_length": 393216 }
Module minification Esprima (offline)
>{ "free": 4765, "usage": 335, "total": 5100, "history": 0, "stackEndAddress": 536959408, "flash_start": 134217728, "flash_binary_end": 379112, "flash_code_start": 134234112, "flash_length": 393216 } { "free": 4735, "usage": 365, "total": 5100, "history": 0,
Module minification Closure (online) –Whitespace only
>{ "free": 4762, "usage": 338, "total": 5100, "history": 0, "stackEndAddress": 536959408, "flash_start": 134217728, "flash_binary_end": 379112, "flash_code_start": 134234112, "flash_length": 393216 } { "free": 4732, "usage": 368, "total": 5100, "history": 0, "stackEndAddress": 536959408, "flash_start": 134217728, "flash_binary_end": 379112, "flash_code_start": 134234112, "flash_length": 393216 }
Module minification Closure (online) – Simple optimizations
>{ "free": 4765, "usage": 335, "total": 5100, "history": 0, "stackEndAddress": 536959408, "flash_start": 134217728, "flash_binary_end": 379112, "flash_code_start": 134234112, "flash_length": 393216 } { "free": 4735, "usage": 365, "total": 5100, "history": 0, "stackEndAddress": 536959408, "flash_start": 134217728, "flash_binary_end": 379112, "flash_code_start": 134234112, "flash_length": 393216 }
Module minification Closure (online) – Advanced
>{ "free": 5027, "usage": 73, "total": 5100, "history": 0, "stackEndAddress": 536959408, "flash_start": 134217728, "flash_binary_end": 379112, "flash_code_start": 134234112, "flash_length": 393216 } { "free": 4999, "usage": 101, "total": 5100, "history": 0, "stackEndAddress": 536959408, "flash_start": 134217728, "flash_binary_end": 379112, "flash_code_start": 134234112, "flash_length": 393216 }
From the Usage values the Advanced option seems to do the best job..
-
-
PICO v1.88
DHT22..... },6); } // Test with var dht = new HT("DHT22",B3); setInterval(function () { dht.read(print); },1000);
This gives:
{ "raw": "0100000001001000010000000011011001111110111", "rh": 28.9, "t": -21.7 } { "err": true, "raw": "0100000001001000110000000011011010111111" } { "err": true, "raw": "01" }
Change the 6 to 50
} else { if (n>1) setTimeout(function() {ht.read(cb,--n);},500); else cb({err:true, raw:d}); } },50); };
This works and gives:
{ "raw": "010000000100011110000000001101100111111000", "rh": 28.6, "t": 21.7 } { "raw": "010000000100011111000000001101101011111010", "rh": 28.7, "t": 21.8 } { "raw": "010000000100011110000000001101100111111000", "rh": 28.6, "t": 21.7 }
-
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
I’ve edited the LSM9DS1_register.h header file changing the #define to a variable object.I looked at some existing modules and found an interesting comment in this one.
https://www.espruino.com/modules/ADS1X15.js
The comment:/* Register values. Most of these aren't used and this is hidden, so it'll get optimised out when minified */ var CONFIG = { OS_MASK : (0x8000), OS_SINGLE : (0x8000), // Write: Set to start a single-conversion OS_BUSY : (0x0000), // Read: Bit = 0 when conversion is in progress OS_NOTBUSY : (0x8000), // Read: Bit = 1 when device is not performing a conversion
What minification settings are used to make this trick work?
-
It were from Auth0.
I think it was because I had kept sending request and their system flagged it as suspicious.
It finally worked as above.
The I tried again and it seemed to take forever to get the reply.
This morning I pulled up the login and did one request for auth. and then switched to the Outlook page and did refresh to get the auth. Email and managed to login again.
Looks like it were a BDOOHS. (Blow Dust Out Of Operator Head Space) -
Some links:
https://en.wikipedia.org/wiki/I%C2%B2C
http://johnny-five.io/news/introducing-i2c-component-backpacks/
https://github.com/sparkfun/SparkFun_LSM9DS1_Arduino_Library
The mreadbyte, xgreadbyte, mwritebyte, xgwritebyte, mreadbytes, and xgreadbyte functions using the I2C Wire class in Arduino are defined in the following:
https://github.com/sparkfun/SparkFun_LSM9DS1_Arduino_Library/blob/master/src/SparkFunLSM9DS1.cpp
Like I said, I know very little about the environment to which you want to port the code.