Introduction: Realtime MPU-6050/A0 Data Logging With Arduino and Android
I have been interested in using the Arduino for machine learning. As a first step, I want to build a realtime (or pretty close to it) data display and logger with an Android device. I want to capture accelerometer data from the MPU-6050 so I designed the build to use the HC-05 at 115200 baud. With this configuration 4 channels of data can be transmitted at 250 samples per second.
The build does have a few steps:
- Build the shield or breadboard
- Program the Arduino
- Load the Android app from Google Play or branch the GitHub and compile it yourself
- Connect the MPU-6050 to something interesting that vibrates (I used an R/C car)
- Use the Android device to connect to the Arduino
- Plot the data, save if interested
- Import into Python (or other platform) for further use
Let's get started!
Step 1: Build the Shield/breadboard
This is the wiring diagram for the Arduino, HC-05, and the MPU-6050. In addition to the MPU-6050 I have the analog input A0 wired to a light sensor to show that the ADC is working. Any 0-5 volt signal could be brought into the A0 ADC. These are the components I used for the build:
- Arduino Uno
- HC-05 (The HC-06 should work too, but my build was with the HC-05)
- Sparkfun photoresistor
- 10kOhm resistor (brown-black-orange)
Most HC-05 Bluetooth modules default to 9600 baud. For the data to transmit successfully you will need to reprogram it for a 115200 baud rate. There's a good HC-05/HC-06 AT Command Instructable that explains how to do it.
Step 2: Program the Arduino
I used the Arduino IDE release 1.6.7 to program the Arduino. The code can be downloaded from the links in this step or from the GitHub repo. I have included three versions: Firmware125.ino is the 125 hertz version, Firmware250.ino is the 250 hertz version, and Firmware500.ino is the 500 hertz version. To get the Arduino to cycle at 500 hertz, the A0 ADC is not collected.
The firmware includes a clock out on Pin 9 that I used to check the timing. The trace shows the cycle time is 4 ms (equivalent to 1/250 hertz). I've found that if there is serial link problems the timing will not be uniform.
The Arduino code does use bit masking to add a channel number to each packet because samples sometimes drop over Bluetooth. I use the three most significant bits to store a channel number. For signed integers the most significant bit (MSB) is reserved for the sign. Since I want to use the MSB for my address, rather than the sign of the integer, I have to convert all of the signed accelerometer values to unsigned integers. I do this by adding 32768 to each value (the MPU accelerometer ADC counts are +32768 to -32768) and cast as unsigned integers:
The channel number are the same for each accelerometer and the A0 port so that a dropped packet can be detected if the channel numbers are out of order. For the packets coming from the Bluetooth on the Arduino, the binary pattern is (the << and >> signs are bit-wise shifting):
(xacc 3 address bits = 0x00, 13bit unsigned) (yacc 3 address bits = 0x01, 13bit unsigned) (zacc 3 address bits = 0x02, 13bit unsigned) (3 address bits = 0x03, iadc13bit unsigned) (xacc 3 address bits = 0x00, 13bit unsigned) (yacc 3 address bits = 0x01, 13bit unsigned) (zacc 3 address bits = 0x02, 13bit unsigned) (3 address bits = 0x03, iadc13bit unsigned) (xacc 3 address bits = 0x00, 13bit unsigned) (yacc 3 address bits = 0x01, 13bit unsigned) (zacc 3 address bits = 0x02, 13bit unsigned) (3 address bits = 0x03, iadc13bit unsigned) ...
If are using something other than the Accel Plot Android app to read the Bluetooth data, here are the steps to extract the address (I'm using the variable names from the Accel Plot Bluetooth.java file from the GitHub repo):
- Read in the 16 unsigned int
- Extract the high byte and save it to btHigh.
- Extract the low byte and save it to btLow.
- Retrieve the address from btHigh using: (btHigh >> 5 ) & 0x07. This statement shifts btHigh 5 bits to the right moving the three address bits to the lowest three registers. The & sign is a logical AND that forces bits 4 and higher to be zero and the last three bits to match the address bits. The result of this statement is your address.
You don't have to worry about the address extraction if you are using Accel Plot.
Step 3: Load the Android App From Google Play or Branch the GitHub
You have a couple choices for loading the Android app on your device. If you want to avoid coding, you can search for "Accel Plot" and the app should come up in the Google Play store. Follow the store instructions for installation.
My desire with this Instructable is really to encourage others to build projects so I have also published the code in a GitHub repo. You should be able to branch this, build it, and modify it as you see fit. I published the code under the MIT License so have fun!
Step 4: Connect to the Arduino to Something Interesting (I Used an R/C Car)
I want to eventually use the device for road surface detection so I thought a small remote controlled (R/C) car would be appropriate. I think it helps in the next step if the accels can be on something that moves or vibrates.
Step 5: Use the Android Device to Connect to the Arduino.
If you haven't already done so, you will need to first pair the HC-05 to your Android device. I believe that on most devices you can do this by going to settings. The default pin for most HC-05 devices will be 1234 or 1111.
Open the AccelPlot app on the Android device. When the app opens, and before you connect to the HC-05, you can change sampling rate (this is set in the Arduino code), accelerometer scales (also set in the Arduino code), and the number of samples to be saved.
Once these settings are made click on the "Connect" button. It should bring up the Bluetooth devices and your device should be listed. Select it and once the code establishes the connection you will see a "Connected" toast pop up.
Use the back arrow button to return to Accel Plot. Tap the "Start Stream" button to display data from the HC-05 device. You should also buttons available to save the data or play the frequency modulated content through the audio jack.
Step 6: Acquire and Plot the Data
The "Start Stream" button should be enabled. Tap it to begin streaming data to the screen.
The "Save Data" button will also be enabled, tap it to store the data.
Accel Plot also includes an option to output a modulated signal on the audio channels. The 2 channels in the Accel Plot app refer to the left and right channels of the audio out jack on the Android device. This is useful if you want to bring the MPU-6050 data into a separate data logging system, like a National Instruments.
The video shows an example of the system collecting data on an R/C car.
Step 7: Import Into Python (or Other Platform) for Further Use
The files are saved to the Android device. The files will be stored under the "AccelPlot" directory for Android API 18 and older. The code places the .dat files in the "\Tablet\Documents\AccelPlot" folder for API 19 (KitKat 4.4) and higher. I have had trouble with some Android devices showing the files when connected via USB. In some cases I have had to reboot the Android device to get them to show up. Not sure why this is, but there should be four files, one for each channel. They can be copied over to a local directory for additional work.
I used Anaconda/Python 2.7 to open the files and display the data. The "ExploratoryAnalysis.ipynb" file has the IPython Notebook file that will open all the data files and plot the sample data. Sample files are include in the GitHub repo. The data is saved as big-endian 4 byte floats ('>f') so any analysis program should be able to open them.
I have also include a simpler file called "ReadDataFiles.ipynb" that shows how to read in a single file by name.