Question for BNO055

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
OdysseySs
 
Posts: 13
Joined: Sat Dec 31, 2022 6:54 am

Re: Question for BNO055

Post by OdysseySs »

No this isn't simple servo interface.
The arduino taking some other info to light up headlight on low, high & 2 cornering beam.

User avatar
OdysseySs
 
Posts: 13
Joined: Sat Dec 31, 2022 6:54 am

Re: Question for BNO055

Post by OdysseySs »

I just made a pretty simple code.
That take the Get Vector in float value and apply in the servo.

And there is still he issue.
There no timer, no print in the loop, no delay...

The code is in my folder in the name : Test - BNO + 1 Servo.ino

User avatar
gammaburst
 
Posts: 1016
Joined: Thu Dec 31, 2015 12:06 pm

Re: Question for BNO055

Post by gammaburst »

I see that you are using conventional PWM servos:
http://wiki.sunfounder.cc/index.php?tit ... ital_Servo

I reproduced the twitching problem.
The culprit is Arduino's broken Servo library. It generates inconsistent PWM pulse widths. It's sensitive to other program activity. I don't know why. My wild guess - it uses interrupts unwisely.

Try this experiment. I tilt the BNO055 and my servo moves smoothly:

Code: Select all

#include <Adafruit_BNO055.h>

#define ServoPin 11

Adafruit_BNO055 bno = Adafruit_BNO055();

void setup()
{
  bno.begin();
  pinMode(ServoPin, OUTPUT);
}

void loop()
{
  imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

  noInterrupts();
  digitalWrite(ServoPin, 1);
  delayMicroseconds(1500 - 1000/90.0 * euler.z());
  digitalWrite(ServoPin, 0);
  interrupts();

  delay(20);
}
This experiment moves my two servos smoothly:

Code: Select all

#include <Adafruit_BNO055.h>

#define ServoPinRoll  11
#define ServoPinPitch 13

Adafruit_BNO055 bno = Adafruit_BNO055();

void setup()
{
  bno.begin();
  pinMode(ServoPinRoll,  OUTPUT);
  pinMode(ServoPinPitch, OUTPUT);
}

void loop()
{
  imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);

  noInterrupts();
  digitalWrite(ServoPinRoll, 1);
  delayMicroseconds(1500 - 1000/90.0 * euler.z());
  digitalWrite(ServoPinRoll, 0);
  interrupts();

  delay(10);

  noInterrupts();
  digitalWrite(ServoPinPitch, 1);
  delayMicroseconds(1500 - 1000/90.0 * euler.y());
  digitalWrite(ServoPinPitch, 0);
  interrupts();

  delay(10);
}
IMG_2723a.jpg
IMG_2723a.jpg (565.16 KiB) Viewed 299 times

User avatar
OdysseySs
 
Posts: 13
Joined: Sat Dec 31, 2022 6:54 am

Re: Question for BNO055

Post by OdysseySs »

Hi Gammaburst,

Yeah it's the sunfunder PWM. The first that I've tested has an Issue I think he is little jammed
It's working pretty well thanks.
So it's my one of my lead in the beginning the Servo Library was that not completly compatible with the BNO.

When I was moving the BNO I don't know why it's not working and I was obligated to reset the board.
And I saw the Led shut down, My electric pod has some issue, I will fix it for the workbrench.

I have a question about the driving with the micro delay:
delayMicroseconds(1500 - 1000/90.0 * euler.z());

The 90.0 is value set for the servo at the beginning ?

User avatar
gammaburst
 
Posts: 1016
Joined: Thu Dec 31, 2015 12:06 pm

Re: Question for BNO055

Post by gammaburst »

The Servo library is poorly designed. It's asking for trouble. The library documentation does not describe its weaknesses.

Good to hear that my experimental code works better for you. I recommend that you replace my code with a hardware timer or hardware PWM generator, so that you can keep interrupts enabled (for use by other things in your project). I don't know how to configure a timer on your microcontroller because every micro seems to have different timer architecture.

Common R/C servos require continuous rectangular pulses at approximately 50 Hz (every 20 milliseconds). You vary the pulse width to control the servo's output angle. A pulse width of 1500 microseconds moves the servo to its center position. You increase or decrease the pulse width to move the servo away from its center position. For some servos, a change of 1000 microseconds moves the servo 90 degrees. (Your servo may have a different ratio.) That's the equation I put into delayMicroseconds().

I'm guessing your servo behaves like that. I'm not certain.

