-
3DMouse8adrainB.js
This version uses the update BNO055.js module from the WebIDE sandbox.
It requires BNO055.js (sandbox), FlashEEPROM, and ESP8266WiFi_0v25 (Espruino modules).
It runs on a PICO with an ESP8266 connected via a shim.
The BNO055 module is connected as before.
// define the I2C connection I2C3.setup({ scl :A8, sda: B4} );
A normally open pushbutton is connected to ground and pin B7. Once the calibration status read 3333 the button is pressed to write the calibrations to the PICO EEROM
The calibration offsets and radiae are saved in PICO EEROM page var CalPage=89;
The html page is divided into two portions page1 and page2 to avoid out of memory errors
The web address uses port 8000. Given a router assigned IP address 192.168.1.6 use
"http//192.168.1.6:8000" in the browser. (Note older browsers may noe support the WebSockets used in this program. ( My old Android Tablet loads the page but doesn't support the websockets)
The drain command is used to serve the two pages.function onPageRequest(req, res) { res.writeHead(200, {'Content-Type': 'text/html'}); res.on('drain',function(){ res.write(page2); res.end();//Page); }); res.write(page1); }
Some sample left pane output:
A {"st":333,"yaw":341.125,"roll":16.625,"pitch":101.3125} Usage= 4369 A {"st":333,"yaw":341.0625,"roll":16.4375,"pitch":101.5} Usage= 4369
The BNO055.js module and savCalBNO055.js can be found at:
http://forum.espruino.com/conversations/305928/ -
BNO055 Module Improvements
24Jun2017BNO055 Module Improvements 24Jun2017
The BNO055.js module was used to implement an application as described here:
Using an IMU to control an airplane imagehttp://forum.espruino.com/conversations/306319/
It was discovered that the Pitch data values from the module were changing for a fixed position of the sensor. The BNO055.js module was updated to correct this problem, the reset function and external clock functions were also added.
The attached program savCalBNO055.js is setup for a PICO connected to a BNO055 board. A normally open pushbutton connected from ground to pin B7 is used to save the calibration data to EEROM on the PICO. When all four of the calibration status indications equal 3, save the calibrations.
Once a calibration has been saved, the program has to be restarted. The presence of calibration in the EEROM is detected and they are read, displayed and loaded into the BNO055 chip. Here is and example:sysstatus= 0 syscal= 0 Gyrcal= 0 Acccal= 0 Magcal= 0 sysstatus= 0 Calibration is defined Aoffset=,-6,3,8,Moffset=,-14,90,-142,Goffset=,0,0,0,Aradius=,1000,Mradius=,816
Here is a data example.
sysstatus= 5 A=,0.47,-9.54,-1.62,m/s^2 M=,20.1875,-7,11.1875,uT G=,-0.25,-0.3125,0.375,deg/s Heading=,359.9375,Roll,2.6875,Pitch,99.75deg Q=(,5276.5,-6259,-47.5,2.5,)E-14 Lin=,-0.01,0.1,-0.06,m/s^2 Grav=,0.46,-1.97,-1.66,m/s^2 Temperature= 64 F syscal= 0 Gyrcal= 3 Acccal= 3 Magcal= 3 Aoffset=,-6,3,8,Moffset=,-14,90,-142,Goffset=,0,0,0,Aradius=,1000,Mradius=,816
-
Found the fix to gotcha 1
Recall that glitch1 produces Pitch values that fluctuate for a steady position of the IMU chip.
The BNO055.js has been changed to fix this problem and the median filter has been removed from the 3dMouse8aDrain.js.
The original approach was to read a series of BNO055 registers in one big scoop.BNO055.prototype.getIMU=function(){ var IMU=new Int16Array(13); this.selectPage(0); IMU=this.ReadBytes(this.Page0Regs.EUL_Heading_LSB,26); this.Head[0]=IMU[0]/this.EULscale; this.Head[1]=IMU[1]/this.EULscale; this.Head[2]=IMU[2]/this.EULscale; this.Quant[0]=IMU[3]/2; this.Quant[1]=IMU[4]/2; this.Quant[2]=IMU[5]/2; this.Quant[3]=IMU[6]/2; this.Lin[0]=IMU[7]/this.ACCscale; this.Lin[1]=IMU[8]/this.ACCscale; this.Lin[2]=IMU[9]/this.ACCscale; this.Grav[0]=IMU[10]/this.ACCscale; this.Grav[1]=IMU[11]/this.ACCscale; this.Grav[2]=IMU[12]/this.ACCscale; };//end getIMU
By changing the way the data are read from the BNO055 the data value flutter issue has been resolved.
(The Art of Computer Programming)BNO055.prototype.getIMU=function(){ var IMU=[]; this.selectPage(0); var R=this.Page0Regs.EUL_Heading_LSB; for(var i=0;i<13;i++){ IMU.push(this.ReadBytes(R,2)); R=R+2; }//next i this.Head[0]=IMU[0]/this.EULscale; this.Head[1]=IMU[1]/this.EULscale; this.Head[2]=IMU[2]/this.EULscale; this.Quant[0]=IMU[3]/2; this.Quant[1]=IMU[4]/2; this.Quant[2]=IMU[5]/2; this.Quant[3]=IMU[6]/2; this.Lin[0]=IMU[7]/this.ACCscale; this.Lin[1]=IMU[8]/this.ACCscale; this.Lin[2]=IMU[9]/this.ACCscale; this.Grav[0]=IMU[10]/this.ACCscale; this.Grav[1]=IMU[11]/this.ACCscale; this.Grav[2]=IMU[12]/this.ACCscale; };//end getIMU
The module will be further updated to extend this discovery to other block reads of data.
-
From the BNO055 datasheet
The output data format is based on the following convention regarding the rotation angles
for roll, pitch and heading / yaw (compare also section 3.4):Table 3-13: Rotation angle conventions
Rotation angle Range (Android format) Range (Windows format) Pitch +180° to -180° -180° to +180° Roll -90° to +90° -90° to +90° Heading / Yaw 0° to 360° 0° to 360° -
Gotcha 1 Glitches in the data from the BNO055.
Examine the pitch values which should be around 180 degrees but on occasion read near 0.
Cal= 3033 {"st":3033,"yaw":181.6875,"roll":18.5625,"pitch":-179.3125} Cal= 3033 {"st":3033,"yaw":181.9375,"roll":16.875,"pitch":177.0625} Cal= 3033 {"st":3033,"yaw":180.875,"roll":6.875,"pitch":178.25} Cal= 3033 {"st":3033,"yaw":179.8125,"roll":3.375,"pitch":178.9375} Cal= 3033 {"st":3033,"yaw":181.3125,"roll":3.1875,"pitch":179.9375} Cal= 3033 {"st":3033,"yaw":181.75,"roll":2.3125,"pitch":-0.0625} Cal= 3033 {"st":3033,"yaw":181.25,"roll":3.8125,"pitch":-0.0625} Cal= 3033 {"st":3033,"yaw":182.625,"roll":5.1875,"pitch":-179.6875} Cal= 3033 {"st":3033,"yaw":183.0625,"roll":6,"pitch":-0.0625} Cal= 3033 {"st":3033,"yaw":183.375,"roll":7,"pitch":-177.75} Cal= 3033 {"st":3033,"yaw":183.125,"roll":7.25,"pitch":-177.625} Cal= 3033 {"st":3033,"yaw":183.9375,"roll":7.875,"pitch":-176.8125} Cal= 3033 {"st":3033,"yaw":184.3125,"roll":-0.0625,"pitch":-0.0625} Cal= 3033 {"st":3033,"yaw":185.0625,"roll":9.25,"pitch":-175.75}
Try using a median filter on the Yaw, Roll and Pitch data.
See attached file medianFilter.js and 3Dmouse8b.js
var MM=new xyzMF(7); //global … W.getIMU(); MMM=MM.getMF(W.Head); Msg.yaw=MMM[0]; Msg.roll=MMM[1]; Msg.pitch=MMM[2]; console.log(JSON.stringify(Msg));
And the output:
Cal= 3003 {"st":3003,"yaw":178.625,"roll":2.875,"pitch":179.75} Cal= 3003 {"st":3003,"yaw":178.6875,"roll":2.8125,"pitch":179.75} Cal= 3003 {"st":3003,"yaw":178.6875,"roll":2.8125,"pitch":179.75} Cal= 3003 {"st":3003,"yaw":178.625,"roll":2.75,"pitch":179.625} Cal= 3003 {"st":3003,"yaw":178.5625,"roll":2.6875,"pitch":179.5625} Cal= 3003 {"st":3003,"yaw":178.625,"roll":2.625,"pitch":179.6875} Cal= 3003 {"st":3003,"yaw":178.6875,"roll":2.625,"pitch":179.75} Cal= 3003 {"st":3003,"yaw":178.625,"roll":2.75,"pitch":179.75} Cal= 3003 {"st":3003,"yaw":178.8125,"roll":2.625,"pitch":179.8125} Cal= 3003 {"st":3003,"yaw":178.875,"roll":2.75,"pitch":179.875} Cal= 3003 {"st":3003,"yaw":179.0625,"roll":2.75,"pitch":179.9375} Cal= 3003 {"st":3003,"yaw":179.0625,"roll":2.8125,"pitch":179.875} Cal= 3003 {"st":3003,"yaw":179.125,"roll":2.875,"pitch":179.875}
3DMouse8c.js reconnects the web interface and uses the median filter
This version eliminates the image radically changing positions on the screen.
I still wonder if I missed a data ready status in the BNO055 module that might be causing the problem.
The hypothesis BNO055 is updating values at the same time the PICO is trying to read them. I’ll have to revisit this issue.Other gotchas relating to the position of the screen image and the position of the chip still remain to be resolved.
testws7a.js allows one to type yaw=23; roll=45; or pitch=-179 (supply your value) into the left pane of the WebIde and have the position of the airplane change on the web page.
-
Success
Combined two programs with some editing and the resulting program connects to the BNO055 IMU, then is connects to the local WiFi to serve the display page. As you move the BNO055 chip around the airplane on the screen seems to follow. (Just got it working so there are likely some gotchas, but I feel pretty good for now).
Put the BNO055.js in the modules directory of the WebIDE project (sandbox)
The WiFi is an ESP8266 on a Pico shim
The BNO055 is I2C. See code for pins. -
I reworked the communications link last night. Removed the timer approach and went to the approach that the client sends a character, the server replies with the JSON string, on receipt by the client, but before the JSON parse, the client sends another character, then does the JSON parse within a try/catch framework. The results run much faster and much longer without errors
The port used in the browser is 8000 not 8080. (you can edit it if you like). So the IP address line of the browser reads:
http//192.168.1.6:8000
The latest are attached. -
The HTML POST problem
If you try to post and then process the reply too fast, the header information winds up in the message from the client to the server.
Are Websockets faster?
To find out I went to the Espruino site to try a Websocket example
https://www.espruino.com/ws
In the Websocket server example code:var page = '<html><body><script>var ws;setTimeout(function(){'; page += 'ws = new WebSocket("ws://" + location.host + "/my_websocket", "protocolOne");'; page += 'ws.onmessage = function (event) { console.log("MSG:"+event.data); };'; page += 'setTimeout(function() { ws.send("Hello to Espruino!"); }, 1000);'; page += '},1000);</script></body></html>';
This is the HTML code sent to the client. Note the line page += 'ws.onmessage = function (event) { console.log("MSG:"+event.data); };';
Console.log is not a valid way to display a message in HTML/javascript.
The example works but nothing appears on the client screen.
A better example is in the attached file websockserve1a.jsWebsockets seem to be faster
Reworked the HTML file into the attached file flight5a.html to use Websockets. It is incorporated into the server code as a string using the file converter site at
https://www.espruino.com/File+Converter
The attached file websocketserver2.js contains the server code using Websockets.Bugs
The airplane flies and flies but eventually stops communicating.
Using the debugger on the client side the following two errors were occurringws.onmessage=function(event){ var S=JSON.parse(event.data); (index):1 Uncaught SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) at WebSocket.ws.onmessage ((index):214) VM44:37 WebSocket connection to 'ws://192.168.1.6:8000/my_websocket' failed: A server must not mask any frames that it sends to the client
The JSON.parse bug has been fixed.
The file trycatch.js shows how this was done in the client code. The messages sometime come in garbled and the JSONparse throws an error. The code catches the error and discards the message.
ws.onmessage=function(event){ try{ var S=JSON.parse(event.data); } catch(e){return;} CalStat=S.st;
The other bug I have no clue. Helpful suggestions are welcome.
Is this project the start of a 3D mouse?
The POST method fails with 500 ms sample intervals.
The Websockets method works well at 300ms and maybe 200ms. -
Using http Post is a bit slow. I'm working on using web sockets instead. I hope web socket data rates are faster. Model airplane control would be nice. I've seen some examples on the web. But that's another hobby to support.
I would like to try recording the heading and linear acceleration and then using integrations to get velocity and position, and plotting the course taken and see how well it would match the actual course. (Walk around the block for instance). This sort of thing could be useful to map a cave or tunnel.
-
If you Google SL4A Scripting Language for Android
https://en.wikipedia.org/wiki/Scripting_Layer_for_Android
Write code in Python, HTML and JavaScript to access Android features including Bluetooth.
I have an older version and do the editing on my PC and use Samsung Kies to move the files over to my tablet. Some stuff I've done in Python only, others I use the Python to display an HTML page from the SD card and then use JavaScript scripts to do stuff like speak, access Bluetooth or access the Web. All of the Android facades are accessible.http://www.mithril.com.au/android/doc/
Attached two files as an example.
-
Introduction
Having developed an Espruino module for the BNO055 IMU chip, this project will attempt to use the Euler angle of Yaw, Pitch and Roll that the chip provides to position a video rendering of an airplane on the computer screen. It is intended that as the orientation of the BNO055 chip is changed that the airplane image on the screen will follow.
http://forum.espruino.com/conversations/305928/Implementation
The progress so far serves a webpage that display the airplane and HTMP post commands obtain updated Euler angles that the PICO increments. Integration with the BNO055, will follow in a few days.
A PICO with an ESP8266 attached by a shim is the platform. The BNO055 IMU chip is also connected to the PICO.The attached files
Flight4.html contains the web page that will display the airplane, but it is set to simulate the changes of the Euler angles. If opened in a browser, it demonstrates the airplane in motion.
Flight4a.html is similar to flight4.html but is set to use HTML Post messages to the server to obtain the Euler angles.
Jnet.js is the Web credentials file that you will need to edit and place in the WebIDE projects module subdirectory. Edit the ssid and pw for your local wifi network./* Jnet.js */ exports = { id: "...", ssid: "funny", pw: "1234567890", ip: "..."
ServePage3a.js contains the server code. It connects to the WiFi using jnet.js credentials.
It displays the IP address that you will use to access via a browser.1v92 Copyright 2016 G.Williams >Start Start connection process Try again =undefined Reset the ESP8266 Connecting to WiFi IP= 192.168.1.6 null Wi-Fi Connected
Once a browser connects you will see:
1v92 Copyright 2016 G.Williams >Start Start connection process Try again =undefined Reset the ESP8266 Connecting to WiFi IP= 192.168.1.6 null Wi-Fi Connected {"st":3333,"yaw":0,"roll":10,"pitch":0} A {"st":3333,"yaw":0,"roll":20,"pitch":0} A {"st":3333,"yaw":0,"roll":30,"pitch":0} A {"st":3333,"yaw":0,"roll":40,"pitch":0} A {"st":3333,"yaw":0,"roll":50,"pitch":0}
Screenshot1.jpg shows a screenshot of the webpage.
Future work
- Use six switches, two for each axis. If a switch is closed increment or decrement the angle
- Use 3 potentiometers two in a joystick and one for the rudder , use the values read by an analog port to increment or decrement the Euler angles.
Write the code to uses the BNO055 module to change the Euler angles.
Msg.roll+=10; if(Msg.roll>360){ Msg.roll=0; Msg.yaw+=45; if(Msg.yaw>360){ Msg.yaw=0; Msg.pitch+=15;if(Msg.pitch>360)Msg.pitch=0; }//endif yaw }//endif roll var M=JSON.stringify(Msg); console.log(M); res.writeHead(200, {'Content-Type': 'text/plain','Content-length':M.length}); //res.writeHead(200); res.end(M);
- Use six switches, two for each axis. If a switch is closed increment or decrement the angle
-
Thanks @Gordon for the prompt reply.
I'll try your suggestions later today.
It may be a bit more complex but that makes it fun. (see snippet)
Send reset or change clock and then catch the error and retry on a subsequent read of a status register using the snippet./** Readbyte(BusAddress,SubAddress) */ BNO055.prototype.ReadByte=function(subAddress){ var data=Uint8Array(1); this.i2c.writeTo(this.BusAddress, subAddress); data=this.i2c.readFrom(this.BusAddress, 1); return data[0]; };//end ReadByte
-
The error message
Uncaught InternalError: Timeout on I2C Read Receive
The usual suspect are pull up resistors
Other causes
You send a command via I2C that causes the device to require a delay before it is ready to talk I2C again.
Examples for the BNO055 are reset, change clock between internal and externalOne solution is to use a callback
Is there a way to throw and catch the error and then try again N times or until the error clears?
function start(){ // define the I2C connection I2C3.setup({ scl :A8, sda: B4} ); // define the bus address of the BNO055 chip var BusAddress= 0x28;//If ADR pin at 3V 0x29 //load the BMO055 module W=require("BNO055").connect(I2C3,BusAddress,function(){ // set the BNO055 clock to external using a callback funtion W.External_Clk(1,function(){ //the callback code goes here });//end set external clock });//end require }//end start
The external clock function with callback
BNO055.prototype.External_Clk=function(a,callback){ this.selectPage(0); if(a) this.WriteByte(this.Page0Regs.SYS_TRIGGER,0x80); else this.WriteByte(this.Page0Regs.SYS_TRIGGER,0x00); setTimeout(function () { callback(); }, 50); };
-
-
-
The error that shows up on occasion in other projects but here it's persistant
ERROR: SD card must be setup with E.connectSDCard first
The error occasionally occurs when other modules are required, but usually clears on a 2nd or third send to Espruino.The code is an example from @allObjects
var creds = require("credsXYZ.js"); //var creds={ id: "XYZ", ssid: "Mine", pw: "123456", ip: "..." }; console.log(creds); /* credsXYZ.js */ //exports = { id: "XYZ", ssid: "Mine", pw: "123456", ip: "..." }; var creds1={ id: "XYZ", ssid: "Mine", pw: "123456", ip: "..." }; console.log("creds1= "); console.log(creds1);
The credsXYZ.js module in the sandbox
/* credsXYZ.js */ exports = { id: "XYZ", ssid: "Mine", pw: "123456", ip: "..." };
The output
1v92 Copyright 2016 G.Williams >ERROR: SD card must be setup with E.connectSDCard first WARNING: Module "credsXYZ.js" not found undefined creds1= { "id": "XYZ", "ssid": "Mine", "pw": "123456", "ip": "..." } =undefined >
-
Solved the reset and external clock problem
Reset
The reset requires a delay after the command is issued.
This was solved by using a callback structure in the moduleexports.connect = function(i2c,BusAddress,callback) { var W= new BNO055(i2c,BusAddress); W.RST_SYS(); setTimeout(function () { callback(); }, 1000); return W; };
Which changes the code in the test program.
//load the BMO055 module W=require("BNO055").connect(I2C3,BusAddress,function(){ ///lots of code here in the callback });//end require
External Clock
The call to change the clock souce also requires a delay which is addressed using a callback function
In the module:BNO055.prototype.External_Clk=function(a,callback){ this.selectPage(0); if(a) this.WriteByte(this.Page0Regs.SYS_TRIGGER,0x80); else this.WriteByte(this.Page0Regs.SYS_TRIGGER,0x00); setTimeout(function () { callback(); }, 50); };
The code in the test program:
//load the BMO055 module W=require("BNO055").connect(I2C3,BusAddress,function(){ W.External_Clk(1,function(){ //1=external 0=internal clock //Lots of code //do a timed loop that acquires and displays data var i; setInterval(function () { console.log(" "); showAMG(); showIMU(); showTemp(); showCalibStatus(); showOffsets(); }, 500);//display rate });//end set external clock });//end require }//end start
-
BMO055 Module progress
Place the attached BMO055.js in the modules directory of your WebIDE project.
Run testBMO055.js.
Try editing the unit selections or the operating mode to see what happens. I’ve tested modes 7 and 12.The test code follows
//testBMO055.js 7 Jun 2017 var W; // For accelerometer slowly position chip on 6 faces of a cube. // For magnetometer move chip in verical figure 8 pattern // For gyroscope leve chip in one position for a bit // When the calibration status numbers are all eqaul to three //calibration has been achieved function showCalibStatus(){ console.log("syscal= "+W.Bitread(W.REGval.SYS_Calib_Status)+ " Gyrcal= "+W.Bitread(W.REGval.GYR_Calib_Status)+ " Acccal= "+W.Bitread(W.REGval.ACC_Calib_Status)+ " Magcal= "+W.Bitread(W.REGval. MAG_Calib_Status)); }//end showCalibStatus function showTemp(){ console.log("Temperature= "+W.getTemperature()+" "+W.Tunitstr); }//end showTemp( function showAMG(){ W.getAMG(); console.log("A=,"+W.ACC[0]+","+W.ACC[1]+","+W.ACC[2]+","+W.ACC_Unitstr); console.log("M=,"+W.Mag[0]+","+W.Mag[1]+","+W.Mag[2]+","+W.Magunitstr); console.log("G=,"+W.Gyr[0]+","+W.Gyr[1]+","+W.Gyr[2]+","+W.GYR_Unitstr); }//end showAMG function showIMU(){ //fusion modes W.getIMU(); console.log("Heading=,"+W.Head[0]+",Roll,"+W.Head[1]+",Pitch,"+W.Head[2]+W.Anglestr); console.log("Q=(,"+W.Quant[0]+","+W.Quant[1]+","+W.Quant[2]+","+W.Quant[3]+",)"+W.Qstr); console.log("Lin=,"+W.Lin[0]+","+W.Lin[1]+","+W.Lin[2]+","+W.ACC_Unitstr); console.log("Grav=,"+W.Grav[0]+","+W.Grav[1]+","+W.Grav[2]+","+W.ACC_Unitstr); }//end showIMU var Off; function showOffsets(){ Off=W.readOffsets(); console.log("Aoffset=,"+Off[0]+","+Off[1]+","+Off[2]+ ",Moffset=,"+Off[3]+","+Off[4]+","+Off[5]+ ",Goffset=,"+Off[6]+","+Off[7]+","+Off[8]); console.log("Aradius=,"+Off[9]+",Mradius=,"+Off[10]); }//end showOffsets function start(){ // define the I2C connection I2C3.setup({ scl :A8, sda: B4} ); // define the bus address of the BNO055 chip var BusAddress= 0x28;//If ADR pin at 3V 0x29 //load the BNO055 module W=require("BNO055").connect(I2C3,BusAddress); // W=new BNO055(I2C3,BusAddress); W.run();//Get it started Needs work //W.RST_SYS(); //not working yet //display all knobs and indicators W.showBits(); //W.External_Clk(); //not working yet //to configure the chip must be in Opmode 0 W.Bitwrite(W.REGval.Operation_Mode,0); /* setupTemperature source 0= Accelerometer, 1= Gyro; unit 0=C, 1=F **/ W.setupTemperature(1,1);//(source,unit) // choose units to display W.setEULunits(0); //0 deg,1 rad W.setGYRunits(0); //0 deg,1 rad W.setACCunits(0); // 0 m/s,1 mg //chip registers are paged //to direct read output need to be on page 0 W.selectPage(0); // choose am operating mode /* ##### Operation_Mode 0=CONFIG MODE 1=ACCONLY 2=MAGONLY 3=GYROONLY 4=ACCMAG 5=ACCGYRO 6=MAGGYRO 7=AMG 8=IMU 9=COMPASS 10=M4G 11=NDOF_FMC_OFF 12=NDOF */ W.Bitwrite(W.REGval.Operation_Mode,12); //do a timed loop that acquires and displays data var i; setInterval(function () { console.log(" "); showAMG(); showIMU(); showTemp(); showCalibStatus(); showOffsets(); }, 500); }//end start //function startPgm(){ //Wait for program to load setTimeout(function () { start(); }, 1000); //}//end startPgm
The output follows
Note the all three values in syscal, showing that the chip is calibrated.
A=,-0.63,0.02,9.81,m/s^2 M=,-0.0625,-0.0625,-0.0625,uT G=,-0.0625,-0.0625,-0.0625,deg/s Heading=,275.125,Roll,-7.5625,Pitch,0.5625deg Q=(,6033.5,-395.5,373,5514.5,)E-14 Lin=,0.64,-0.02,0.26,m/s^2 Grav=,-1.29,-0.09,9.72,m/s^2 Temperature= 74 F syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3 Aoffset=,-29,15,18,Moffset=,-230,196,-1156,Goffset=,-1,-1,0 Aradius=,1000,Mradius=,372 A=,-1.12,0.17,9.37,m/s^2 M=,22.5625,7.75,-42.0625,uT G=,7.75,-14.3125,-0.0625,deg/s Heading=,304.75,Roll,-5.5625,Pitch,-2deg Q=(,7249,-56,422,3792.5,)E-14 Lin=,-0.01,-0.01,-0.01,m/s^2 Grav=,-0.01,-0.01,-0.01,m/s^2 Temperature= 76 F syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3 Aoffset=,-29,15,18,Moffset=,-230,196,-1156,Goffset=,-1,-1,0 Aradius=,1000,Mradius=,372 A=,-0.63,0.03,9.27,m/s^2 M=,-0.0625,-0.0625,-0.0625,uT G=,-0.0625,-0.0625,-0.0625,deg/s Heading=,330.875,Roll,-2.0625,Pitch,0.5deg Q=(,-0.5,-0.5,-0.5,-0.5,)E-14 Lin=,-0.01,-0.01,-0.01,m/s^2 Grav=,-0.01,-0.01,-0.01,m/s^2 Temperature= 76 F syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3 Aoffset=,-29,15,18,Moffset=,-230,196,-1156,Goffset=,-1,-1,0 Aradius=,1000,Mradius=,372 A=,-1.13,-0.07,9.47,m/s^2 M=,0.25,16.0625,-13.25,uT G=,-0.0625,-0.0625,-0.0625,deg/s Heading=,5.1875,Roll,-2.1875,Pitch,-1.75deg Q=(,8181,134.5,153,-372,)E-14 Lin=,-0.26,-0.1,0.63,m/s^2 Grav=,-0.01,-0.01,-0.01,m/s^2 Temperature= 76 F syscal= 2 Gyrcal= 3 Acccal= 3 Magcal= 3 Aoffset=,-29,15,18,Moffset=,-230,196,-1156,Goffset=,-1,-1,0 Aradius=,1000,Mradius=,372 A=,-0.61,0.79,9.54,m/s^2 M=,-0.0625,-0.0625,-0.0625,uT G=,-0.0625,-0.0625,-0.0625,deg/s Heading=,30.8125,Roll,-3.125,Pitch,-1.5deg Q=(,7893,164,190.5,-2178,)E-14 Lin=,-0.1,-0.48,1.04,m/s^2 Grav=,-0.01,-0.01,-0.01,m/s^2 Temperature= 76 F syscal= 2 Gyrcal= 3 Acccal= 3 Magcal= 3 Aoffset=,-29,15,18,Moffset=,-230,196,-1156,Goffset=,-1,-1,0 Aradius=,1000,Mradius=,372 A=,-0.17,0.27,10.13,m/s^2 M=,-11.5,12.5,-45.6875,uT G=,3.1875,-0.0625,-0.0625,deg/s Heading=,39.5625,Roll,-1.5625,Pitch,-0.75deg Q=(,7707.5,90.5,87,-2773,)E-14 Lin=,0.06,0.23,-0.01,m/s^2 Grav=,-0.26,0.13,9.8,m/s^2 Temperature= 76 F syscal= 2 Gyrcal= 3 Acccal= 3 Magcal= 3 Aoffset=,-29,15,18,Moffset=,-230,196,-1156,Goffset=,-1,-1,0 Aradius=,1000,Mradius=,372 >clearInterval(); =undefined >
Not finished yet
- External clock
- Reset
- POST and chip ID checks
- How to save and load calibration data
- Testing Interrupts
- Things and bugs I haven’t found yet
Some links
https://www.bosch-sensortec.com/bst/products/all_products/bno055
Quaternions
https://github.com/kriswiner/LSM9DS1/commit/73a372a62c166a79fbdac46b8d3322430bf75428http://x-io.co.uk/res/doc/madgwick_internal_report.pdf
http://diydrones.com/profiles/blogs/sebastian-oh-madgwicks-filter
- External clock
-
-
It's early in the learning curve on this one but so far I like it a lot.
In mode 12 NDOF, you just slowly move the chip into the six positions of the cube and watch for the calibration register numbers to all equal 3, then you are calibrated. A lot easier than prior chips.
Units can be degrees or radians per second square, F or C temperature from two sources,
m/s^2 or mg acceleration units and both gravity and linear acceleration outputs.When you mount the chip in your model airplane or other project, it has the ability to reassign the axis designations and signs (to keep the coordinate system either left or right handed).
Try Amazon for a lower price.
-
BNO055 Nine Degree of Freedom IMU with built in Quaternion function
Thanks to @trusktr for finding this chip at Adafruit.
https://www.adafruit.com/product/2472https://learn.adafruit.com/adafruit-bno055-absolute-orientation-sensor/overview
Connections
I hooked the breakout board to a PICO with short wires and began to get results with code that follows.
+3 to Vin, GND to GND, A8 to SCL, B4 to SDA
I changed to a longer set of wires so I can move the breakout board around without the PICO USB connector coming loose, and the performance became intermittent. Looking at the schematic I tried
Connecting the Vin and 3vo pins together on the breakout board and fixed the problem for use with the 3 Volts from the PICO. The Vin connected to a MIC6225-3.3 Voltage regulator input and the 3vo pin to the output.Almost a Module
The attached code is almost a module. Some issues remain to be resolved but I am getting some interesting results. The output values are not scaled and are just the signed 16 bit integers.
Most of the knobs for the chip are accessed using a data structure that defines the register, mask and shift for the particular bits (a document will follow as the module is completed)
In NDOF mode (12) the output looks like this:A=,-232,-1,-1,M=,-1,-1,-1,G=,-1,-1,-1 Heading=,5541,Roll,-247,Pitch,-111 Q=,-16091,-699,-2305 Lin=,-1925,27,-5 Grav=,6,-1,-1 Temperature= 74 F syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3 Aoffset=,-24,3,25,Moffset=,-24,62,-297,Goffset=,0,-1,-2 Aradius=,1000,Mradius=,867 A=,-211,-1,-1,M=,-1,-1,-1,G=,-1,-1,-1 Heading=,5510,Roll,-243,Pitch,-117 Q=,-16057,-718,-2294 Lin=,-2198,16,7 Grav=,10,-1,-1 Temperature= 74 F syscal= 3 Gyrcal= 3 Acccal= 3 Magcal= 3 Aoffset=,-24,3,25,Moffset=,-24,62,-297,Goffset=,0,-1,-2 Aradius=,1000,Mradius=,867 >clearInterval();
In AMG mode the output looks like this
A=,69,-930,-244,M=,-1,-1,-1,G=,-1,-1,-1 Heading=,0,Roll,0,Pitch,0 Q=,0,0,0 Lin=,0,0,0 Grav=,0,0,0 Temperature= 72 F syscal= 0 Gyrcal= 0 Acccal= 0 Magcal= 0 Aoffset=,-21,6,19,Moffset=,47,23,-1,Goffset=,-1,-1,-1 Aradius=,-1,Mradius=,-1 A=,67,-932,-240,M=,-1,-1,-1,G=,-1,-1,-1 Heading=,0,Roll,0,Pitch,0 Q=,0,0,0 Lin=,0,0,0 Grav=,0,0,0 Temperature= 72 F syscal= 0 Gyrcal= 0 Acccal= 0 Magcal= 0 Aoffset=,-21,6,19,Moffset=,47,23,-1,Goffset=,-1,-1,-1 Aradius=,-1,Mradius=,-1 >clearInterval();
Issues that remain are:
Using the external clock on the Adafruit board,
Writing the offsets and radius to the chip and a way to save them on the PICO
Sorting out the scale factors on the output as they change with the units settings and operating mode settings.
Changing the code into a module.
-
Now that looks like a gee whiz chip.
Connecting it is the easy part.
You setup an I2C object connect the pins and make sure the pull up resistors are enabled.
The datasheethttps://cdn-shop.adafruit.com/datasheets/BST_BNO055_DS000_12.pdf
From the datasheet section 4.6 the I2C Bus Address is either 0x28 or 0x29.
Section 4.2 list the registers.
The register at 0x00 is the chip IDvar Busaddress=0x28; var ChipId=0; // set up I2C I2C1.setup({ scl : B6, sda: B7 }); //you have to configure the pins and wiring // tell the chip which register to access I2C1.writeTo(Busaddress, ChipID); // read byte from ChipID register var d = I2C1.readFrom(Busaddress,1); //1 byte console.log(d.toString(16)); // in hex // should be 0xa0 see 4.3.1 in datasheet
The hard part is setting up to read and write all the registers and even more so specific bits in each register.
On soldering, a low wattage iron, a holder for the iron when not in use, a small shallow container with a wet sponge to clean the tip. In years past I used a light dimmer to control the power to the iron. A really pointy tip is a blessing.
Depending on your budget a temperature controlled iron is a blessing $100 or so.Happy soldering:)
-
You can identify an interval by naming it
and use the name to clear only that intervalvar id = setInterval(function () { print('foo'); }, 1000); clearInterval(id)
https://en.wikipedia.org/wiki/Composite_video
Analog TV studios used a master framing source for all their equipment so that the composite video frames were synchronized. Without that synchronization, switching video sources causes the monitor to resync to the new source and in the process the picture gets scrambled until it locks to the new sources framing pulses.
NTSC signal explanation:
https://www.youtube.com/watch?v=X24zDXz8Xgc
Part2 Color Burst
https://www.youtube.com/watch?v=mHXDX0MXcyk
Here's someone who appears to have done it.
https://electronics.stackexchange.com/questions/116052/how-to-make-a-simple-video-switch