jps2000 / BNO080

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

FSM300 #11

Closed mlw94 closed 4 years ago

mlw94 commented 4 years ago

Hi,

Relatively inexperienced user here, so please excuse the general ignorance. I'm having trouble getting your examples working using an Arduino Uno and a FSM300. The code is verifying and uploading just fine. The furthest i'm getting on the serial monitor in any example is this:

11:48:15.623 -> 11:48:15.623 -> Basic code for running BNO080 on Arduino Nano etc. (Atmega 328p) V1.1 2017-07-16 11:48:15.657 -> 11:48:15.657 -> 11:48:16.130 -> Scanning for I2C devices... (SOMETIMES STALLS HERE) 11:48:16.164 -> 11:48:16.164 -> 11:48:16.164 -> **** set feature command quat ** 11:48:16.535 -> 11:48:16.535 -> **** configure ME cal **

I'm using the following wiring : ('/' to indicate when i've tried multiple)

UNO ---------FSM300 3.3v-----------VDD GND----------GND SCL/A4--------SCL SDA/A5--------SDA

I've also tried using 2.2k pullups on the SCL and SDA lines.

Uncommenting SerialDebug doesn't seem to have any effect.

I don't believe there's anything wrong with my soldering or any damage to the FSM300, as i've gotten it working with the software provided by Hillcrest. Unfortunately, I still need it working on Arduino.

Thanks in advance for any help you could provide.

Best,

Merlin

jps2000 commented 4 years ago

You need a I2C level shifter as the Uno is 5v and the BNO is 3V3!!!!!!!!!!! like this https://www.adafruit.com/product/757 And you better should use the .2 example. This is more up to date

mlw94 commented 4 years ago

Hi Again,

Thanks for your quick response!

I've added a bidirectional level shifter, and i seem to be able to detect the BNO sometimes, but i'm still getting weird output. I've tried with and without pullups, and addresses 0x4A and 0x4B.

I've also uncommented the i2c scanner which seems to report random addresses? ie 0x8, 0x14. There doesn't seem to be a pattern as to which.

12:09:48.374 -> Rock bottom code for BNO080 on Atmega 328p; Cortex M0 (Simblee) and M4 (nrf52) V1.1 2018-12-30 12:09:48.374 -> ** 12:10:05.130 -> Rock bottom code for BNO080 on Atmega 328p; Cortex M0 (Simblee) and M4 (nrf52) V1.1 2018-12-30 12:10:05.130 -> 12:10:05.177 -> BNO found 12:10:05.177 -> SHTP advertising: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 12:10:17.995 -> Rock bottom code for BNO080 on Atmega 328p; Cortex M0 (Simblee) and M4 (nrf52) V1.1 2018-12-30 12:10:17.995 -> ***** 12:10:18.042 -> BNO found

Is there anything i should be doing differently with an Uno rather than a Nano?

Thanks again for your help.

Merlin

jps2000 commented 4 years ago

This is the circuit how to connect for I2C bus mode grafik You see PS0 must be connected to GND BOOTN, INTN NRST can be left open. Bidirectional level shifter is a must It shold have I2C pullups included so no extra are needed I2C adress ist 4A grafik In the code you define nano You can uncomment the I2C scanner and it should report always 0x4A . good luck you are coming closer

mlw94 commented 4 years ago

Thanks for all your help! It's working!

Thanks again for the library too.

Merlin

jps2000 commented 4 years ago

great congratulation

mlw94 commented 4 years ago

Hi again,

As i'm using the BNO080 for head orientation tracking applications, i'd like to be able to use the gyro rotation vector. The data sheet states that this is on a different channel than the rest of the reports. I've tried to find where in your code you select the channel, in the hope that i could work out how to get it myself, but i've had no luck.

Could you advise on how to get the gyro rotation vector? Will it be better for my applications?

Thanks,

Merlin

jps2000 commented 4 years ago

Hi To get gyro data from BNO080 you have to adapt some code accordingly: set_feature_cmd_QUAT(); and get_QUAT(); The first tells the BNO to send requested data and the second reads it. You need to walk through the data sheet an try first to understand how those quat examples work and then change them to gyro. But most likely you do not need raw gyro data at all. Gyro data are used anyhow in the fusion software to calculate orientation. Quats is all what you need. But you need to explain your application. The more acurrate the description the better I can help.

