Go Down

Topic: MPU6050 erratic values with MOTOR on LOAD - HELP! (Read 449 times) previous topic - next topic

r0yy

I have been working on a self balancing with the MPU6050 using DMP to get pitch values which I use it with a PID controller. The code seems to be working fine as shown in the video. But as soon as I put the bot on the ground to do its thingy MPU starts giving erratic values and the bot goes ham mostly causing arduino to freeze or the motor jitters.

I have gone through numerous articles and forums trying to debug.
I am powering the arduino uno from the USB and the motor controller(L298N) is powered by a 3S Lipo.
To eliminate the issue caused by motor noise I have added 3 0.1uf caps to both the motors. I am pretty inclined that its a hardware issue and not an issue on the code side. Would like to hear what do you guys think, pretty much stuck on this for couple of days now. Thanks for the help!


link to the video: https://youtu.be/diJG3d6wrv0

I have also attached the complete code if anyone wants to go through that

MartinL

Hi r0yy,

Have you tried enabling the MPU6050's digital low pass filter?

For example the following line of code sets the DLPF to bandwidth to 20Hz:

Code: [Select]
mpu.setDLPFMode(MPU6050_DLPF_BW_20);
The options are:

Code: [Select]
// Bandwidth | Accel BW (Hz) | Accel Delay (ms) | Gyro Bandwidth (Hz) | Gyro Delay (ms) | Fs(kHz)
// ----------+---------------+------------------+---------------------+-----------------+---------
//     0     |      260      |         0        |         256         |      0.98       |    8
//     1     |      184      |       2.0        |         188         |       1.9       |    1
//     2     |       94      |       3.0        |          98         |       2.8       |    1
//     3     |       44      |       4.9        |          42         |       4.8       |    1
//     4     |       21      |       8.5        |          20         |       8.3       |    1
//     5     |       10      |      13.8        |          10         |      13.4       |    1
//     6     |        5      |      19.0        |           5         |      18.6       |    1
//     7     |    RESERVED   |    RESERVED      |        RESERVED     |    RESERVED     |    8
  
// void MPU6050::setDLPFMode(uint8_t bandwidth)
// #define MPU6050_DLPF_BW_256         0x00
// #define MPU6050_DLPF_BW_188         0x01
// #define MPU6050_DLPF_BW_98          0x02
// #define MPU6050_DLPF_BW_42          0x03
// #define MPU6050_DLPF_BW_20          0x04
// #define MPU6050_DLPF_BW_10          0x05
// #define MPU6050_DLPF_BW_5           0x06

r0yy

Thanks for the reply,
I haven't done what you suggested. But the thing is the code behaves properly when the motor is not put under load(when the bot is left itself to balance). When testing the code with the bot kept on a box(motors arent under load), it behaves exactly it should: As shown in the video link I posted

Anyways i'll try this and revert back here. Hopefully this solves the issue! Also I've ordered another MPU6050 to cross out the possibility of a faulty sensor which might be too prone to the slightest electrical noise produced by the motors

MartinL

#3
Oct 14, 2020, 09:58 am Last Edit: Oct 14, 2020, 10:09 am by MartinL
Hi r0yy,

I only mention this, because I encountered glitches on my quadcopter motors, until I discovered that it was necessary to filter the gyroscope/accelerometer outputs. Setting the filter to 20Hz or 42Hz resolved the issue.

Another issue could be the motor PWM frequency. I recently had problems controlling DC motors using the DRV8833 dual DC motor driver that caused the microcontroller on my radio controlled tracked vehicle to randomly reset. The solution was to change the PWM frequency from 490Hz to 31.25kHz. This also had the advantage of taking the PWM out of the audible range that stopped the motors from humming, (well,... at least took it out of my hearing range).

To change analogWrite() to operate at 31.25kHz on digital pins 3, 9, 10 and 11 of my Arduino ProMini, (compatible with the Uno/Nano), I simply added these lines of code to the setup() function in my sketch:

Code: [Select]
TCCR1B &= ~_BV(CS11);                               // Increase the PWM frequency of timers 1 and 2 to 31.25kHz
TCCR2B &= ~_BV(CS22);
TCCR2B |= _BV(CS20);

After adding these lines, analogWrite() will output PWM at this higher frequency. Note that this only works on AVR Arduino boards. Note that digital pins 9 and 10 use timer 1 (TCCR1B), while digital pins 3 and 11 use timer 2 (TCCR2B).

r0yy

So I tried adding this 

mpu.setDLPFMode(MPU6050_DLPF_BW_20);

and also this

TCCR1B &= ~_BV(CS11);                               // Increase the PWM frequency of timers 1 and 2 to 31.25kHz
TCCR2B &= ~_BV(CS22);
TCCR2B |= _BV(CS20);

but the same isssue persists, I tried changing the MPU 6050 but the issue remains the same.

I ran the program without the BO Motors, basically the L298N motor driver disconnected from the Arduino, the program ran without any issues or any freezing.

As soon as I connect back the motors and motor driver back to the UNO the program runs for a couple of seconds and then freezes up or it receives garbage value from the MPU6050 causing the motor to spin at full speed.

