jps2000 / BNO080

Arduino sketch for BNO080 9DOF with sensor fusion
50 stars 5 forks source link

Assistance required please #7

Closed duckman1961 closed 5 years ago

duckman1961 commented 5 years ago

Hi Peter l see you are in OZ l am in Taz, could you offer some help regarding the GY-BNO08X please, as l am certainly not a programmer. I have uploaded your code to a Nano uncommented SerialDebug and I2Scan but nothing showing in the scan, changed #define BNO_ADDRESS 0x4A to 0x4B without success as well. I have ohmed out my 3.3v,gnd,SCL, SDA cables from the Nano pins to the IMU pins and they are ok, so connections and cable correct Have SCL = A5, SDA = A4. Not sure what you mean re below, as supplying 3.3v off Nano to IMU, so there shouldn't be a level shifter required?. "Needs a 3V3 supply and connect I2C Bus via a level converter 5V --> 3V3!!! SDA = A4; SCL = A5."

Now have just tested Nano SCL (A5) and see it has 5v on it, In previous things of 3.3v l had used SPI does that use 3.3V? So l may have killed both these IMU, if that is the case l won’t be getting any more.

Have used another I2C scanner and with 3.3v to IMU and direct SCL, SDA to Nano can see IMU on Ox4B. Have today purchased a level shifter and connected up, but still your code and now the other I2C scanner that worked with direct connect I2C can't see the IMU.

Any way if l get these to work, the next part of your code ask's for ("**** set feature command quat **"); to do this do l uncomment // get_feature_request_quat()??, which l did and that removed the request. ("**** configure ME cal ** ");to do this do l put 5V to T6?? Tried that without success but of course l have no comms with the IMU.

Anything else required to get Yaw ?? Regards Kevin

duckman1961 commented 5 years ago

Hi Peter, l now have had intermittent operation, didn't really change anything. I am currently direct connect to Nano with digitalWrite(SDA, LOW);// disable pullup resistors so can use on 3.3V digitalWrite(SCL, LOW); added to supposedly make the lines 3.3V compatibly, but there is conjecture on this depending on the min V needed. I couldn't scan with the level shifter inline, but without now intermittently l got 0x4B to show on your scan (which l had altered to already). l have also altered the I2C speed,although that may have slightly helped. I2c.setSpeed(0); // default = 1 = set I2C to 400kHz, 0 = 100khz