mlw94 commented 4 years ago

Hi,

Thanks for your reply, I'm not looking for raw gyro data, but the "gyro rotation vector" which the datasheet lists as a lower latency but less accurate version of the rotation vector, relying a little more heavily on the gyro i believe, which periodically corrects to the rotation vector.

I've tried to modify the code, but the problem is that the gyro rotation vector is sent on a different channel, rather than address, to the other data (for lower latency apparently), and i can't find where that channel is specified in the code.

I'm trying to record the orientation of a rat's head as it moves around a complex environment as part of a neuroscience research project, if that helps. The datasheet states that the gyro rotation vector is more appropriate for AR/VR applications, so i think it'll work better for me.

Thanks again for your help,

Merlin

jps2000 commented 4 years ago

I see. The problem is that I did my work on this already some years ago. So I do not remember everything and would have to dig into the spec and my notes and do some experiments which may take significant time (that I do not have at the moment). But I truly believe the the rotation vector running with 400Hz is sufficient for your application. you get fresh quaternions every 2.5 milliseconds (400Hz) . That is pretty fast. How do you send / record your data? What is the actual problem why you think "it'll work better for me" ? Do you know this: https://www.xsens.com/xsens-dot its a turnkey solution

mlw94 commented 4 years ago

No problem! That's completely understandable.

The rotation vector should be good enough, yes. I may simply apply an time offset to the data to cancel out the slightly higher latency. The only "problem" is how much of a delay i have between the neural recordings i am making and the orientation information being received, hence i thought that this may work better for me.

Thanks for recommending the xsens dot, unfortunately i don't think it'll work for me, as i need to record a TTL pulse along with the orientation readings for synchronisation with the neural data.

On another note, you mention in the code that serial output seriously reduces data rate. I've been using serial output and haven't noticed this, although i may not know what to look for. Can you recommend any other way of getting the data which doesn't have this problem?

mlw94 commented 4 years ago

Sorry, forgot to include, I'm using an Arduino Uno and recording the orentation and TTL pulse from the serial output using CoolTerm.

jps2000 commented 4 years ago

The delay you need can only be determined with an experiment. Wether the serial output - or other code- delays your software you can find out if you toggle a digital pin every time the main loop is done. Then you can look with an oscilloskope what is going on. Videos and data compression can also have significant time delay. Think about the lip sync problem. Likely the events you are monitoring do not come so fast that you fail to find coincidence. But for scientific purpose there is no way around validating your system.

mlw94 commented 4 years ago

That makes sense, I'll have a go at it! Thanks!

Last question, i don't trust myself to pull apart an old CRT monitor or tape deck for a degaussing coil. Would this one work? If not, could you recommend one which would?

https://www.amazon.co.uk/Screwdriver-Tweezers-Demagnetizer-Demagnetize-Repair/dp/B013UDW448/ref=sr_1_1?keywords=Degausser&qid=1582286102&s=diy&sr=1-1

jps2000 commented 4 years ago

this degausser should work. Alternative is a 110V (230V) solenoid from a magnetic valve. You have just to put an iron screw through it. Never operate it without an iron core. It will overheat quickly.

95Fox commented 4 years ago

This is the circuit how to connect for I2C bus mode grafik You see PS0 must be connected to GND BOOTN, INTN NRST can be left open. Bidirectional level shifter is a must It shold have I2C pullups included so no extra are needed I2C adress ist 4A grafik In the code you define nano You can uncomment the I2C scanner and it should report always 0x4A . good luck you are coming closer

in the code for the feather NRF52840 you say to use PIN 27 for NRST which pin on the feather board is this? can you descirbe which pin on the feather board is #27 there is no pic on adafruit web site showing pin 27. only A0-A5 and 5-13

jps2000 commented 4 years ago

I used P0.27 which is GPIO5 the pin next to SCL on the feathers. ( see schematics) However, you may asign any GPIO to NRST.

95Fox commented 4 years ago

I used P0.27 which is GPIO5 the pin next to SCL on the feathers. ( see schematics)

However, you may asign any GPIO to NRST.

I got it working and i am able to connect the adafruit app and see values etc..

