Sparkfun BNO080 - Teensy 3.6 >> 4.0

Status
Not open for further replies.
Just to be clear the data I posted is from gyrotest2

When you move the bno080, the data change?
the issue might be related to the radio module maybe then ?

I wish someone else would be able to test sparkfun radio module and bno080, because either it is something we are doing wrong or something is wrong somewhere else ?
 
Yes. But remember what I said about the error in your sketch for getting dcc and dy.

You have to set prevquat to currentquat after you calculate dcc and dy.
 
Yes. But remember what I said about the error in your sketch for getting dcc and dy.

You have to set prevquat to currentquat after you calculate dcc and dy.

I will ask Hiran to create an account and reply here. He is writing the code.
Thank you so much! We live in different time zones so we would potentially reply at different times of the day.

We were using a bno050 on a t32 to control an emulated mouse but we have issues with the low polling rate due to bno055 and radio delays.
The hope /idea was to test with the bno080, but we have been running in all sort of issues even before being able to test the polling rate of the emulated mouse using the bno080



We have been working on emulating mouse and joystick for adding head movements in certain games.

We have been working also on hand controllers using exoskeleton for both VR gaming and regular gaming.
We use teensy boards

https://www.youtube.com/watch?v=DYrK1zF27YU

a1c0c43ea1c49dcc93f1921cf7ba114ec1d65789.jpg


Would be very grateful getting help please
 
Last edited:
@marcob - very cool project.

Ps this is the main sketch I am using that I fixed so the setting of the prevQuat is in the correct spot:
Code:
#include <Wire.h>
#include "quaternion.h"
#include "SparkFun_BNO080_Arduino_Library.h"

BNO080 myIMU;

#define X_AXIS_SENSITIVITY  50
#define Y_AXIS_SENSITIVITY  50

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("BNO080 Read");
  
  Wire.begin();

  if (myIMU.begin() == false)
  {
    Serial.println(F("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing..."));
    while (1)
      ;
  }

  Wire.setClock(400000);
  
  myIMU.enableGyroIntegratedRotationVector(5); 

  Serial.println("Started!!!");
}

imu::Quaternion prevQuat;
int dx = 0, dy = 0;

void loop()
{
  //Look for reports from the IMU
  if (myIMU.dataAvailable() == true)
  {
    float dqw = myIMU.getQuatReal(); float dqx = myIMU.getQuatI(); float dqy = myIMU.getQuatJ(); float dqz = myIMU.getQuatK();
    imu::Quaternion currQuat(dqw, dqx, dqy, dqz);
/*
    Serial.print(dqx, 2);
    Serial.print(F(","));
    Serial.print(dqy, 2);
    Serial.print(F(","));
    Serial.print(dqz, 2);
    Serial.print(F(","));
    Serial.println(dqw, 2);
    Serial.printf("currQuat--> %2.2f, %2.2f, %2.2f, %2.2f, %2.2f\n", currQuat.w(), currQuat.x(), currQuat.y(), currQuat.z());
*/
    
    imu::Quaternion newQuat = currQuat * prevQuat.conjugate();
    newQuat.normalize();
    imu::Vector<3> euler = newQuat.toEuler(); 

    dx = getValue(euler.z() * 180 / PI, X_AXIS_SENSITIVITY, false);
    dy = getValue(euler.y() * 180 / PI, Y_AXIS_SENSITIVITY, false);

[B][COLOR="#FF0000"]    prevQuat = currQuat;
[/COLOR][/B]    Serial.printf("dx, dy: %d, %d\n", dx, dy);
  }
}

int getValue(double val, double sensitivity, bool is_rotation)
{
  constexpr double c[] = { 3e-1, 1e-1 };
  return (int)round(val * sensitivity * c[unsigned(is_rotation)]);
}
I highlighted in red where I moved your setting the currQuat to the prevQuat. You had it before the calculation so dx and dy would always be zero. Nothing else was changed that matter.
 
@marcob - very cool project.

Ps this is the main sketch I am using that I fixed so the setting of the prevQuat is in the correct spot:
Code:
#include <Wire.h>
#include "quaternion.h"
#include "SparkFun_BNO080_Arduino_Library.h"

BNO080 myIMU;

#define X_AXIS_SENSITIVITY  50
#define Y_AXIS_SENSITIVITY  50

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("BNO080 Read");
  
  Wire.begin();

  if (myIMU.begin() == false)
  {
    Serial.println(F("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing..."));
    while (1)
      ;
  }

  Wire.setClock(400000);
  
  myIMU.enableGyroIntegratedRotationVector(5); 

  Serial.println("Started!!!");
}

imu::Quaternion prevQuat;
int dx = 0, dy = 0;