So l had for a short time had S, E and quats displayed (showing live data, albeit the S+E weren't as mag not calibrated), l then switched D6 to 5V and started to calibrate with E showing live data, then it freezed after about 3 seconds. Any advice? Regards Kevin

duckman1961 commented 5 years ago

I will add that l have about 300mm long wires between the Nano and GY-BNO08X, with other IMU's l have had 8M long cat 5 cable working with the Wire library without issue.

duckman1961 commented 5 years ago

Hi Peter, currently have GY-BNO08X running using a Mega, seemed to have varying freezing problems with 3 different Chinese Nano copies. Still to go through and work out how to calibrate yet. Currently getting live S,E, Quates data without freezing up using 300mm long leads direct to IMU (NO level converter). Regards Kevin

duckman1961 commented 5 years ago

Just wrote a long winded post and lost it. Anyway seems to be an issue with I2C library it can take up to 15 times restarting to get data, with Sparkfun Wire library it starts every time even with 5M of cat5 cable. So much for I2C is better than Wire! Just mucked around getting Euler angles, why it wasn't an option is beyond me, also orientation seems off and using Tare which is supposed to give N.E.D doesn't seem to work. Have to have the IMU on it's edge to line up the yaw, pitch, roll. Very limited testing shows heading repeat ability is good, your code showed reasonable low tilt induced error on the heading were as Sparkfun was worse than other IMU's even after using there Calibrate code. So more testing/playing to be done

jps2000 commented 5 years ago

Just read about your problems lets first make clear which hardware you are using now and what is the actual status I will help you wherever I can so keep cool In case you are using a 5V controller then you need definitely a level converter for I2C bus and others Otherwise you may kill the BNO Using 3V3 controllers like M0 for example you dont need those level converters but there need to be pullups ( seem to be on the BNO board)

ramiss commented 5 years ago

I don't have the startup issue, but I just have a 1000ms delay in my setup

duckman1961 commented 5 years ago

Thanks Peter, currently using a Chinese GY-BNO08X IMU on 3.3V VIN a copy Mega and 5M of Cat5 cable connecting the 2. When using a Jaycar level shifter (tried 2 of) l can't see the IMU. At this stage l will persevere with learning how to operate the IMU (check the different vectors) realistically using the Sparkyfun code as it comms every time. ( l did try it when l couldn't seem to get yours working, but had the same result, it wouldn't work either with the Nano) using a Mega board. On memory, the Sparkyfun code and with a Mega board it wouldn't comm at wire speed 400khz, took that back to 100khz and it has never missed a beat. I did see with your code if l slow up the baud rate to 9600 it shows ch3 data, were at a higher rate it only shows ch 0,1,2 Any idea why the level shiftier doesn't seem to work, l have it wired as shown by Sparkyfun 5V=HV, 3.3v =LV , SDA straight thru 1 channel( rx, tx , tried changing these around) and SCL the other. Regards Kevin

duckman1961 commented 5 years ago

ramiss, will try that, did read were there is an issue with I2C were it doesn't start every time and some code to restart it would be advisable.

ramiss commented 5 years ago

Also, make sure the IMU is not setup to sample faster than the Arduino can handle. If you find a way to reset I2C I would love to get a snippet. I have I2C issues with it crapping out after a static discharge (robot) and I can't reset without cycling power.

duckman1961 commented 5 years ago

ramis, Peter, have added a 1000ms delay after I2C speed() which has lowered restarts to about 6 so far (although there is a delay of 500ms after the first print anyway). Also l misread the TARE/CAL buttons and now have put them to GND instead of 5V+, but l had been using Sparkyfun Cal code. Using RoationVector with Euler angle formula. The pitch/roll still seems to be arse about face and the roll is reading 176 degrees. IMU is screen print up as per axis diagram. S = 3, E = <2 static and <6 when IMU moving. The yaw seems very heavily filtered and takes >20 seconds to come to a consistent heading when tilted to 45 degrees (that's 1 of the pitfalls of having 2 decimal place outputs, but the same as all my other IMU's) In all my testing of other IMU's l hold the tilt position until the reading is solid (within reason, until the reading is going +- around a number, not just increasing or decreasing). The others l have tested get a solid reading in <5 seconds. It is picking up the initial large movement around the compass quickly then takes 5-10 seconds to settle on the last <0.5 degrees. In basic testing in my shed at a tilt of 45 degrees l see <=5 degree tilt induced error on/around 0 and all other headings are very good, so in that sense it is as equal as good as l have test. But still to prove whether the velocity issue has been rectified and any other prob's that might show there head. When the weather improves l will do a full compass/tilt test outside.

ramiss commented 5 years ago

Are you sure you are getting high readings on the calibration routine before running these tests. This IMU has some weird anomalies until it is property calibrated

jps2000 commented 5 years ago

Great Kevin, that you are progressing You need first to get your hardware under control. It may work somehow already but you may have unpredictable effects that may cost you plenty of headache continuously.

So first use a shorter cable, 400kHz I2C is important because the BNO tells a lot of stuff at the beginning that need to be over before accepting commands etc. The buttons can only work if there are pullups ( preferably external) that a H-> L transition is present at the input. Then I would focus first on getting 4 stable and valid quaternions. They need to be all <1 showing positive and negative values. Quaternions are the base for everything . It helps reducing the data rate of the BNO to may be 10 or 100 Hz and the output data rate (Serial) to 0.5 seconds. Show the quats first on serial. Pressing tare button should bring quaternions to 1,0,0,0. Then you should be able to get stat_ to 3 by doing calibration. and store that values in the BNO.

In my feather example you find useful improvements but you can also post your code and I will see what I can do. For example there I put also a check of the quats for plausibility (vector sum == very close to 1) and now it works outstanding.

I use a featherNRF52 with a BNO and a baro, and a second NRF52 working a dongle to receive that data and send it via USB to Excel to plot yaw pitch roll every second.

duckman1961 commented 5 years ago

Hi Peter, re cable length, if it can't do about 7M the IMU is worthless to me. It is the basies for a Yacht auto pilot, so requires mounting that far away from the Arduino. When I2C is set at 1 (400khz) the code won't move past the Basic serial print, so it isn't getting to the Loop(). The TARE/CAL buttons work, or so it says when l remove the GND. I see this isn't the case as the Q are staying the same as what they were, although it says they are TARED and saved. Also when l try and open your Feather sketch, it says "Error, could not create sketch" but l can open all the others. ramiss Yes to Cal all HIGH at S=3, E=<3

jps2000 commented 5 years ago

But you should not start off with 7 meters at the beginning. There are I2C drivers that can do that lenght . or you may simply reduce the pullup resistors to 2k2. 400kHz is a must as I remember. But again: I strongly suggest to follow a step by step approach. Attach your code here if I should help You can use the feather sketch only on this platform but you may use part of the software from corrected an error ( wrong bracket) in the feather sketch

ramiss commented 5 years ago

Since, at 7M, you are on the edge, why not employ 2 Arduinos? One at the IMU talking at high speed that then does a serial or wifi to your main Arduino? You then have the advantage of offloading/balancing calcs to each Arduino.

jps2000 commented 5 years ago

Indeed this is always possible https://hackaday.com/2017/02/08/taking-the-leap-off-board-an-introduction-to-i2c-over-long-wires/ but again: solving problems need to tackle one after the other in the order of importance. Main Q for Kevin is if the BNO080 has the required performance.That is what I understood so far. So it is recommended to bring the setup reliably to operation e.g. with 10 cm cables first.

duckman1961 commented 5 years ago

In

Re Cable, l have Pololu V3, MPU9255, BNO055, Kris Winer IMU's (2 different ones) , TMQ , Masertron (plus a couple of others l can't remember) all of which can operate at 7M+, so cabling isn't really an issue (apart for the GY-BNO08X). I did try with 300mm cables previously without luck and will be looking back into this morning. I re tried Sparkyfun at 400khz without luck, at 100khz it starts straight away. As previous said, this IMU in current testing is only equal to other IMU's and as such isn't anything special (at 5 degree tilt induced error it is at best 1 degree better then the GY-MPU9255). At $30AUD compared to a GY-MPU9255 at $4.60AUD (both delivered) it hasn't so far proved worth the cost and effort. But l will go back to basics and try and get it to work correctly. ramiss, yes l could go with 2 Arduino's but why would l, my/Jack Edwards AP steers as well as the best (NKE) and l don't require a Arduino at the IMU, although initially it looked like we would need to, due to IMU freezing, but with correct termination of the Cat5 cable l was able to over come the freeze issue. I'm still to test how much processing is going to the Arduino, as with Sparkyfun they seem to be doing Euler cal outside of the SH-2 as is Peter. There output is a lot quicker, but a bit more jumpy, which makes me wonder on there filtering, as your one has none on the Eulers (that l can see)

