issues with Uno R3 using FreeIMU v0.4, MPU6050, and Processing - Page 1
Forum section: electronics / general

author: rperez88
author_rank: Newbie
timestamp: July 04, 2014, 08:11:17 pm
content: Hello all. I recently bought a MPU-6050 to use with my Uno R3.Heres the specific board I'm using:https://www.sparkfun.com/products/11028and i have it connected like so:VDD - Arduino 3.3vGND - Arduino GNDINT - Arduino digital pin 2FSYNC - leave unconnectedSCL - Arduino SCL (dedicated pin or Analog 5)SDA - Arduino SDA (dedicated pin or Analog 4)VIO - Arduino 3.3vCLK - leave unconnectedASCL - leave unconnectedASDA - leave unconnectedI followed this beginner guide:http://playground.arduino.cc/Main/MPU-6050gotit working with little effort.After that I tried using this guide which includes using the IDE "Processing" to get a visual representation in 3d space:http://www.varesano.net/blog/fabio/initial-tests-freeimu-v04-and-mpu6050This is where I'm running into issues. In his video as he turns the arduino with the mpu6050, the rectangle on screen moves accordingly.When I'm using my arduino and the MPU6050, the "processing" rectangle on screen is just free floating, me moving the actual chip with around has no effect on it.Heres the code I'm using on my arduino, its just the FreeIMU_quaternion example sketch:#include "CommunicationUtils.h"#include "FreeIMU.h"#include <Wire.h>#include <SPI.h>float q;// Set the FreeIMU objectFreeIMU my3IMU = FreeIMU();void setup() {Serial.begin(115200);Wire.begin();delay(5);my3IMU.init();delay(5);}void loop() {my3IMU.getQ(q);serialPrintFloatArr(q, 4);Serial.println("");delay(20);}And Heres what I'm using in processing:/**Visualize a cube which will assumes the orientation describedin a quaternion coming from the serial port.INSTRUCTIONS:This program has to be run when you have the FreeIMU_quaternionprogram running on your Arduino and the Arduino connected to your PC.Remember to set the serialPort variable below to point to the name theArduino serial port has in your system. You can get the port using theArduino IDE from Tools->Serial Port: the selected entry is what you haveto use as serialPort variable.Copyright (C) 2011 Fabio Varesano -http://www.varesano.net/This program is free software: you can redistribute it and/or modifyit under the terms of the version 3 GNU General Public License aspublished by the Free Software Foundation.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program. If not, see <http://www.gnu.org/licenses/>.*/import processing.serial.*;Serial myPort; // Create object from Serial classfinal String serialPort = "/dev/tty.usbmodem1411"; // replace this with your serial port. On windows you will need something like "COM1".float [] q = new float ;float [] hq = null;float [] Euler = new float ; // psi, theta, phiint lf = 10; // 10 is '\n' in ASCIIbyte[] inBuffer = new byte; // this is the number of chars on each line from the Arduino (including /r/n)PFont font;final int VIEW_SIZE_X = 1024, VIEW_SIZE_Y = 768;void setup(){size(VIEW_SIZE_X, VIEW_SIZE_Y, P3D);myPort = new Serial(this, serialPort, 115200);// The font must be located in the sketch's "data" directory to load successfullyfont = loadFont("CourierNew36.vlw");/*float [] axis = new float;axis = 0.0;axis = 0.0;axis = 1.0;float angle = PI/2.0;hq = quatAxisAngle(axis, angle);hq = new float;hq = 0.0;hq = 0.0;hq = 0.0;hq = 1.0;*/delay(100);myPort.clear();myPort.write("1");}float decodeFloat(String inString) {byte [] inData = new byte;if(inString.length() =={inData = (byte) unhex(inString.substring(0, 2));inData = (byte) unhex(inString.substring(2, 4));inData = (byte) unhex(inString.substring(4, 6));inData = (byte) unhex(inString.substring(6,);}int intbits = (inData << 24) | ((inData & 0xff) << 16) | ((inData & 0xff) <<| (inData & 0xff);return Float.intBitsToFloat(intbits);}void readQ() {if(myPort.available() >= 18) {String inputString = myPort.readStringUntil('\n');//print(inputString);if (inputString != null && inputString.length() > 0) {String [] inputStringArr = split(inputString, ",");if(inputStringArr.length >= 5) { // q1,q2,q3,q4,\r\n so we have 5 elementsq = decodeFloat(inputStringArr);q = decodeFloat(inputStringArr);q = decodeFloat(inputStringArr);q = decodeFloat(inputStringArr);}}}}void buildBoxShape() {//box(60, 10, 40);noStroke();beginShape(QUADS);//Z+ (to the drawing area)fill(#00ff00);vertex(-30, -5, 20);vertex(30, -5, 20);vertex(30, 5, 20);vertex(-30, 5, 20);//Z-fill(#0000ff);vertex(-30, -5, -20);vertex(30, -5, -20);vertex(30, 5, -20);vertex(-30, 5, -20);//X-fill(#ff0000);vertex(-30, -5, -20);vertex(-30, -5, 20);vertex(-30, 5, 20);vertex(-30, 5, -20);//X+fill(#ffff00);vertex(30, -5, -20);vertex(30, -5, 20);vertex(30, 5, 20);vertex(30, 5, -20);//Y-fill(#ff00ff);vertex(-30, -5, -20);vertex(30, -5, -20);vertex(30, -5, 20);vertex(-30, -5, 20);//Y+fill(#00ffff);vertex(-30, 5, -20);vertex(30, 5, -20);vertex(30, 5, 20);vertex(-30, 5, 20);endShape();}void drawCube() {pushMatrix();translate(VIEW_SIZE_X/2, VIEW_SIZE_Y/2 + 50, 0);scale(5,5,5);// a demonstration of the following is at//http://www.varesano.net/blog/fabio/ahrs-sensor-fusion-orientation-filter-3d-graphical-rotating-cuberotateZ(-Euler);rotateX(-Euler);rotateY(-Euler);buildBoxShape();popMatrix();}void draw() {background(#000000);fill(#ffffff);readQ();if(hq != null) { // use home quaternionquaternionToEuler(quatProd(hq, q), Euler);text("Disable home position by pressing \"n\"", 20, VIEW_SIZE_Y - 30);}else {quaternionToEuler(q, Euler);text("Point FreeIMU's X axis to your monitor then press \"h\"", 20, VIEW_SIZE_Y - 30);}textFont(font, 20);textAlign(LEFT, TOP);text("Q:\n" + q + "\n" + q + "\n" + q + "\n" + q, 20, 20);text("Euler Angles:\nYaw (psi) : " + degrees(Euler) + "\nPitch (theta): " + degrees(Euler) + "\nRoll (phi) : " + degrees(Euler), 200, 20);drawCube();}void keyPressed() {if(key == 'h') {println("pressed h");// set hq the home quaternion as the quatnion conjugate coming from the sensor fusionhq = quatConjugate(q);}else if(key == 'n') {println("pressed n");hq = null;}}// See Sebastian O.H. Madwick report// "An efficient orientation filter for inertial and intertial/magnetic sensor arrays" Chapter 2 Quaternion representationvoid quaternionToEuler(float [] q, float [] euler) {euler = atan2(2 * q * q - 2 * q * q, 2 * q*q + 2 * q * q - 1); // psieuler = -asin(2 * q * q + 2 * q * q); // thetaeuler = atan2(2 * q * q - 2 * q * q, 2 * q * q + 2 * q * q - 1); // phi}float [] quatProd(float [] a, float [] b) {float [] q = new float;q = a * b - a * b - a * b - a * b;q = a * b + a * b + a * b - a * b;q = a * b - a * b + a * b + a * b;q = a * b + a * b - a * b + a * b;return q;}// returns a quaternion from an axis angle representationfloat [] quatAxisAngle(float [] axis, float angle) {float [] q = new float;float halfAngle = angle / 2.0;float sinHalfAngle = sin(halfAngle);q = cos(halfAngle);q = -axis * sinHalfAngle;q = -axis * sinHalfAngle;q = -axis * sinHalfAngle;return q;}// return the quaternion conjugate of quatfloat [] quatConjugate(float [] quat) {float [] conj = new float;conj = quat;conj = -quat;conj = -quat;conj = -quat;return conj;}I'm using the FreeIMU example Quaternion uploaded to my Uno, installed all libraries in the FreeIMU, and the processing sketch he provides on his blog. Everything compiles fine on my end, but when I get to the visual representation in processing my rectangle is free floating, and fabios reacts with his arduino/mpu6050's position.Any insight would be greatly appreciated