void loop()
{
  //Look for reports from the IMU
  if (myIMU.dataAvailable() == true)
  {
    float dqw = myIMU.getQuatReal(); float dqx = myIMU.getQuatI(); float dqy = myIMU.getQuatJ(); float dqz = myIMU.getQuatK();
    imu::Quaternion currQuat(dqw, dqx, dqy, dqz);
/*
    Serial.print(dqx, 2);
    Serial.print(F(","));
    Serial.print(dqy, 2);
    Serial.print(F(","));
    Serial.print(dqz, 2);
    Serial.print(F(","));
    Serial.println(dqw, 2);
    Serial.printf("currQuat--> %2.2f, %2.2f, %2.2f, %2.2f, %2.2f\n", currQuat.w(), currQuat.x(), currQuat.y(), currQuat.z());
*/
    
    imu::Quaternion newQuat = currQuat * prevQuat.conjugate();
    newQuat.normalize();
    imu::Vector<3> euler = newQuat.toEuler(); 

    dx = getValue(euler.z() * 180 / PI, X_AXIS_SENSITIVITY, false);
    dy = getValue(euler.y() * 180 / PI, Y_AXIS_SENSITIVITY, false);

[B][COLOR="#FF0000"]    prevQuat = currQuat;
[/COLOR][/B]    Serial.printf("dx, dy: %d, %d\n", dx, dy);
  }
}

int getValue(double val, double sensitivity, bool is_rotation)
{
  constexpr double c[] = { 3e-1, 1e-1 };
  return (int)round(val * sensitivity * c[unsigned(is_rotation)]);
}
I highlighted in red where I moved your setting the currQuat to the prevQuat. You had it before the calculation so dx and dy would always be zero. Nothing else was changed that matter.


Thank you so much!

Hiran will write here later tonight.
 
Yes. But remember what I said about the error in your sketch for getting dcc and dy.

You have to set prevquat to currentquat after you calculate dcc and dy.

Hi,
Thanks for your input on this matter. I'm working with him on this project.
The issue remains now is that when we power up the teensy bno080 is not detected sometimes. Turning on/off couple of times and it detect.

Here's the code of teensy.
View attachment GyroTest.zip

Thanks!
 
Wonder what would happen if you put in a delay at startup... Maybe something like:
Code:
void setup()
{
[COLOR="#FF0000"]  while(!Serial && millis() < 3000) ; // wait up to 3 seconds for the Serial port to be ready.[/COLOR]
  Serial.begin(115200);
  Serial.println();
  Serial.println("BNO080 Read");
  
  Wire.begin();

[COLOR="#FF0000"]  while(millis() < 3000) ; // Wait from startup 3 seconds before we try the IMU... [/COLOR]

  while (myIMU.begin() == false)
  {
    Serial.println(F("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing..."));
    delay(100);
  }

  Wire.setClock(400000);
...

Again not sure how you have setup. Example do you have the reset pin hooked up? If so I don't see anything setting the state of that pin.
Ditto I don't think you are using the interrupt pin...
 
I just gave the gyroTest2 sketch (no radio) with the following minor change:
Code:
  while (myIMU.begin() == false)
  {
    Serial.println(F("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing..."));
    delay(200);
  }
it worked for me everytime - max tries i saw by pulling the usb cable out and putting it back in was 2, i.e, total 400ms. Most of the time it started on the second try every time it failed to detect.

Not sure why its not working for you - can you test the BNO080 with just that change with the radio. To make sure you don;t have some other problem

EDIT:
What library are you using for your radio?
 
Wonder what would happen if you put in a delay at startup... Maybe something like:
Code:
void setup()
{
[COLOR="#FF0000"]  while(!Serial && millis() < 3000) ; // wait up to 3 seconds for the Serial port to be ready.[/COLOR]
  Serial.begin(115200);
  Serial.println();
  Serial.println("BNO080 Read");
  
  Wire.begin();

[COLOR="#FF0000"]  while(millis() < 3000) ; // Wait from startup 3 seconds before we try the IMU... [/COLOR]

  while (myIMU.begin() == false)
  {
    Serial.println(F("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing..."));
    delay(100);
  }

  Wire.setClock(400000);
...

Again not sure how you have setup. Example do you have the reset pin hooked up? If so I don't see anything setting the state of that pin.
Ditto I don't think you are using the interrupt pin...

Sure, will try it. No, we are just using i2c pins only. No interrupt pin is used. Thanks!
 
I just gave the gyroTest2 sketch (no radio) with the following minor change:
Code:
  while (myIMU.begin() == false)
  {
    Serial.println(F("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing..."));
    delay(200);
  }
it worked for me everytime - max tries i saw by pulling the usb cable out and putting it back in was 2, i.e, total 400ms. Most of the time it started on the second try every time it failed to detect.

Not sure why its not working for you - can you test the BNO080 with just that change with the radio. To make sure you don;t have some other problem

EDIT:
What library are you using for your radio?

Was having 100ms delay, yet sometimes needed to plug it again. Trying with adding delay. Thanks!
 
Ok using your gyro sketch with a nRF24L01+ attached to a T3.2 and sending to another nRF24L01+ attached to a T4.1 and using the following sketch on the T4.1 for receive:
Code:
/*
  TMRh20 2014

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  version 2 as published by the Free Software Foundation.
*/

/*
  General Data Transfer Rate Test

  This example demonstrates basic data transfer functionality with the
  updated library. This example will display the transfer rates acheived
  using the slower form of high-speed transfer using blocking-writes.
*/


#include <SPI.h>
#include "RF24.h"
#include "printf.h"

/*************  USER Configuration *****************************/
// Hardware configuration
RF24 radio(7, 8);                           // Set up nRF24L01 radio on SPI bus plus pins 7 & 8

/***************************************************************/

const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL };   // Radio pipe addresses for the 2 nodes to communicate.

byte data[32];                             //Data buffer for testing data transfer speeds

unsigned long counter, rxTimer;            //Counter and timer for keeping track transfer info
unsigned long startTime, stopTime;
bool TX = 1, RX = 0, role = 0;

void setup(void) {
  Serial.begin(115200);
  printf_begin();

  radio.begin();                           // Setup and configure rf radio
  radio.setChannel(1);
  radio.setPALevel(RF24_PA_LOW);           // If you want to save power use "RF24_PA_MIN" but keep in mind that reduces the module's range
  radio.setDataRate(RF24_2MBPS);
  radio.setAutoAck(1);                     // Ensure autoACK is enabled
  radio.setRetries(2, 15);                 // Optionally, increase the delay between retries & # of retries

  radio.setCRCLength(RF24_CRC_8);          // Use 8-bit CRC for performance
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1, pipes[1]);

  radio.startListening();                  // Start listening
  radio.printDetails();                    // Dump the configuration of the rf unit for debugging

  Serial.println(F("\n\rRF24/examples/Transfer/"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));

  randomSeed(analogRead(0));               //Seed for random number generation

  for (int i = 0; i < 32; i++) {
    data[i] = random(255);                //Load the buffer with random data
  }
  radio.powerUp();                         //Power up the radio
}