More info:
https://en.wikipedia.org/wiki/Servo_(radio_control)

Suggestion:

Use an oscilloscope to help troubleshoot problems like this. When I first observed the twitching problem, I didn't know what was causing it. Inadequate power supply perhaps? I looked at my Arduino Uno's 5V output and saw it dipping slightly due to the servo current, but the dips did not coincide with the twitching. I moved the scope to the servo control signal, and immediately saw erratic pulse widths that coincided with the twitching. I've never seen a BNO055 do anything like that, so maybe it's a broken pulse generator. I noticed the pulses were coming from a library. I mumbled "it's probably full of bugs". So I replaced the library with a few lines of code that generate the pulses, and the twitching is gone.

Safety!

Remember this is a vehicle safety system. Imagine the microcontroller or servo getting stuck at a large tilt angle while you are winding down a highway.

The BNO055 has known problems during sustained acceleration such as in a moving vehicle. The pitch or roll angle can drift significantly. I don't have experience with this issue.

User avatar
gammaburst
 
Posts: 1016
Joined: Thu Dec 31, 2015 12:06 pm

Re: Question for BNO055

Post by gammaburst »

Another experiment - This runs on an Arduino Uno. It reads the BNO055 roll and pitch, and uses the 16-bit hardware timer (counting at 2 MHz) to generate PWM pulses for the roll and pitch servos. The pulse outputs are locked to pins 9 and 10.

Code: Select all

// Arduino Uno: read BNO055 roll and pitch, use 16-bit timer (counting at 2 MHz) to generate two PWM outputs to two servos

#include <Adafruit_BNO055.h>

Adafruit_BNO055 bno = Adafruit_BNO055();

void setup()
{
  bno.begin();

  DDRB  |= _BV(PB1) | _BV(PB2);                     // set both pins as outputs
  TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM11);  // non-inv PWM, Mode 14: fast PWM, TOP=ICR1
  TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS11);     // prescaler 8 gives 2 MHz count rate
  ICR1   = 40000;                                   // TOP counter value (relieving OCR1A), 20 ms counter period
}

void loop()
{
  imu::Vector<3> euler = bno.getVector(Adafruit_BNO055::VECTOR_EULER);  // takes 1 to 2 ms

  int16_t roll  = 3000 - 2000/90.0 * euler.z();     // 1.5 ms + (1.0 ms per 90 degrees of rotation)
  int16_t pitch = 3000 - 2000/90.0 * euler.y();
  OCR1A = max(1000, min(5000, roll));               // limit pulse width, output to pin 9, roll servo
  OCR1B = max(1000, min(5000, pitch));              // limit pulse width, output to pin 10, pitch servo
}

User avatar
gammaburst
 
Posts: 1016
Joined: Thu Dec 31, 2015 12:06 pm

Re: Question for BNO055

Post by gammaburst »

The 16-bit hardware timer approach may be your best option. It's stable, it consumes almost zero CPU time, it's immune to your CPU's other activities, and it doesn't require or care about delays or interrupts. It uses Timer/Counter1 which is tied to two specific pins (or one pin if you need only one servo), so those things must be available. Your Nano has a 16 MHz ATmega328P just like the Arduino Uno, so my experimental code may work for you immediately.

User avatar
jps2000
 
Posts: 811
Joined: Fri Jun 02, 2017 4:12 pm

Re: Question for BNO055

Post by jps2000 »

Excellent @gammaburst.
However, you are violating your " Do not use BNO055 Eulers" rule. :-)

User avatar
gammaburst
 
Posts: 1016
Joined: Thu Dec 31, 2015 12:06 pm

Re: Question for BNO055

Post by gammaburst »

Ha!
You're right. In this application I'm relaxing my rule.
As the BNO055 tilts, other things will begin distorting before the Euler angles.

Wait a minute ... will this BNO+servo design work inside a globe of death? I think the accelerometer would saturate, and who knows about the fusion algorithm. Need to slap yet another ugly warning sticker on the product.

User avatar
OdysseySs
 
Posts: 13
Joined: Sat Dec 31, 2022 6:54 am

Re: Question for BNO055

Post by OdysseySs »

Hi,

I made a little break on this, I've been seek.
gammaburst wrote: Fri Jan 06, 2023 7:12 am Safety!

Remember this is a vehicle safety system. Imagine the microcontroller or servo getting stuck at a large tilt angle while you are winding down a highway.