jps2000 commented 5 years ago

In contrast to the BNO055 breakout the GY seem not to have a level converter on board. so regarding the cable you should have the level converter close to the GY and use same pullups on the controller side and the Level converter side. In my software there is a while loop that freezes the software until communication is running

// BNO settings Wire.beginTransmission(BNO_ADDRESS); while (Wire.endTransmission() != 0); //wait until device is responding (32 kHz XTO running) Serial.println("BNO found");

This was made to have minimum starting delay and communication is there It should work with 400k I2C This you have to achieve first; safely and stable at every off / on and instantly.

Then there is a delay needed and you can send a command what the BNO 080 should deliver

delay(200); //needed to accept feature command; minimum not tested set_feature_cmd_QUAT(); // set the required feature report data rate are generated at preset report

This is at the end of the setup. In the loop you can poll the BNO with get_QUAT()

The conversion from quat to eulers does not represent signifcant processor load at all

look into my feather sketch for my latest version

duckman1961 commented 5 years ago

Thanks Peter, looks like the Duinotech shifter l got from Jaycar most probable doesn't work https://forum.arduino.cc/index.php?topic=381795.0

jps2000 commented 5 years ago

inded such level shifters consist of a fet and 2 pullup resistors on both sides so they need to be supplied with 3V3 and 5V. The value of the pullup determines the drive capability of the load long wires represent higher capacity and hence need lower resistors to achieve a certain clock rate image so you may go down to 3k3 or 2k2 instead of 10k but those may do better: https://www.sparkfun.com/products/11955

