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!
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
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:
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).
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.
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).
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
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.
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?
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?
MartinL:
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
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.
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.
At this point I am able to get the I2C working at a stable rate by adding 10k resistors on SDA SCL as pull ups
The bot is working stable as intended with a single lipo battery powering the whole thing. However when I mount the electronics into the bot adruino starts freezing again sometimes it can't read the sensor any more.
The bot works best with the following setup motor controller and arduino away from the motors as shown in the picture
with the other two setups the bot freezes within 5-10 seconds on powering on
I am using fiber glass copper clad board as the base of the bot with the copper intact could that be an issue?
can I use it as a ground shielding(i dont know how it works but was planning to solder a ground wire to the copper clad)
It might be worth adding extra support to your MPU6050 breakout board. It's just that motor vibration can disturb the gyroscope and acceleromter, especially when the board's only physical support is a female pin header.
On my quadcopter I used two, 8mm, nylon hex threaded spacers and nuts, both with M3 threads, plus two small squares of double sided foam tape at the base of each of them, to provide cushioning from vibration:
The quadcopter also required the MPU6050's DLPF to be set to 20Hz. Note that the two 2N7000 N-Channel MOSFETs provide the I2C 5V to 3.3V level shifting.
I built a circuit all from scratch on a perf board,
added spacers to support the MPU 6050
added power filtering with 470uf and 0.01uf caps
added pull up 10k resistors on the SDA SCL lines
shortened all the wires as much as possible
when through numerous arduinos and motor drivers to cross out the problems due to a faulty board
Changed motors to a different kind of 12v motors
after doing all this the problem still exists. THE ARDUINO STILL FREEZES ON MOTOR START!
At this point I want to give up on this project(out of frustration) but I still want to see this through the end(The bot working). I have seen videos and tutorials with people getting away with shabby wiring, no filtering, cheap motors or parts I really dunno what is wrong. ANY HELP WOULD BE REALLY APPRECIATED.
At this point I want to give up on this project(out of frustration) but I still want to see this through the end(The bot working). I have seen videos and tutorials with people getting away with shabby wiring, no filtering, cheap motors or parts
I know that it's really frustrating. It doesn't seem like it now, but it's actually all a learning process. Those who have it easy, don't necessarily learn how to do it right. You've gone through most of the obvious steps that would normally solve the problem.
It took me a while until I discovered that I needed spacers on my first flight controller's MPU6050 breakout board, to stop the motor vibrations affecting the sensor.
Do you have some form of circuit diagram or schematic? It could just be a wiring issue?
Also, I noticed that the L298N has a jumper that should be removed if you're using more than +12V for the supply, in order to disable its on-board +5V regulator.
You mentioned that you were using 3S and 4s Lipo batteries. 3S batteries will supply more +12V when fully charged and 4S more than that. I'm wondering in that case what you're doing wih the +12V jumper and if you're using the on-board +5V regulator?