The BNO055 has known problems during sustained acceleration such as in a moving vehicle. The pitch or roll angle can drift significantly. I don't have experience with this issue.
Don't worry, this is not not my main headlight.
And I working since 2 years on my little free time on the electronic, mechanical, etc... I made a thing that have issue instead nobody try to strike the headlight.
And I can reset or cut the system from the dashboard.

I only use the euler.z() and not the pitch. Because the pitch is set by different potentiometer and up and down with the roll to stay at the same height.

I will try the different thing for the microdelay with timer or not and with 6 servos at the same time.
And I need to find a DC-DC converter with a large amp for the start I have maybe the product and I need to order it and integrate to my new box.

When all the things are ok, I will order my new PCB for the system.
jps2000 wrote: Sun Jan 08, 2023 2:51 am Excellent @gammaburst.
However, you are violating your " Do not use BNO055 Eulers" rule. :-)
gammaburst wrote: Sun Jan 08, 2023 5:27 am Ha!
You're right. In this application I'm relaxing my rule.
As the BNO055 tilts, other things will begin distorting before the Euler angles.

Wait a minute ... will this BNO+servo design work inside a globe of death? I think the accelerometer would saturate, and who knows about the fusion algorithm. Need to slap yet another ugly warning sticker on the product.
I don't have the reference for this.

I try tilt in every direction and try to reproduce the acceleration of the bike to destabilise the BNO but it stay at the same angle for the roll.

I have maybe a plan to use the acceleration X for the down or up when I accelerate or brake to stay at the same height but for the moment it's not for sure that I'm using it.

Br,
Alexis

User avatar
gammaburst
 
Posts: 1016
Joined: Thu Dec 31, 2015 12:06 pm

Re: Question for BNO055

Post by gammaburst »

Hi Alexis,