duckman1961 commented 5 years ago

Just tested the Duiontech, it has 1 x 10K on the 3.3V TX leg, none on the RX, the same on the 5V side, 10K on TX no resistors on the RX, so will go thru my resistors and see if l can put some on the RX. What is the GND doing on the Duiontech level shifter?

jps2000 commented 5 years ago

I do not understand this breakout without having a schematic. also the pin description is weird circuit should be like above

jps2000 commented 5 years ago

Aha https://learn.sparkfun.com/tutorials/retired---using-the-logic-level-converter https://cdn.sparkfun.com/assets/b/0/e/1/0/522637c6757b7f2b228b4568.png it seems to be a clone of a retired sparcfun design so you have to use just the pins on the corners and supply HV with 5V and LV with 3V3 The HV supply is opposite to the LV supply. The HV and LV signals are also on the same side of the pins like the supply voltages You do not need to connect GND

duckman1961 commented 5 years ago

Morning Peter, well l tried with the level shifter with the SCL,SDA on the outside terminals (TX, 1 with 10k pullups) without luck at 100khz and 400khz. Your scanner is seeing it on 0x4B (which previously with the level shifter it couldn't and of course have changed your code address). Tried Sparkyfun code (default address 0x4B,Wire instead of I2C) and it is now working on 400khz, were without the level shifter it didn't. Will look for some 2.2k resistors and put on the RX channels and try that.

duckman1961 commented 5 years ago

I should add, on your code that l do get live data with the level shifter connected with its own pullups at 400khz at times (sometimes first time others 3-4-10-15 restarts on 300mm wires). Tried with a mix of resistors 2.9K and 4.7k but could not even pick up the address. When l do get live data at 400khz the TARE isn't resetting the Q's Your code does start on 5M+ cable at about the same restarts as on 300mm wires. Sparkyfun at 400khz on 5M+ of cable, starts ever time.

jps2000 commented 5 years ago

Which one of my codes do you use now and which wire library? the special I2C library of example 1 does only work with 328 processors but NOT on a M0 or others! So with you processor you should only use Arduino_BNO080_2.ino code. The problem may be that when the communication is not sound that it takes multiple communications that it works. When you can not pick up the address or a wrong then this says everything. It should be according to your address setting of the BNO (SA0 pin ) ; not others. The program hangs in the while loop and does not go further. This MUST work EVERY TIME at 400kHz speed.

A potential cause may be that the BNO does not reset properly when connected to VCC. It may help to put a 1k resistor from the 3V3 (VCC of the BNO) to ground. This achieves to get the VCC below 0.7V rapidly to do a proper reset after next power on. The reset pin does not help completely as some sensors inside needs VCC reset.

Then it is essential that in the setup the command set_feature_cmd_QUAT(); is recognized by the BNO This is only possible if the the BNO has sent a lot of stuff. So there need to be a delay increase it to 200 or 300
But if you are happy with the sparkfun code - no worry. just use it. It just does nor fit in a nano Is tare working in sparkfun code? It may be that your button is still not working. tare requires also calibration first if I remember correctly.

duckman1961 commented 5 years ago

Hi Peter, using your BNO080_ 02 we have a winner (so it is something to do with Wire and the GY-BNO08x).
For anyone else struggling like me, some help below. Had to fix a compile error as you are missing a brkt line 196 if((cargo[9] == quat_report)
defined a Nano (leave as this for a Mega) instead of nrf52

Add below after line 134 // calculate euler angles float yaw = atan2f(Q1 Q2 + Q0 Q3, Q0 Q0 + Q1 Q1 - 0.5f); float argument = 2.0f (Q1 Q3 - Q0 Q2); // may be > 1 due to rounding errors --> undefined if (abs(argument) > 1.0f) argument = 1.0f; float pitch = asinf(argument); float roll = atan2f(Q0 Q1 + Q2 Q3, Q0 Q0 + Q3 * Q3 - 0.5f);

yaw += PI * 0.5f; // correction of the y axis direction
if (yaw < 0) yaw += 2.0f * PI;
if (yaw > 2.0f * PI) yaw -= 2.0f * PI;

yaw   *= radtodeg;
yaw    = 360.0f - yaw;
pitch *= radtodeg;
roll  *= radtodeg;

roll = -roll;// negate roll so right side down = +
pitch = -pitch;// negate pitch so up = +

Serial.print ("YAW                    "); Serial.print ("    "); Serial.print (yaw); Serial.print ("    "); Serial.print ("PITCH    "); Serial.print ("    "); Serial.print (pitch); Serial.print ("    "); Serial.print ("Roll    "); Serial.print ("    "); Serial.println (roll);

Comms straight away, l did look at this code but didn't carry on with it due to compile error. TARE does 1 +0 q's, but it resets yaw to 270 degrees ( which is were it starts in GameRotationVector) and flips the pitch and roll. If l re calibrate it does Euler's correctly. That is after l re soldered the pins up the other way on the GY-BNO08X, it should be screen print down for correct N.E.D I also only ever wired the 3.3v, Gnd,SCL, SDA, none of the other options. I just jumped the pins for TARE and Cal to Gnd. So no reset or interrupt was wired. The reason l didn't stick to the Sparkfun is they haven't coded in the TARE in there library, which l started to do, but it was taxing my limited coding skills. So will keep playing. Any idea on fixing the very slow heading update, so l can then do a really test around the compass. Thanks and l appreciate your assistance and perseverance. Regards Kevin

jps2000 commented 5 years ago

great Thank you reporting this error. I have adapted the code accordingly. No worry with orientation: in line 209 you can shuffle around orientation of the sensor (mounting) exchange b with c and change signs etc. Do not touch Q0 = a. tare makes always 1,0,0,0 independent of the euler calculation later in my euler example there is the line yaw = 360.0f - yaw; where you can correct any offset. so replace 360 by 90 will cause 0/360 deg yaw. heading update should be fast once cal is correct Which cal do you have in setup? maybe better comment this line out

duckman1961 commented 5 years ago

Peter, am l correct in thinking you don't actual have the Calibration procedure (mag,accel,gyro), it looks like you use the auto cal feature, then it's sends that to ram when T6 is GND then released or powered off? After re reading TARE data sheet l see for me it has no benefit at all, so won't worry about it any more. Re heading, it takes up to 20 seconds for it to stabilise when tilted, are you see that? my stat is 3 and h_est = 1.4 degrees. I see in data sheet we can play with filter gains, so more learning and playing coming up How do l code in No to auto cal. Maybe like below, in start up. ME_cal(1, 1, 1, 0);//P0 = accelerometer, P1 = gyro; P2 =magnetometer; P4 = planar accelerometer (without Z axis) So ME_cal(1,1,0,0) //accel,gyro =on, mag, planer = off ????

I will retry Sparkfun cal code and save to ram and then would like for your code to have auto cal off. Actual just started reading the SH-2 sheet, so l will carry on playing , but if you are able to help re above, it would be greatly appreciated. Regards Kevin

jps2000 commented 5 years ago

Corrrect; 1 = on 0 is off default after reset when not calling ME_cal is(1,0,1,0); so gyro is off That is also mentioned in the tare application note So after setup and warm up ( 1 minute) do calibration movements as described there and then press cal button that saves the cal results to memory and is present after next startup The 20 sec delay I do not see

jps2000 commented 5 years ago

Accelerometer: For 3D calibration the device should be moved into 4-6 unique orientation and held in each orientation for about 1 second to calibrate the accelerometer For planar calibration the device should be rotated around it Z-axis by at least 180 degrees Gyroscope: Device should be set down on a stationary surface for approximately 2-3 seconds to calibrate the gyroscope Magnetometer : Device should be rotated about 180° and back to the beginning position in each axis (roll, pitch and yaw). Device should be rotated about 2 seconds on each axis.

So having set ME_cal (1110) you do above calibration motions in your final environment. ME_cal (1110) is done in the setup already. Then save the result and switch autocal off set ME_cal (0000) or whatever you like. This is done by pressing cal button) You can make an extra button that do ME_cal (1110) to start autocalibration again SO the bno is doing continuously autocal. You can switch autocal off and store the results for next power on.

duckman1961 commented 5 years ago

Thanks again Peter, it is as l thought. My request for help is now closed

jps2000 commented 5 years ago

This does not sound enthusiastic what is still the problem?

duckman1961 commented 5 years ago

Hi Peter, as l have posted re your code the Yaw changes are too slow to be usable at approx 20 seconds to stabilise. Sparkfun's code settles in 4-6 seconds but like yours is <+-0.5 jittery. If you are able to advise how to rectify this issue l would say it is a great IMU (subject to confirming there is no velocity induced issues for this IMU) . So in testing the GY-BNO08X outside yesterday l got Max tilt induced Yaw error of approx -4, +3 degrees, but due to jitters it could be more. So that makes this IMU slightly ahead of the others in tilt induced error. The cost is against it compared to the GY-MPU9250 at <$5AUD delivered. l now have a GY_BNO08X and will at some stage code it into my AP. l will still be using the Pololu V3 as main compass as it has proven to be very reliable (over 5000 miles) with , maybe +-0.1 degree jitter, but up to 12 degree tilt error, but l use it in a gimbal so that negates the tilt error. Maybe my problems are related to this being a Chinese copy of the BNO080? Below Excel 2010. Regards Kevin

BNO055, GY-BNO08X, MPU9250, NXP.xlsx

duckman1961 commented 5 years ago

Maybe l'm being a bit harsh, l changed reporting_frequency = 400; plot_interval = 20; // plot interval in ms and times are now 10+ seconds, but it is hard to tell with the jitter. Update hz is about 35-40ms I know you say serial slows up the data, but l can get others to print below 10ms (125hz) . Regards Kevin

jps2000 commented 5 years ago

20ms is much too fast for plotting would not go faster than 250 or 500 ms reporting freq. may be 200 or 100 should give more integration.

reaction time could be low if output is only processed rarely due to bus load

have you tried 6dof also ( 0x08 reporting instead 0x05) just to see if jitter is gone; stability etc

jps2000 commented 5 years ago

I also strongly suggest to degauss the sensor and the board /fixation take a coil of a magnetic valve. Replace the valve by an iron screw. switch coil on at 1m distance. then move coil close to the sensor and all components remove coil 1m away and switch it off

re calibrate sensor

mount the board only with one screw to avoid mechanical stress on the chip

duckman1961 commented 5 years ago

Yes had tried gaming mode, which was very stable, but due to no mag, no North reference the Gyro just drifts away. So short term result was good, but after some minutes the heading drifts. plot 250, frq 200 = approx 35ms update. I do have a degauss from a TV which l will run it through tomorrow, but l can't see that changing things, as l have used it on other IMU's without any gain. My IMU is taped to a block of wood so there isn't any issues there.

duckman1961 commented 5 years ago

What was interesting was l had tried to check the heading by putting a pair of pliers beside the IMU, the yaw didn't change, but the accuracy went up to 20+ from 1+. Then l moved the pliers away quickly the yaw went crazy. I changed from Mag cal on and also off, with no difference to the result

jps2000 commented 5 years ago

degauss is important as chips and crystal etc of your sensor board can be magnetized. this demonstrates clearly your experiment also degauss your pliers, screw drivers etc as well best is really what I proposed with the magnetic valve coil. I know this from ancient tape recorders

jps2000 commented 5 years ago

looked in your excel interestingly in many of your measurements you had largest yaw deviation @ ~240deg despite using different sensors. How close is your magnetic compass? Any other magnetised parts in the environment?