I am unclear on how to calibrate it though. Can you describe to me on how i would calibrate roll angle and pitch angle etc... also heading for north is not correct

Thank you for replying

jps2000 commented 4 years ago

Calibration is described in the specification. You bring the sensor first in all orientations (every axis up and down) for about 2 seconds. ( Hold it on a table) This is acc calibration. For magnetometer cal needed for heading slowly rotate around each axis or do figure of eights in 3d space. Then you should achieve stat = 3.

95Fox commented 4 years ago

Calibration is described in the specification. You bring the sensor first in all orientations (every axis up and down) for about 2 seconds. ( Hold it on a table) This is acc calibration. For magnetometer cal needed for heading slowly rotate around each axis or do figure of eights in 3d space.

Then you should achieve stat = 3.

I understand that portion. What i dont understand is sending commands the “c” and “t”

Also how i only want to calibrate when i decide its time. I would like it to not go into calibration mode everytime it is powered on? Is there a way to only claibrate when a command is sent?

jps2000 commented 4 years ago

sending c stores the actual calibration data to have it available for next startup. In setup there is also in line 175: save_periodic_DCD(); // saves DCD every 5 minutes ( only if cal = 3) This updates automatically calibration data It turned out to be useful to do this. Calibration happens all the time anyhow.

95Fox commented 4 years ago

sending c stores the actual calibration data to have it available for next startup. In setup there is also in line 175: save_periodic_DCD(); // saves DCD every 5 minutes ( only if cal = 3) This updates automatically calibration data It turned out to be useful to do this. Calibration happens all the time anyhow.

ok, thanks i understand now. another question, i need to use this code on a teensy 3.6 board. would you know what it would take to modify to get it to run on the teensy:

https://www.pjrc.com/store/teensy36.html

i need to get the teensy to read the IMU data and then display.

jps2000 commented 4 years ago

never worked with teensy but this should be no problem. I would start with this example however Arduino_BNO080_2.ino

95Fox commented 4 years ago

never worked with teensy but this should be no problem. I would start with this example however Arduino_BNO080_2.ino

was something updated to the nrf52 feather file yesterday?

I have it working on a NRF52840 feather express, and it connects to bluetooth to my iphone properly and display values etc... but when trying to use the AHRS/Calibration on the app it will crash the app you have to restart. so that app functionality is not possible. is this normal?

I still need to get this running on the Teensy board. that has proven frustrating with i2c comms errors.

95Fox commented 4 years ago

can you tell me why this errors when trying to compile?

I have changed it to print roll, pitch, yaw, stat. I'd also like it to print accelerometer x,y,z

print test.txt

jps2000 commented 4 years ago

I updated just the comment on NRST pin definition

No Idea why it does not compile. Follow the error what the compiler says. Are you using Arduion IDE?

<<but when trying to use the AHRS/Calibration on the app>> I do not understand. You just move the sensor as described and then you send the letter c. There is no AHRS calibration on the app for the BNO

95Fox commented 4 years ago

it says roll not declared errr

95Fox commented 4 years ago

the nrf_52 feather code does not error like this, looks almost identical except for bluetooth items

jps2000 commented 4 years ago

"Almost identical" is sometimes not sufficient in software writing. When you define a parameter you need to declare what type it is so you missed the line float yaw,pitch,roll; To modify a code is an efficient method to learn programming. Watch carefully all the errors you get. The highlited line in arduino IDE is not pointing to the first error. So you need to go up in the assembler reporting window

95Fox commented 4 years ago

at this point i have everything working well with the FSM300 and sending its data over a CAN bus to a data logger.

I am having a problem though of slow updating of the channels pitch, roll, yaw. The CAN bus is 1M and the data logger is logging at 500hz. But the output of the code seems to be slow to update when changing the position of the FSM300.

is there something in your example code that can cause it to be slow to update? its over i2c which i thought was good enough for 400hz.?

also one other question, occasionally the fsm will stop and lock up at random times even when just sitting on the bench and not being touched. the board reset button will need to be pressed or power cycled to start the code running again. do you have any input as to why it randomly just shuts down?

attached is a picture of the channels logging and how slow they are updating.

in the pic the traces: yellow = roll angle blue = pitch purple = yaw imu log

jps2000 commented 4 years ago

