SOOOO! This is my first post and I am creating to help others. I have figured out a few things that I wasn't aware of and I'm not sure if I'm the only one who has figured this out.
This is gonna be a long post, so if you don't wanna read about how I figured this out, scroll on down to the TLDR break
TL;DR Arduino starts Wire.h for I2C communication automatically when Serial.begin() is called OR (and the is a BIG OR) it is CURRENTLY PLUGGED IN to a computer via USB.
I've played with Arduino's for a while but never had a nitty gritty use for them. My plan was to eventually turn my home into a smart home but due to relationship issues and getting divorced, that project will have to wait. However, in my pursuit of therapeutic hobbies, I decided to get into model airplanes in the meantime. I have always loved flying and planes. I currently also paraglide when weather permits and I'm not at work
I have found plenty of hardware that accomplishes gyro stabilization and flight controllers for model airplanes, but almost always at a steep price. I am self taught most of my mathematics and physics and I thought, this would be the perfect project. I had some nanos and uno's that I've used for other projects such as haptic feedback for my Logitech racing pedals and to get started with sensors and integration of the home environment with server scripting and google homes... And my thought was, this would be the perfect pass time right now is to just forget about what is going on emotionally in my mind and enjoy myself for a bit each day.
Queue home built flight computer. I say computer since my plans will go far beyond stabilization... such as autopilots, autonomy, control mixing yada yada yada. I have a servo controller and the gy-521, 6-DOF sensor for acceleration and gyrometers. The servo driver isn't important because it isn't what made me realize why the arduino was doing what caused me to wanna tear my hair out for the last 24 hours.
I'm not an engineer, but I try to follow steps when I build my projects. I'm pretty procedural in what I do. I rarely as for help because I troubleshoot pretty methodically. I set up my code when something doesn't work right to give me feedback in the serial monitor or the blinking of the built in LED to help me. And when I'm pretty sure I've found where the problem is, I can look it up and sure enough, someone has had the same problem.
Except this one problem, lots of people have had, and even finding out what it was that was happening, there isn't a whole lot, if any documentation on why this happened. Seems to me the perfect oppertunity to share with the world.
--------------------TLDR-------------------
What was the problem? I was having trouble communicating with the MPU6050 when I was disabling the Serial Monitor as when it was powered on battery, I'd have no way of checking the outputs. And the debugging I did via the built in wouldn't give me any clue as to why it wasn't working because Wire.h was handling the exceptions without hanging the Arduino.
Turns out, when an Arduino is plugged in to a computer via USB, OR, the Serial.begin() is used, the Arduino somehow automatically calls Wire.begin() TOO. And if you forget to call Wire.begin(), the moment that you try to run off battery and power cycle, not just reset the Arduino, it just stops working.
I searched and searched:
arduino hangs when powered by battery
MPU6050 only working when plugged in to computer
MPU6050 doesn't work on battery
etc etc etc
I found a bunch of great articles about pull-up resistors being needed, decoupling, using too long of wires and the capacitance was too great or cross talk was occuring. Only problems with these were that my wires were 2 inches at most on this prototype. No chance for significant capacitance or cross talk. The GY-521 package that has the MPU6050 already had pull-up resistors. Some people were saying its your soldering connections. Others were saying that they got around this with sending an SCL pulse until the SDA pin would pull up for 9 cycles.
NONE OF IT WORKED!
I went through the code dozens of times. And it wasn't until I copied my code and begain using different I2C methods of communicating before I finally ran into the fact that I didn't ever call Wire.begin() in my setup function to start communicating with the MPU6050.
So, here are the exact symptoms I had when I was having these issues so if you have them, check to see if you used Wire.begin()! And as a side note, while I'm wrapping this up, even with this quirk of the arduino, just save yourself some time and add it anyways even if your arduino will always be connected to the computer.
Symptoms:
- An I2C device worked worked when it was connected to the computer. NO HICCUPS NO QUALMS
- You can unplug it if it has its own power and it will still work
- Resetting it using the button, the I2C device will still function
- When you remove power and the arduino is no longer connected via USB, and then add power, the I2C device no longer communicates with the Arduino
- It doesn't matter whether the SCL or SDA are changing. Seems to me that the Arduino is still trying to communicate over it. Other devices such as my Servo Driver still worked fine.
- Lastly, the Arduino doesn't hang. It seems the Wire library can cope with the error
CHECK YOUR CODE BEFORE YOU WRECK YOURSELF