For seven years I've been warning folks about the BNO055's Euler math problem - its Euler orientation become distorted during combined steep-pitch-roll angles. That's old news - jps2000 and I sometimes joke about it. You won't see this problem riding your bike on roads and hills, but you could see it while riding in a globe of death (that's a joke, or maybe not??).

While riding (not while sitting still) you may see the BNO055's fusion problem. After several seconds of sustained acceleration, its fusion algorithm sometimes mistakenly changes its internal gravity vector, and that upsets its pitch or roll outputs. I don't use the BNO in a moving vehicle so I've never observed this problem, but many folks have discussed it in old forum messages, for example this thread has over 150 messages:
viewtopic.php?p=397706

I understand that moving the headlight up/down is different than merely using the BNO's pitch output. For example, riding up or down a hill.

My Arduino Uno with hardware timer and two servos is sitting here on my desk. It's fun to play with, like a fidget toy. It's been running fine for days.

User avatar
gammaburst
 
Posts: 1016
Joined: Thu Dec 31, 2015 12:06 pm

Re: Question for BNO055

Post by gammaburst »

Hi basilavad,

The BNO055 datasheet warns:
"The linear acceleration signal typically cannot be integrated to recover velocity, or double-integrated to recover position. The error typically becomes larger than the signal within less than 1 second if other sensor sources are not used to compensate this integration error."
Are you planning to use additional sensors?

Next time please create a new topic for your question rather than adding it to a discussion about servos and headlight stabilization.

User avatar
OdysseySs
 
Posts: 13
Joined: Sat Dec 31, 2022 6:54 am

Re: Question for BNO055

Post by OdysseySs »

Hi Gammaburst,

Okk I will test it on the bike if I see this issue I hope not. Because I choice the BNO to avoid it.

I tested with a UNO and a NANO with 6 Servo with the basic one of upper.
And it's work perfectly, I can upload the video if you want, it's quiet funny to see.

But I don't understand the Microdelay to do what I want.

Code: Select all

delayMicroseconds(1500 - 1000/90.0 * euler.z());
- 1500: It's to move to center position
- 1000/90: To obtain the ms of 1° ? It's What ?

Normally I have 4 differents command:
- Z:

Code: Select all

delayMicroseconds(1500 - 1000/90.0 * euler.z());
We have already this one.

- Y: Depend on witch side I leaned.
I have 3 potentiometer, One General to up & down both side and 1 for each side the same height. This for the set
But when I lean on each side, the inside beam is lower and the other is upper. My plan to use a percentage of Euler Z to correct. There is a ratio on the gears such as 1/10 to have more precision at each degree of the servo and less backlash, so I was like:

Code: Select all

delayMicroseconds(1500 - 1000/90.0 * (10*(PG+PL+(0.1*euler.z()))))
10: Ratio Gear, 10 of Servo for 1 degre for the beam
PG: Pot General Height
PL: Pot Left Height
0.1*euler.z(): Ajustment of 10% of Angle

- X: Each side turn on side where I Go:
So if I go to left, The beam turn to inside left and right stay at is position.

Code: Select all

delayMicroseconds(1500 - 1000/90.0 * (5*(0.6*euler.z()));
5: Ratio Gear
0.6*euler.z(): I've a average at maximum of 25° of lean each side and I've 15°orientation of my 3D piece.
I will put a condition to stop at 25.

I'm in right for the calculation of Delay or completly wrong.

Thanks in advance.

Br,
Alexis

User avatar
gammaburst
 
Posts: 1016
Joined: Thu Dec 31, 2015 12:06 pm

Re: Question for BNO055

Post by gammaburst »

Hi OdysseySs,

Your servo responds to pulse width modulation. The microcontroller sends rectangular pulses to the servo at about 50 Hz. The servo changes its rotation angle according to the width of those pulses. My small servo rotates from -90 to 0 to +90 degrees as I apply pulse widths from 500us to 1500us to 2500us. That's how I derived my delayMicroseconds() equation -- center is at 1500us, and a change of 1000us causes 90 degrees of rotation. Your servo may require a different equation. Refer to its datasheet to learn exactly how it responds to pulse widths.

"6 Servo with the basic one of upper" -- something there was lost in translation.

You lean -25 to +25 degrees and your headlight has 10:1 gear reduction -- that means your servo must rotate -250 to +250 degrees to maintain a level headlight. Can your servo rotate that far?

"delayMicroseconds(1500 - 1000/90.0 * (10*(PG+PL+(0.1*euler.z()))))"
If your headlamp has 10:1 gear reduction, then the equation's "10*" seems correct, but the "0.1*" seems incorrect because it counteracts the "10*".

User avatar
OdysseySs
 
Posts: 13
Joined: Sat Dec 31, 2022 6:54 am

Re: Question for BNO055

Post by OdysseySs »

gammaburst wrote: Tue Feb 07, 2023 8:56 am
Your servo responds to pulse width modulation. The microcontroller sends rectangular pulses to the servo at about 50 Hz. The servo changes its rotation angle according to the width of those pulses. My small servo rotates from -90 to 0 to +90 degrees as I apply pulse widths from 500us to 1500us to 2500us. That's how I derived my delayMicroseconds() equation -- center is at 1500us, and a change of 1000us causes 90 degrees of rotation. Your servo may require a different equation. Refer to its datasheet to learn exactly how it responds to pulse widths.
I found the complete Datasheet

2023-02-07 22_27_55-TD-8120MG_Digital_Servo.pdf et 10 pages de plus - Personnel – Microsoft​ Edge.png
2023-02-07 22_27_55-TD-8120MG_Digital_Servo.pdf et 10 pages de plus - Personnel – Microsoft​ Edge.png (42.63 KiB) Viewed 80 times

So it's 500 to 2500 µs
gammaburst wrote: Tue Feb 07, 2023 8:56 am "6 Servo with the basic one of upper" -- something there was lost in translation.
No like in French, the word are just lost in my mind.
I was saying that I put the same code for the microdelay six times on each PWN output: 3,5,6,9,10,11.
And It works
gammaburst wrote: Tue Feb 07, 2023 8:56 am You lean -25 to +25 degrees and your headlight has 10:1 gear reduction -- that means your servo must rotate -250 to +250 degrees to maintain a level headlight. Can your servo rotate that far?
Not at all, he has a range of 270°
But If you want the Servo is in horizontal for the initial position and a Head light go down for 5-6°and 2-3° on upper on lean to adjust. So I need 100° for this.
gammaburst wrote: Tue Feb 07, 2023 8:56 am "delayMicroseconds(1500 - 1000/90.0 * (10*(PG+PL+(0.1*euler.z()))))"
If your headlamp has 10:1 gear reduction, then the equation's "10*" seems correct, but the "0.1*" seems incorrect because it counteracts the "10*".
The ''10'' is in the beginning, the ''0.1'' is to adjust by a percetage that I will find when I drive my moto. And It was an example maybe it will be 20%-30% of euler Z to be at the same Height when the bike is at angle 0.

Br,
Alexis

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Products from Adafruit”