I tried changing motors as well but it did not help. I suspect the motors are causing the Arduino to freeze up. i have tried soldering 0.1uf caps on the motors but the issue doesnt go away. At this point I am really confused and out of options.

Do you have any idea what might be going on?


MartinL

#5
Oct 15, 2020, 10:59 am Last Edit: Oct 15, 2020, 04:09 pm by MartinL
Hi r0yy,

I ran you code on my Arduino Uno with a MPU6050. Using the micros() function I measured your loop time. This is around 100Hz (10ms), even though your PID sample time is set to 200Hz (5ms).

r0yy

oh I just noticed that myself. I adjusted the sample time according to the loop time now.

I added these lines of code to check my loop time in the void loop()

prevLoopTime = 0;
loopTime = millis();

//DMP code begins
//DMP code ends

currLoopTime = loopTime - prevLoopTime;

//PID code
//Motor state update code

prevLoopTime = loopTime


I noticed a weird thing. When the code is run without the motor, currLoopTime value is 20. When motors are connected and the bot is put to test the currLoopTime value is no longer constant it starts varying a lot and in the end leading to the crash.

I suspect something is going wrong in the DMP code when the motor load is added into the system, which is causing the crash.

At this point I have crossed out the following things that could have been factors for this issue

1) Faulty MPU: I have tried 3 different sensors all yield the same result
2)noisy power to the sensor: I have added 0.1uf along with some 10uf caps in the power rail
3)incompetent power source: I am using a 4S 1550mAh Lipo that are used for racing drone so I am pretty sure voltage sag isn't a factor.



r0yy

To cross out the issue caused by DMP, I started writing a code to get the raw values from the accelerometer and gyro and use complementary filter to get a usable angle that I could use it with the PID. The bot atleast works for a good amount of time trying to balance itself and then the MCU freezes again and the motor rotates at the last value of PWM before the MCU got stuck

So i think the DMP shouldn't be the issue. Something is causing the MCU to freeze up but I am not sure what it is. I am using 20cm long jumpers to connect the motor driver pins to the arduino and 4cm long wires to connect the MPU to the UNO. Could it be possible that the PWM noise from the long wires are causing the MCU to freeze up?

MartinL

Hi r0yy,

Are you using a 5V to 3.3V level shifter between your Uno and MPU6050?

r0yy

I am using the GY521 breakout board for the MPU so no, I am directly connecting it to the arduino WITHOUT a level shifter

MartinL

#10
Oct 16, 2020, 07:33 pm Last Edit: Oct 16, 2020, 07:37 pm by MartinL
Hi r0yy,

Quote
I am using the GY521 breakout board for the MPU so no, I am directly connecting it to the arduino WITHOUT a level shifter
I know that there are a lot of tutorials out there that describe connecting the MPU6050 GY521 board directly to the SCL (A5) and SDA (A4) pins of the Uno. In most cases this works OK, however the minimum high level input voltage for I2C is marginal at 0.7 * Vcc, that's a threshold of 0.7 * 5.0V = 3.5V.

By default the Wire library activates the microcontroller's internal pull-up resistors at 5V, which will pull your SCL and SDA lines, (most likely already pulled-up with 10k resistors to 3.3V on your GY521 board) a little higher.

To ensure that voltage levels are within spec, it's possible to use a level shifter, this can be two 2N7000 N-channel MOSFET transistors, or an I2C level shifter board, (note that the image uses the BSS138 and that your GY521 board already has 10k resistors or thereabouts):



Standard GPIO on the Uno have a minimum high level input voltage at 0.6 * Vcc @5V, which sets the threshold at 3.0V. This means that GPIO will receive and accept 3.3V input levels OK.

Saying that, it could just be that vibration is causing connection problems. It might be just the jumper wires from your Arduino to the GY521?


r0yy

Saying that, it could just be that vibration is causing connection problems. It might be just the jumper wires from your Arduino to the GY521?
To solve this I have direcly soldered the GY521 breakout board to Uno but it doesnt seem to change anything

r0yy

I do have  level shifter board laying around will give it a try and see if anything changes. I have seen many forums asking to connect the GY521 board directly some recommend using pull up resistors I'll give it a try though.

r0yy

So I think I have narrowed down the issue to the Arduino. I was suspecting the Arduino to reset on motor start, so I wrote a simple code to spin the motors at 75% rpm for a brief 10s and then shut off for 3s and added Serial.print("MOTOR ON") and Serial.print("MOTOR ON") before executing the Motor ON and Motor OFF lines. I used 2 of the Arduino UNOs I had

Arduino 1: ran the code properly for a single loop and then it gave up, completely froze and the motors spun at the last pwm received.

Arduino 2: ran the code a bit longer than Arduino 1 before causing random resets and freezes.

I am powering the Arduino from my USB and obviously the Motor shield has a separate LiPo powering it. I tried powering the arduino from its DC jack with a separate 3s LiPo but things did not change.

Anyone knows what's going on here?

Go Up