Once you start the BNO it begins vomiting data. The host is expected to receive all the data. If the BNO can not send the data completely it tries to resend everything. That may slow down everything So you need to check how fast your main program can digest all the data coming from the BNO. First you should run the I2C bus at 400khz. check SCL with a scope. Then you can look at the INTN Pin with a scope. L means the BNO has data ready. when the pin is H then there is time for other tasks of the host. There can be the strange thing that setting lower output data rate of the BNO increase the data rate on the SD card. Try to lower the reporting frequency to 50 Hz for example. Also blocking can be caused by above described phenomenon.

95Fox commented 4 years ago

i have found solution to the slow updating. if you remove the serial plotter from your code, the imu will update very quickly at the manufacturers fastest rates. because the serial plotter for arduino ide was enabled in the code it slowed everything down being updated and transmitted.

attached is a new pic of a data log with the imu channels being logged at 500hz. they are now very smooth and realistic now with no blocky jumps. thank you for your help, i though i would relay this info for future people who may run into the same issues. datalogimu

jps2000 commented 4 years ago

Good that it works now. It is as I said above. The host must digest all the data coming from the BNO. If the controller is slowed down by whatever data rate is not as expected. Time budget in the loop is crucial.

95Fox commented 4 years ago

could you tell me how you had the FSM oriented for your code?

I currently have the FSM300 riented like this:

X= Forward ( X points to the direction of travel and ROLL will be around x axis) Y=Left (pitch will be around Y axis) Z=UP (towards sky, YAW will be around Z axis)

Is there something I need to change in the code so that the orientation would be correct with the direction of travel?

with the FSM on a vehicle in motion and experiencing high g's and high velocity, i am getting un realistic roll and pitch values from the FSM when compared to another brand of known good IMU that has correct values.

thanks for you help

95Fox commented 4 years ago

if you look at this screen shot, you can see the FSM shows similar characteristics to a known good IMU.

The white trace from this data log is a IMU from a OEM manufacture of vehicle.

The red trace is the FSM305. on the right of the pic is a GPS track map of the course that was used during this test.

you can see the FSM outputs the wrong roll and pitch values. a normal roll value for this vehicle is 65 degrees, no more. any more than that and it would be a crash. so the very high values the FSM is putting out are not reality. they are skewed for some reason. and their magnitude is off a bit as well.

if you have any thoughts on this it would be most helpful, as im trying to get the most accurate roll and pitch data that represents real world for this vehicle.

FSM305(1)

jps2000 commented 4 years ago

I suggest to follow general rules of debugging: That is to test with as simple as possible and well defined conditions. So what is the pitch/ roll angle when the sensor is flat on the table provided the _stat value is >=2 ? Then you may use a cardboard angle of 45 degrees and check correct pitch/ roll reading.

Which rotation vetctor and which data rate do you have? .... You need to understand that I can only help If enough informations are provided

95Fox commented 4 years ago

I forgot to mention that when sitting on a bench it works properly. Bench testing shows accurate angles. When flat it reads 0 and when tipped on its side it reads 90 one way and -90 the other

So sitting still it appears to work correctly

Here is video of bench testing

https://youtu.be/lr_5b7qM5AI

It is wired on i2c. And tested to work at 400

One thing that i unfortunately was not logging was the stat.

On the bench it will read 3

But i do not know what it was while on track

jps2000 commented 4 years ago

Ok then the code is fine. Probably you are loosing cal. How do you mount the metal box on the bike? Are there strong vibrations?. Is the box heating up from externally? Try to attach a mass to the sensor board ; 50-100grams or so ( lead) and then pack everything in foam and put all togehter in an outer housing that you then mount on the bike. In case the sensors are overload they can not deliver correct data.

95Fox commented 4 years ago

It is isolated from vibration quit well and in a area where heat is not present.

Is it possible to have it set in a manner where once its calibated it wont lose this?

jps2000 commented 4 years ago

good I would suggest to use game rotation vector (0x08) if you do not bother about yaw.

95Fox commented 4 years ago

is this the correct dev board to use? which one did you use?

https://www.digikey.com/product-detail/en/stmicroelectronics/NUCLEO-F411RE/497-14711-ND/4866485

jps2000 commented 4 years ago

there is no correct one. I use arduino ide and adafruit boards. nrf52832 feather for example.