author: FreddyVictor
author_rank: Regular Contributor
timestamp: July 04, 2014, 10:41:39 pm
content: ok, you did change the line in the Processing sketch for the serial port ?you need to find the correct port on your pc and change the following line:final String serialPort = "/dev/tty.usbmodem1411"; // replace this with your serial port. On windows you will need something like "COM1".incidentally, the SF IMU board is seriously overpriced BTW (considering that it's strictly 3.3V) cheaper alternatives:eg

author: rperez88
author_rank: Newbie
timestamp: July 04, 2014, 11:08:28 pm
content: Yes i did change the port already, I'm on a MAC, thats why my serial port is described like that.Thanks for replying! Any other ideas?

author: dannyf
author_rank: Super Contributor
timestamp: July 04, 2014, 11:12:00 pm
content: I would put the device on a windows machine to see if it works - you probably want to rule out that it is not something with your mac; and I would definitely put a logic analyzer on the tx/rx pins to see what's going on.Also, with all the floating point math, have you thought about using the onboard dmp?

author: rperez88
author_rank: Newbie
timestamp: July 04, 2014, 11:24:09 pm
content: I haven't really tried anything besides the examples show in the video. Both codes are examples from FreeIMU, his works, mine doesn't.I will try it on a windows machine though.Are you saying just use the logic analyzer to make sure TX and RX are working? When I use the MPU and this:http://playground.arduino.cc/Main/MPU-6050I get raw readouts like I'm supposed to, but they also don't change when I move the chip around (but they are reading the chip!).