void loop(void) {

    while (radio.available()) {
      radio.read(&data, 32);
      counter++;
    }
    if (millis() - rxTimer > 100) {
      rxTimer = millis();
      unsigned long numBytes = counter * 32;
      Serial.print(F("Rate: "));
      //Prevent dividing into 0, which will cause issues over a period of time
      Serial.println(numBytes > 0 ? numBytes / 1000.0 : 0);
      Serial.print(F("Payload Count: "));
      Serial.println(counter);
      counter = 0;
    }

}
along with the 200ms delay in the loop I have had no problems with the gyro sketch. I removed power rapidly and slowly still started without any issues except maybe it took an extra try. I also just sent the T3.2 a reset several times with out an issue.

At this point not sure what else to say or try. Unless there is an issue with wiring or the units or several other things. Might be other issues with your setup and what you have attached?
 
Hi guys, I am going crazy.

Could anyone of you please run this code and see if you have any issue?

I have also attached the arduino console during the uploading of the code


Thanks
 

Attachments

  • GyroTest-2021-07-22-1228.zip
    5 KB · Views: 54
  • New Text Document (8).txt
    92.1 KB · Views: 63
Last edited:
Hi guys, I am going crazy.

Could anyone of you please run this code and see if you have any issue?

I have also attached the arduino console during the uploading of the code


Thanks

Not sure what you mean not printing. Its printing the BNO080 read and Started messages.

No data is being printed since you don't has a Serial.println(buffer) after the sprintf - add it and you will see your data.

Sorry can't check the RF code since I took my setup down
 
Hi!
I had the same kind of problems using the Arduino MKRZero with the BNO080. Constantly getting false returned from dataAvailable(), and nothing but I2C Timeouts when I enabled debugging... I read almost this entire thread, made it 8 pages... then I got a few hints of what to try, using the unmodified SparkFun BNO080 libarary and samples.

1) I added:
while (!Serial) {;} // ensure serial starts up, otherwise we see nothing on the MKRZero.

2) MOST IMPORTANTLY:
I changed this to that...
myIMU.begin()
myIMU.begin(0x4A); // Because 0x4A is the default I2C address for the BNO080. Change to 0x4B as needed.

3) TA DA! WORKS FINE for all the SparkFun BNO080 samples.

--Scott
 
Status
Not open for further replies.
Back
Top