author: dannyf
author_rank: Super Contributor
timestamp: July 04, 2014, 11:44:20 pm
content: Code:my3IMU.getQ(q);serialPrintFloatArr(q, 4);I went through the code quickly but you probably want to make sure that q is a pointer (likely?) or my3IMU.get() wouldn't be return a value (unless it is done via global variables). Similarly, make sure that serialPrintFloatArr() takes a pointer - from its name it seems that it does.QuoteIf so, maybe 1) they aren't reading the chip right and 2) the chip is defective.

author: andyturk
author_rank: Frequent Contributor
timestamp: July 05, 2014, 03:19:04 am
content: Quote from: dannyf on July 04, 2014, 11:12:00 pmUsing the DMP on those chips is a pain-and-a-half. The "firmware" for the DMP needs to be downloaded onto the sensor's processor first and last I checked, all of Invensense's example code is for MSP430.I've written low-level drivers for the 9-axis variants (MPU-9150 and -9250), but since we had a Cortex M4F at our disposal, we just did the IMU implementation on the mcu. It wasn't that computationally expensive.At any rate, if the OP's quaternions aren't changing at all, he should verify that the accel/gyro values are successfully making from the sensor chip to the mcu. No movement at all sounds like zeros are being read. The "opposite" problem is when the sensor is stationary and the 3D model spins wildly. That usually indicates a problem with initial conditions of the IMU and/or the filter constants it's configured with.

author: FreddyVictor
author_rank: Regular Contributor
timestamp: July 05, 2014, 06:01:56 am
content: Quote from: rperez88 on July 04, 2014, 11:08:28 pmOKI still think the code should work - probably because the serial data isn't being sent/received - although I havin't checked it myselfI think you already did this, but when you run the arduino sketch + view the serial port data in the IDE, you are getting data which is changing (maybe change the delay to 200)If this is ok, add a debug line into the Processing sketch in the readQ() function to see whats being received<edit>un-comment line://print(inputString);