Jump to content
I2Cdevlib Forums

Leaderboard

Popular Content

Showing content with the highest reputation since 08/01/2013 in all areas

  1. I have made an Arduino sketch that simplifies the task of calibrating the MPU6050's offsets. Easy steps: - Wire your MPU6050 to your Arduino. - Put the MPU6050 as horizontal as possible and leave it there, don't touch it. - Check the sketch in order to configure your MPU's I2C address (0x68 or 0x69). - Upload the sketch to your Arduino. - Open Arduino serial monitor and send any character to the Arduino. - Wait. - Write down your offsets for that particular MPU6050 and use them with library's functions "...setoffset..." in your projects. There are also a few options in the code in case you want to fine tune it. There may be bugs, or maybe it does not converge for everyone, so let me know your experience. I use it with an Arduino DUE, configured to 400KHz I2C bus speed, but I think you can use any Arduino and standard bus speed (100KHz). If people find it useful maybe Jeff can add it to the library once it is bugfree. Happy new year. UPDATE 30th January: New version 1.1 available. It fixes a bug related to variables overflowing in Arduinos other than the DUE. MPU6050_calibration_v1.1.zip
    11 points
  2. Respected Sir, I got some data from accelerometer and gyrometer using MPU 6050 with arduino. But i am not able to interpret numerical values of it. Can you help me to figure out this information? here i am sending you some of data: Accelarometer Gyrometer Ax Ay Az Gx Gy Gz -6616 13880 -1380 915 -68 -49 -6624 13924 -1496 909 -41 -136 -6680 13896 -1408 917 -46 -148 -6636 13996 -1508 913 -35 -111 -6668 13896 -1616 902 -47 -47 -6716 13944 -1496 916 -43 -40 -6616 13972 -1412 879 -57 -5 -6584 13884 -1536 918 -47 -25 -6920 14192 -1584 892 -10 -164 -7792 15016 -1524 1022 -80 -68 -6928 14244 -1484 773 -112 261 -6396 13764 -1416 939 -72 112 -6636 14020 -1596 892 -43 -154 -6520 13836 -1524 946 4 -242 -6776 13916 -1552 926 8 -333 -6916 14008 -1568 891 -64 -54 -6592 13936 -1460 866 -113 216 Thanks.
    6 points
  3. Hello, Basically what I am doing is I have the ADS1115 in single channel mode, measuring the voltage across a resistor, which indicates the current flowing through the resistor. The current comes from an AC Current Clamp which sits on my mains power board. Basically what I am trying to do is measure the current flowing, using information I have found on the openenergymonitor.org site. They have a library which basically offsets the AC wave into the positive space, then filters out the wave in code and samples the wave to get an average, which then gives you the current flowing in the AC line. They have used the standard 10 bit ADC on the Arduino, but I wanted to use the 16bit ADS1115 instead. I have set the Gain to be 4.096, and have tried 860samples/second in continuous mode, but I am seeing very weird results sometimes. Its like Channel 0 is merging into Channel, and 2 into 3, or some other random combination, and I cannot fully understand what is going on. I found a similar problem described on the Adafruit website http://forums.adafruit.com/viewtopic.php?f=19&t=54496 This is however using their own library, but one guy mentions yours and said it has a similar problem. He describes a fix, but I cannot find where to apply that. I am also using a Chipkit board, so its running at 80Mhz compared to the 16Mhz of the Arduino. I was wanting to know if you could tell me if there is any reason why doing sampleI = adc.getConversionP1GND(); quite fast, would cause problems. I was under the impression that you could call this as often as you liked, and it would just report the current figure that the ADS1115 had measured at the time, since its in continuous mode. Is that right? Here are the 2 main functions I have in my code, which is mainly copied out of the example from the openenergymonitor.org website double calcIrms(int NUMBER_OF_SAMPLES, int Channel) { double ADC_COUNTS = 24512; //portion of 15bit count used for range double SUPPLYVOLTAGE = 3064; //3.064V is the full scale I can output into sensor from clamp double ICAL = 100; //current constant = (100 / 0.050) / 20 = 100 for (int n = 0; n < NUMBER_OF_SAMPLES; n++) { lastSampleI = sampleI; if(Channel == 1) { sampleI = adc.getConversionP1GND(); } else if(Channel == 3) { sampleI = adc.getConversionP3GND();; } else { return 0; } lastFilteredI = filteredI; filteredI = 0.996 * (lastFilteredI + sampleI - lastSampleI); // Root-mean-square method current // 1) square current values sqI = filteredI * filteredI; // 2) sum sumI += sqI; } double I_RATIO = ICAL * ((SUPPLYVOLTAGE / 1000.0) / (ADC_COUNTS)); double Irms = I_RATIO * sqrt(sumI / NUMBER_OF_SAMPLES); //Reset accumulators sumI = 0; return Irms; } void loop() { Irms1 = calcIrms(100, 1); // Calculate Irms only Irms3 = calcIrms(100, 3); // Calculate Irms only apparentPower1 = supplyVoltage * Irms1; //extract Apparent Power into variable apparentPower3 = supplyVoltage * Irms3; //extract Apparent Power into variable } I am displaying this to a TFT LCD and sometimes the figures just drop to 0 and stay there, and now and then the numbers blink to show something, and then go away again. Any help you could provide would be appreciative, esp if you see that I am doing something stupid. Regards WanaGo
    4 points
  4. Hi @vrutangs, The accelerometer and gyroscope measurements are explained in the MPU-6050 datasheet in the GYRO_CONFIG and ACCEL_CONFIG register descriptions (sections 4.4 and 4.5 on pages 14 and 15). The scale of each depends on the sensitivity settings chosen, which can be one of +/- 2, 4, 8, or 16g for the accelerometer and one of +/- 250, 500, 1000, or 2000 deg/sec for the gyroscope. The accelerometer produces data in units of acceleration (distance over time2), and the gyroscope produces data in units of rotational velocity (rotation distance over time). The output scale for any setting is [-32768, +32767] for each of the six axes. The default setting in the I2Cdevlib class is +/- 2g for the accel and +/- 250 deg/sec for the gyro. If the device is perfectly level and not moving, then: X/Y accel axes should read 0 Z accel axis should read 1g, which is +16384 at a sensitivity of 2g X/Y/Z gyro axes should read 0 In reality, the accel axes won't read exactly 0 since it is difficult to be perfectly level and there is some noise/error, and the gyros will also not read exactly 0 for the same reason (noise/error).
    4 points
  5. Hi, I am currently doing a project in which I need to capture the acceleration of a pivoted rotating wooden beam. From the acceleration, I need to determine the velocity. I am using Jeff's teapot sketch with the mpu6050 and I have managed to also include the acceleration in the teapotPacket to print acceleration in processing. I know that velocity is the first integral of acceleration. Such integral can be expressed as: v = u + AT, where v is the current velocity, u is the velocity before, A is the acceleration and T is a time interval. This is my code for the velocities in the three directions with sampling time of 1ms: vX = uX + (AX)*0.001; //vX = current velocity in the X direction, uX = velocity in the previous iteration, AX = acceleration in the x direc uX = vX; //setting the current velocity as the previous velocity vY = uY + (AY)*0.001; uY = vY; vZ = uZ + (AZ)*0.001; uZ = vZ; If I move the sensor say in the x direction, acceleration in the x direction increases and when I stop the sensor, acceleration becomes negative and converges to zero, as expected. The velocity seems to be calculated and printed right when increasing from zero to a particular value. Now my problem is, that when I stop moving the sensor, velocity does not go back to zero when the sensor is stationary, but it decreases by a small amount only (say it stops decreasing at 0.5m/s. This gets worse when the sensor is moved faster. It seems like the acceleration is read more than the deceleration (decreasing acceleration) and therefore, less negative values for acceleration are captured. Can anybody help me? Thanks, Hatt
    3 points
  6. Hello, Is it possible to pool data from DMP when needed instead of it writing to FIFO constantly? Similar like you can write 0x3B and read 14 registers to get raw data... Thanks, Dario
    3 points
  7. I just recently found out how to accurately read the Accelerometer Data off the MPU6050 You may get an output like this: MPU-6050 Read accel, temp and gyro, error = 0 accel x,y,z: 1856, 308, 15604 temperature: 30.435 degrees Celsius gyro x,y,z : -33, -252, -235, and you see its not obvious on how to understand this data. What I found out is that is this: If your scale is +-2G Divide by 2048 If your scale is +-4G Divide by 4096 If your scale is +-8G Divide by 8192 If your scale is +-16G Divide by 16384 Thank you- Jeremy Hall
    3 points
  8. Hi, I am using MPU6050 with your written code in DMP mode on Arduino due and it's working fine stand alone.. But I have to integrate some other things into my code like (Due timer library to generate software interrupt every second, external interrupt on pin 52 to count pulses ). when i tried to integrate them in one code i have FIFO Overflow problem. even though i tried to run it at as low as 20hz by changing the registers value in the "3dmath.h" file. can you please help me out with this problem i am facing. my project is kind of stuck at this point. Thank you. #include <DueTimer.h> #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif MPU6050 mpu; //#define OUTPUT_READABLE_WORLDACCEL #define OUTPUT_READABLE_REALACCEL #define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) #define LED_PIN1 12 bool blinkState = false; bool blinkState1 = false; // MPU control/status vars bool dmpReady = false; // set true if DMP init was successful uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) uint16_t packetSize; // expected DMP packet size (default is 42 bytes) uint16_t fifoCount; // count of all bytes currently in FIFO uint8_t fifoBuffer[64]; // FIFO storage buffer // orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel sensor measurements VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements VectorFloat gravity; // [x, y, z] gravity vector float euler[3]; // [psi, theta, phi] Euler angle container float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector double vel_data; double vel; double Dummy = 0 ; double t_s = 0; double S[2] = {0,0}; double Q[2] = {0.05,0.05}; double R[2] = {0.5, 0.01}; double Y[2] = {0,0}; double X[2] ={0,0}; double P[2] = {0.5,0.5}; double K[2] = {0, 0}; uint32_t timer = 0; uint32_t dt = 0; int16_t sample,sped=0; int16_t ax, ay, az; int16_t gx, gy, gz; int16_t sensorValue; char val; int count; bool flag; // ================================================================ // === INTERRUPT DETECTION ROUTINE === // ================================================================ volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void dmpDataReady() { mpuInterrupt = true; } // ================================================================ // === INITIAL SETUP === // ================================================================ void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); Wire1.begin(); //TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif Serial1.begin(115200); //115200 or 19200 while (!Serial1); // wait for Leonardo enumeration, others continue immediately Serial1.println(F("Initializing I2C devices...")); mpu.initialize(); // verify connection Serial1.println(F("Testing device connections...")); Serial1.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); // wait for ready // Serial1.println(F("\nSend any character to begin DMP programming and demo: ")); // while (Serial1.available() && Serial1.read()); // empty buffer // while (!Serial1.available()); // wait for data // while (Serial1.available() && Serial1.read()); // empty buffer again // load and configure the DMP Serial1.println(F("Initializing DMP...")); devStatus = mpu.dmpInitialize(); // supply your own gyro offsets here, scaled for min sensitivity mpu.setXGyroOffset(-1); //220 inc. will inc. mpu.setYGyroOffset(-24); //76 mpu.setZGyroOffset(51); //-85 mpu.setZAccelOffset(1788); // increasing number will increase 16384 // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready Serial1.println(F("Enabling DMP...")); mpu.setDMPEnabled(true); // enable Arduino interrupt detection Serial1.println(F("Enabling interrupt detection (Arduino Due external interrupt 2)...")); attachInterrupt(2, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); // set our DMP Ready flag so the main loop() function knows it's okay to use it Serial1.println(F("DMP ready! Waiting for first interrupt...")); dmpReady = true; // get expected DMP packet size for later comparison packetSize = mpu.dmpGetFIFOPacketSize(); } else { // ERROR! // 1 = initial memory load failed // 2 = DMP configuration updates failed // (if it's going to break, usually the code will be 1) Serial1.print(F("DMP Initialization failed (code ")); Serial1.print(devStatus); Serial1.println(F(")")); } // configure LED for output pinMode(LED_PIN, OUTPUT); delay(5000); attachInterrupt(52, rpm_fun, FALLING); Timer.getAvailable().attachInterrupt(firstHandler).start(1000000); // from DueTimer library delay(50); } void firstHandler(){ // Software interrupt every one second. Serial1.println("int"); flag = true; } void rpm_fun() // Hardware interrupt to count external pulses. { count = count + 1; } // ================================================================ // === MAIN PROGRAM LOOP === // ================================================================ void loop() { // if programming failed, don't try to do anything if (!dmpReady) return; // wait for MPU interrupt or extra packet(s) available while (!mpuInterrupt && fifoCount < packetSize) { // other program behavior stuff here // . // . // . // if you are really paranoid you can frequently test in between other // stuff to see if mpuInterrupt is true, and if so, "break;" from the // while() loop to immediately process the MPU data // . // . // . } // reset interrupt flag and get INT_STATUS byte mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); // get current FIFO count fifoCount = mpu.getFIFOCount(); // check for overflow (this should never happen unless our code is too inefficient) if ((mpuIntStatus & 0x10) || fifoCount == 1024) { // reset so we can continue cleanly mpu.resetFIFO(); Serial1.println(F("FIFO overflow!")); // otherwise, check for DMP data ready interrupt (this should happen frequently) } else if (mpuIntStatus & 0x02) { // wait for correct available data length, should be a VERY short wait while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); // read a packet from FIFO mpu.getFIFOBytes(fifoBuffer, packetSize); // track FIFO count here in case there is > 1 packet available // (this lets us immediately read more without waiting for an interrupt) fifoCount -= packetSize; #ifdef OUTPUT_READABLE_REALACCEL // display real acceleration, adjusted to remove gravity // -----Get data from MPU-6050----- mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetAccel(&aa, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); sample = -(aaReal.x); //Dummy = (abs(sample)>80) ? ((double)sample/16384)*9.81 : 0; Dummy = (double)sample/16384 * 9.81; t_s = (((double)micros() - timer)/1000000); // -----Get data from Arduino UNO----- Wire1.requestFrom(2, 1); // request 1 byte from slave device #2 while(Wire1.available()) // slave may send less than requested { sped = Wire1.read(); // receive a byte as character vel_data = ( 0.85 *((double)(sped)* 0.216)) + (0.15 * X[1]); // Serial1.println(sped); // print the character } //--------Prediction------- X[0] = X[0]; // Velocity X[1] = X[1]; // Acceleration P[0] = Q[0]; P[1] = t_s * Q[1]; //-------Kalman Gain-------- S[0] = P[0] + R[0]; S[1] = P[1] + R[1]; K[0] = P[0]/S[0]; K[1] = P[1]/S[1]; //--------Update------------- //vel = vel + t_s * Dummy; Y[0] = vel_data - X[0]; Y[1] = Dummy - X[1]; // Y[1] = Dummy - X[1]; X[0] = X[0] + (K[0]*Y[0]); X[1] = X[1] + (K[1]*Y[1]); P[0] = P[0] - (K[0]*P[0]); P[1] = P[1] - (K[1]*P[1]); timer = micros(); #endif // blink LED to indicate activity blinkState = !blinkState; digitalWrite(LED_PIN, blinkState); } }
    3 points
  9. Hello, I'm using I2Cdevlib to read out the fused DMP data from an MPU-6050 breakout board, and I'm absolutely amazed at the amount of precision I get from such a low-cost sensor! I've got one problem though: I attached the sensor to a mobile robot, which sometimes moves in large circles, i.e. the gyroscope will register the same small turn velocity over a long period of time. During these periods, after ~8 seconds the yaw reading of the sensor stabilizes at some point and I don't get rotation updates anymore. From what I gathered from other posts, I assume that the DMP tries to cancel out gyro drift by subtracting any constant gyro reading that it gets from the next readings. I guess what happens is that the DMP thinks my slowly moving robot is actually the gyroscope drifting and tries to compensate. (I can actually see the yaw moving in the opposite direction for a short while when I stop the robot mid-turn.) So my question is: Is there some way I can turn off gyro drift compensation in the DMP? I can take care of slow drifts myself by measuring the gyro drift when I'm completely sure that the robot isn't moving. It would be a pity if I couldn't use this great sensor and library because I can't disable this feature. Thanks a lot for your responses, Simon
    3 points
  10. Sorry If this question is already answered or is way too noob.... I am a novice programmer and I dont really know how to get Degrees/second mpu.getRotation(&gx, &gy, &gz); gyroRoll = gx/131.0; gyroPitch = gy/131.0; gyroYaw = gz/131.0; Is this correct ? Does my gyroRoll, gyroPitch, gyroYaw give values in degrees/second? I want the values to use in my quadcopter code... Also I didnt change any default sensitivity in my MPU6050. Actually I am using Hextronik Nanowii V01 flight controller which is Arduino Leonardo. Also I got another doubt, Is ± 250 °/s more sensitive to changes and give wider range of raw values and ± 2000 °/s is less sensitive to changes and gives narrow range of raw values??? Sorry if these questions are way too noob, I just cant confirm anywhere the above assumptions that I have made.
    3 points
  11. Hello, Thanks to Jeff for his work ! I couldn't even try using DMP without his code... The MPU6050_raw works well with my sparkfun mpu6050 connected to an arduino uno. The MPU6050_DMP6 has an irregular behavior. When launching, the serial monitor says "DMP ready! Waiting for first interrupt...", and indeed it waits a pretty long time... The interrupt pin is connected to arduino pin 2 I've also tried to connect the vio to arduino 3.3v The point is that I've no interrupt signal when connecting an oscilloscope on INT pin of the mpu... is there a hardware issue ? or should I initialize something in the mpu ? Thanks for your response damien
    3 points
  12. bmsrao

    mpu-6050 dmp access

    hello jeff rowberg, I B.M.S.RAO.I am an engineering final year student. I am doing a project which is having mpu-6050, and using ATMEGA32L (8-bit) micro controller. My task is to display the YAW rate, PITCH rate, ROLL rate on the hyper terminal, and I succeeded to get the raw data, But in the datasheet, there was no data about how to access the DMP register, I tried a lot to get these details, but I didnt get the adequate information regarding dmp access and no relevant data on internet also ,meanwhile I saw your code(C++ language) in github website to get YAW rate ,PITCH rate ,ROLL rate and you said ,you have used reverse engineering method to get that data. Sir its my kind request, please help me how to get the above YAW rate, PITCH rate, ROLL rate. Sir I cant afford to use arduino based, spark fun based hardware kits and their soft wares. I have stand-alone ATMEGA32L (8-bit) micro controller, avr studio version 6. Regarding this; I had sent a mail (how to get dmp data in mpu-6050) to invensense, where they replied me that to use Embedded_MotionDriver_5.1.But I have nil knowledge regarding the Embedded_MotionDriver_5.1. Sir I humbly request you to please help me. Is it possible to get the code that you have mentioned in the git hub website in C language or in any algorithm form (like flowchart to access dmp registers)?
    3 points
  13. Why are we dividing by 8 and 4 before setting the offsets? Where is that documented? Or is just a step to prevent wide changes in the offset and help the optimization converge?
    3 points
  14. Hi I'm new to Arduino and I'm trying to use a 6DOF IMU (the MPU-6050) along with the i2cdevlib. I've been able to set the libraries and to execute a sketch in order to calculate the offset of the IMU starting from the raw data. Now I'm trying to execute the example code that i found on the github of the i2cdevlibhttps://github.com/jrowberg/i2cdevlib/blob/master/Arduino/MPU6050/Examples/MPU6050_DMP6/MPU6050_DMP6.ino setting the output in the YPR modeCode: #define OUTPUT_READABLE_YAWPITCHROLL with and without my offset parameters. In both sketches I found the same issue. The data on the serial shift from the initial position for 5-8 second showing an increment of several degrees (depends on the cases but usually there are 12-25 degrees) of the YPR angles without moving the IMU. The same thing happen with the Euler anglesCode: #define OUTPUT_READABLE_EULER I've tried also to execute the quaternion output modeCode: #define OUTPUT_READABLE_QUATERNION which i don't know how to read (I'm just started learning about this) but the value I read on the serial seems to stay "stable". I might solve this with a delay from the turn on which allow me to see of how much degrees the IMU "virtually moved" and then subtract that value to future reading (such as another offset) but i find this not usefull since I need the IMU to have the right angles on the turn on. Thanks for reading, hope someone could help me
    2 points
  15. Hi everyone, After searching in forums i found out that people have different values for the "setXGyroOffset/setYGyroOffset/setZGyroOffset/setZAccelOffset" functions. But i can't understand how i can find what values i need to use. Can somebody explain me how do i choose the parameters for those functions? Thanks in advance.
    2 points
  16. Hi friends, I have managed to read from two mpu6050 on DMP. Both sensors are fitted on a piece of board and are perfectly levelled. My problem is that when I tilt the sensors such that I increase/decrease Roll, the Yaw is changed, even when the sensors are not rotated on the z axis. Is it normal that rolling affects yawing? Furthermore, the change in Yaw for both sensors is not the same, and there will be a difference in yaw of 8 deg between the two sensors for a 45deg rolling. Thanks in advance, Hatt
    2 points
  17. Hey everyone! Thought I'd share my version of an auto-offset calibration sketch; it converges all offsets in about 20s or so. Just upload and watch the serial (at 38400bps)! A note on how it works/converges: - the code takes an initial guess for each offset (supplied at the top of the sketch), takes a certain number of readings from the MPU-6050 (the # of readings it takes is defined by countMax), and averages those number of readings. If that average is less than the value errorCheck, it assumes that axis has converged - if the average isn't less than errorCheck, it will subtract a certain amount from the initial guess - if the errorCheck you set is too small, or the initial guess is smaller than what the solution is, it wont converge - in this case either choose a larger value for errorCheck or a larger initial guess I've given some initial guesses / settings which should help you get to where you need to be; just watch the serial - it'll tell you what the average reading from the MPU-6050 was for each guess, you'll want that average to be as close to 0 as possible for each axis. Enjoy! MPU6050_calibration.zip
    2 points
  18. I was under the impression that the default range for the MPU-6050 accelerometer was +/-2g, but after doing some datalogging I'm beginning to think that is only the case for the raw values (i.e. using MPU6050_raw.ino) and not true when using the DMP (i.e. using DMP6050_DMP6.ino). The values I obtained are half of what I believe they should be, leading me to believe that with DMP the default range is +/-4g. I found a line in MPU6050_6Axis_MotionApps20.h that only confuses me more: // get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g) If the sensitivity is 2g, doesn't 1g = 16,384? Or am I reading the datasheet incorrectly? At this point I'm pretty confused and hopefully somebody can clear it all up for me...
    2 points
  19. Sadtab

    ODROID Platform

    Hi everybody, I was wondering if any development is runing for odroid SBC ? If not Iwanted to kindly request that http://www.hardkernel.com/main/products/prdt_info.php?g_code=G143452239825
    2 points
  20. Hi everybody... I've been working on a project recently and i need to measure the roll and pitch angles of a moving platform, but the problem is that the value of these angles starts from 0 then reaches 90, then starts to decrease again to reach 0 (positive or negative 90 degrees of course) ... what i need to do is to have this value in the range of zero to 180 (positive or negative) not from zero to 90 as it is now ... do anyone have any idea??
    2 points
  21. Hello! I'm trying to log the acceleration measured by a MPU6050 on a GY-521 breakout board on a microSD card using a microSD shield made by Sparkfun. Because the MPU6050_DMP6 sketch from the MPU6050 library of Jeff Rowberg (also using his I2Cdev lib) and the dataLogger sketch from the SDfat library both worked very good (when runnning alone) i thought i could combine them to achieve my goal. I deleted the (for my use) unnecessary code and instead of printing the acceleration data to the serial monitor i print it to the logfile. But this is not working so great. The sketch stops working completely random. Sometimes it runs for a couple of minutes, sometimes only for a few seconds. When it freezes i have to reset the arduino and it runs again for some time. I just can't figure out what the problem is. Here is what i already tried: 1) check the connections SD shield is just put on top of the arduino MPU -> Arduino VCC -> 5V GND -> GND SCL -> Analog 5 SDA -> Analog 4 INT -> Digital 2 solder points look good 2) check memory usage don't remember the exact value but it was stable and there was enough free memory 3) a LOT of different approaches how to handle the data all with pretty much the same results, i will spare you the details because mostly it was "try and error" Here is the basic sketch i described: ///////////////////////////////////////////////////////////////////////////////// #define BUTTON_PIN 4 ///////////////////////////////////////////////////////////////////////////////// //////////////Includes, Constants and Objects for datalogging//////////////////// #include <SdFat.h> // SD chip select pin. Be sure to disable any other SPI devices such as Enet. const uint8_t chipSelect = 8; //#define LOG_ACC // Log file base name. Must be six characters or less. #define FILE_BASE_NAME "DATA" // Error messages stored in flash. #define error(msg) error_P(PSTR(msg)) // File system object. SdFat sd; // Log file. SdFile file; //Variable for collumn separation ************* char tab = ';'; ///////////////////////////////////////////////////////////////////////////////// //////////////////////Includes, Constants and Objects for MPU//////////////////// #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" //#define OUTPUT_READABLE_REALACCEL // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation // is used in I2Cdev.h #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif // class default I2C address is 0x68 // specific I2C addresses may be passed as a parameter here // AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board) // AD0 high = 0x69 MPU6050 mpu; //MPU6050 mpu(0x69); // <-- use for AD0 high //#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6) bool blinkState = false; // MPU control/status vars bool dmpReady = false; // set true if DMP init was successful uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) uint16_t packetSize; // expected DMP packet size (default is 42 bytes) uint16_t fifoCount; // count of all bytes currently in FIFO uint8_t fifoBuffer[64]; // FIFO storage buffer // orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel sensor measurements VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements VectorFloat gravity; // [x, y, z] gravity vector float euler[3]; // [psi, theta, phi] Euler angle container float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector // packet structure for InvenSense teapot demo uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' }; ///////////////////////////////////////////////////////////////////////////////// //////////////////////////////User functions///////////////////////////////////// //------------------------------------------------------------------------------ // Write data header. void writeHeader() { file.print(F("accel_X")); file.print(tab); file.print(F("accel_Y")); file.print(tab); file.print(F("accel_Z")); file.println(); } //------------------------------------------------------------------------------ // error messages void error_P(const char* msg) { sd.errorHalt_P(msg); } //------------------------------------------------------------------------------ // Interrupt detection volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void dmpDataReady() { mpuInterrupt = true; } //------------------------------------------------------------------------------ // setup function void setup() { const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1; char fileName[13] = FILE_BASE_NAME "00.CSV"; Serial.begin(115200); //while (!Serial) {} // wait for Leonardo //delay(1000); pinMode(BUTTON_PIN, INPUT_PULLUP); Serial.println(F("Press Button to start")); while(digitalRead(BUTTON_PIN)) {} //wait for button // Initialize the SD card at SPI_HALF_SPEED to avoid bus errors with // breadboards. use SPI_FULL_SPEED for better performance. if (!sd.begin(chipSelect, SPI_FULL_SPEED)) sd.initErrorHalt(); // Find an unused file name. if (BASE_NAME_SIZE > 6) { error("FILE_BASE_NAME too long"); } while (sd.exists(fileName)) { if (fileName[BASE_NAME_SIZE + 1] != '9') { fileName[BASE_NAME_SIZE + 1]++; } else if (fileName[BASE_NAME_SIZE] != '9') { fileName[BASE_NAME_SIZE + 1] = '0'; fileName[BASE_NAME_SIZE]++; } else { error("Can't create file name"); } } if (!file.open(fileName, O_CREAT | O_WRITE | O_EXCL)) error("file.open"); do { delay(10); } while (Serial.read() >= 0); Serial.print(F("Logging to: ")); Serial.println(fileName); // Write data header. writeHeader(); // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // initialize device Serial.println(F("Initializing I2C devices...")); mpu.initialize(); // verify connection Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); // load and configure the DMP Serial.println(F("Initializing DMP...")); devStatus = mpu.dmpInitialize(); // supply your own gyro offsets here, scaled for min sensitivity mpu.setXGyroOffset(99); mpu.setYGyroOffset(-35); mpu.setZGyroOffset(67); mpu.setZAccelOffset(1106); // 1688 factory default for my test chip // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready Serial.println(F("Enabling DMP...")); mpu.setDMPEnabled(true); // enable Arduino interrupt detection Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = mpu.getIntStatus(); // set our DMP Ready flag so the main loop() function knows it's okay to use it Serial.println(F("DMP ready! Waiting for first interrupt...")); dmpReady = true; // get expected DMP packet size for later comparison packetSize = mpu.dmpGetFIFOPacketSize(); } else { // ERROR! // 1 = initial memory load failed // 2 = DMP configuration updates failed // (if it's going to break, usually the code will be 1) Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); } // configure LED for output pinMode(13, OUTPUT); } // ================================================================ // === MAIN PROGRAM LOOP === // ================================================================ void loop() { // if programming failed, don't try to do anything if (!dmpReady) return; // wait for MPU interrupt while (!mpuInterrupt && fifoCount < packetSize) { // other program behavior stuff here // . // . // . // if you are really paranoid you can frequently test in between other // stuff to see if mpuInterrupt is true, and if so, "break;" from the // while() loop to immediately process the MPU data // . // . // . } // reset interrupt flag and get INT_STATUS byte mpuInterrupt = false; mpuIntStatus = mpu.getIntStatus(); // get current FIFO count fifoCount = mpu.getFIFOCount(); // check for overflow (this should never happen unless our code is too inefficient) if ((mpuIntStatus & 0x10) || fifoCount == 1024) { // reset so we can continue cleanly mpu.resetFIFO(); Serial.println(F("FIFO overflow!")); // otherwise, check for DMP data ready interrupt (this should happen frequently) } else if (mpuIntStatus & 0x02) { // wait for correct available data length, should be a VERY short wait while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); // read a packet from FIFO mpu.getFIFOBytes(fifoBuffer, packetSize); // track FIFO count here in case there is > 1 packet available // (this lets us immediately read more without waiting for an interrupt) fifoCount -= packetSize; // get real acceleration, adjusted to remove gravity mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetAccel(&aa, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); file.print(aaReal.x); file.write(tab);//*************** file.print(aaReal.y); file.write(tab);//*************** file.println(aaReal.z); // Force data to SD and update the directory entry to avoid data loss. if (!file.sync() || file.getWriteError()) Serial.println(F("write error")); if (!digitalRead(BUTTON_PIN)) { // Close file and stop. file.close(); Serial.println(F("Done")); while(1) {} } } } If you have any ideas how to solve this issue, any help will be greatly appreciated. wambo
    2 points
  22. nicnac

    GY-86

    Hey! I've got a GY-86 with MPU6050, a Barometer and the HMC5883L. On the Arduino (UNO) I get the MPU to work. But I can't figure out how to get the magnetometer data! I2C scanner tells me: Scanning... I2C device found at address 0x68 ! I2C device found at address 0x77 ! done and 0x68 is definately the mpu6050. And since I know, that it can be a master again, I suspect, that the other would be barometer and the HMC is on the slave of the MPU. Am I right with that? Can anybody tell me how I can proceed? Check my assumption or just get the mag data? Any help much appreciated!!
    2 points
  23. Hi to all! I am using the MPU-6050 sensor, among others, as a part of my graduation project. I am trying to use the MPU6050 together with the BMP180 (and some other simpler sensors), and with some intuition I could manage to make them work together by just taking the raw data from the MPU6050. All my attempts to use the needed libraries to acquire the yaw/pitch/roll data format and take into account the DMP and the fifo buffer the sensor itself has while using other sensors in the same program have failed, maybe because I don't have so much experience with programming. I attach my code, because maybe you could help me to make it work. The MPU6050 example works, as far as I don't mix it with other sensors. I use different functions as part of the main code, like these ones: But all I get from the ypr variables are zeros. Any help would be really appreciated. Kind regards, María.
    2 points
  24. i imported i2cdev.h and mpu6050.h library. But it doesnt work. Help me please. Error code; MPU6050.cpp:1997:6: error: prototype for 'bool MPU6050::getMotionStatus()' does not match any in class 'MPU6050' bool MPU6050::getMotionStatus() { ^ In file included from MPU6050.cpp:37:0: C:\Users\ziya.ozcelik\Documents\Arduino\libraries\MPU6050/MPU6050.h:611:17: error: candidate is: uint8_t MPU6050::getMotionStatus() uint8_t getMotionStatus();
    2 points
  25. Can anyone please help me in interfacing mpu6050 with 8051? I dont have the library. neither i have any idea about how to use it. please help me.
    2 points
  26. Hi.. The default is seeting for accelero is +/-2G and for gyro is +/-250deg/sec. So what are the changes one should make in mpu6050.cpp and mpu6050.h to change default setting? thanks in advanced.
    2 points
  27. HI.. I am using MPU 6050 for accelero and gyro data. The default setting in the I2Cdevlib class is +/- 2g for the accel and +/- 250 deg/sec for the gyro. So that means i can detect maximum of 250 deg/s and it will saturate at 250 (in the plot) if my angular velocity is more than 250 deg/s. So how can we change to the +/- 2000 deg/s? Also, is it possible to change only gyro scale and retaining the accelerometer range which is +/- 2g (inbuilt)? Any help is highly appreciated. thanks.
    2 points
  28. Hi all. I'm using an MPU6050 to obtain orientation information for a quadcopter, however when the function that is attached to the interrupt pin is ran (to obtain the orientation data from the FIFO buffer), the sketch crashes. Sometimes, the console prints the first few characters of "Getting Sensor Data!", which is called in the routine. Am I doing anything seriously wrong? Main Sketch: Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); attachInterrupt(0, AP_getSensorData, RISING); // Actually pin 2-(5?) AP_Sensors.cpp: // Library header #include "Sensors_.h" #include "I2Cdev.h" #include "MPU6050_6Axis_MotionApps20.h" #include "Serial_.h" #include <SFE_BMP180.h> #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif /************************************** * LED DEFINITIONS *************************************/ #define LED_GREEN 9 #define LED_YELLOW 10 #define LED_YELLOW2 11 #define LED_YELLOW3 12 #define LED_RED 13 // Code MPU6050 onboardIMU; extern bool systemError; int ultrasonicAlt; // MPU control/status vars bool dmpReady = false; // set true if DMP init was successful uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) uint16_t packetSize; // expected DMP packet size (default is 42 bytes) uint16_t fifoCount; // count of all bytes currently in FIFO uint8_t fifoBuffer[64]; // FIFO storage buffer // orientation/motion vars Quaternion q; // [w, x, y, z] quaternion container VectorInt16 aa; // [x, y, z] accel sensor measurements VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements VectorFloat gravity; // [x, y, z] gravity vector float euler[3]; // [psi, theta, phi] Euler angle container float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector byte error, address; int nDevices; // ================================================================ // === INTERRUPT DETECTION ROUTINE === // ================================================================ volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high void dmpDataReady() { mpuInterrupt = true; } bool AP_initSensors() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif /************************************** * Scan for I2C Devices *************************************/ Serial.println("Scanning I2C Bus..."); nDevices = 0; for (address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); Serial.println(" !"); nDevices++; } else if (error == 4) { Serial.print("Unknow error at address 0x"); if (address < 16) Serial.print("0"); Serial.println(address, HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("Completed I2C Bus Scan...\n"); Serial.println("Initalising I2C Devices..."); onboardIMU.setSleepEnabled(false); onboardIMU.initialize(); // Try to connect to IMU Devices... Serial.println("Connecting to I2C Devices..."); if (onboardIMU.testConnection()) { Serial.println("IMU Connected!:"); // load and configure the DMP Serial.println(F("Initializing DMP...")); devStatus = onboardIMU.dmpInitialize(); // supply your own gyro offsets here, scaled for min sensitivity onboardIMU.setXGyroOffset(220); onboardIMU.setYGyroOffset(76); onboardIMU.setZGyroOffset(-85); onboardIMU.setZAccelOffset(1788); // 1688 factory default for my test chip // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready Serial.println(F("Enabling DMP...")); onboardIMU.setDMPEnabled(true); // enable Arduino interrupt detection // Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); // attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = onboardIMU.getIntStatus(); // set our DMP Ready flag so the main loop() function knows it's okay to use it Serial.println(F("DMP ready! Waiting for first interrupt...")); dmpReady = true; // get expected DMP packet size for later comparison packetSize = onboardIMU.dmpGetFIFOPacketSize(); } else { // ERROR! // 1 = initial memory load failed // 2 = DMP configuration updates failed // (if it's going to break, usually the code will be 1) Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); } } else { Serial.println("Unable to find any I2C Devices..."); } Serial.println("Initialising Barometric Sensor..."); AP_initBarometricSensor(); } void AP_getSensorData() { Serial.println("Getting Sensor Data!"); // reset interrupt flag and get INT_STATUS byte mpuInterrupt = false; mpuIntStatus = onboardIMU.getIntStatus(); // get current FIFO count fifoCount = onboardIMU.getFIFOCount(); // check for overflow (this should never happen unless our code is too inefficient) if ((mpuIntStatus & 0x10) || fifoCount == 1024) { // reset so we can continue cleanly onboardIMU.resetFIFO(); Serial.println(F("FIFO overflow!")); // otherwise, check for DMP data ready interrupt (this should happen frequently) } else if (mpuIntStatus & 0x02) { // wait for correct available data length, should be a VERY short wait while (fifoCount < packetSize) fifoCount = onboardIMU.getFIFOCount(); // read a packet from FIFO onboardIMU.getFIFOBytes(fifoBuffer, packetSize); // track FIFO count here in case there is > 1 packet available // (this lets us immediately read more without waiting for an interrupt) fifoCount -= packetSize; onboardIMU.dmpGetQuaternion(&q, fifoBuffer); onboardIMU.dmpGetGravity(&gravity, &q); onboardIMU.dmpGetYawPitchRoll(ypr, &q, &gravity); } }
    2 points
  29. Hello People, I have got a Problem with the MPU6050_DMP6 Code as it sometimes hangs when its running. It seems to stop randomly after some time and it makes no difference if i have the Arduino powered from USB, USB and Running Serial Monitor or from 9V Battery. I did minor changes to the code: Added Raw Values and Datalogging on a Micro SD Card with a Catalex Micro SD Adapter for Arduino and removed parts like TeaPot Demo and so one because i dont need them for my application. But i dont think this problem occus due to my changes because i think i saw this freezing also with the Basic MPU6050_DMP6 Code. I tried the Datalogging with SD-Library and SDFatLibrary but the Problem occured with both. The FIFO/DMP Rate is set to 25 Hz with 0x02, 0x16, 0x02, 0x00, 0x07 // D_0_22 inv_set_fifo_rate in the MPU6050_6Axis_MotionApps20 Library .h File because i had Fifo Overflow when runnig with 100Hz. Here is my sketch code: I added a Led on Pin 8 with indicates aktivity so i see the led stopping blinking once in a while when i run the code. If i have the serial monitor then it just stoppes writing new lines. Can somebody give me a hint why this happens and how it could be fixed? Or if somebody got a code for Datalogging Yaw Pitch and Roll Values + Raw Values Accelerometer and Gyroskop i would also appreciate very much! I also tried 2 differnet SDCards (one Class 10) and ther was no differnce... I really annoying because i want to log data and when it stops randomly and mostly after not more than 2 to 3 minutes the application is unreliable and useless.... Greets Julian
    2 points
  30. Hi, I know that there are some eamples showing how to put magnetometer data into DMP. For example this one: http://www.i2cdevlib.com/forums/topic/111-arduino-example-sketch-to-read-magnetometer-while-dmp-is-on/ but it does not make any sensor fusion. I couldn't find any library which would make magnetometer fusion inside DMP. Does such library exist? Maybe code in this file MPU6050_9Axis_MotionApps41.h make DMP+magnetometer fusion? I couldn't find any tips in the code and right now I am not able to test it. So the question is: does such library exist or the only way to do this is to make own fiters (for example complementary filter)? Maybe there is some MPU9150 library that can be used with MPU6050+magnetometer?
    2 points
  31. ibrahims

    MSP430 + MPU 9150

    Hi im trying to access the magnetometers data. I am using Energia. THe following code is being used. The x,y,z values are all nearly the same. If anyone can please post a fix with code this would be helpful.
    2 points
  32. Can someone explain the raw DMP packet information to me. Here's what i know so far. Every packet is 42 bytes. 0:3 QW 4:7 QX 8:11 QY 12:15 QZ 16:19 GX 20:23 GY 24:27 GZ 28:31 AX 32:35 AY 36:39 AZ 40:41 unknown Am I correct in assuming that all the quaternions are double precision floating point numbers? And the gyro and accel are 32 bit int? Are the gyro and accel numbers what the DMP read off of the register when it calculated the quaternions?
    2 points
  33. Thanks this worked well first time. I made a slight modification to your code. In the loop() where it prints out the offsets I changed it to the following: Serial.println("Your offsets:\t"); Serial.print("mpu.setXGyroOffset("); Serial.print(gx_offset); Serial.println(");"); Serial.print("mpu.setYGyroOffset("); Serial.print(gy_offset); Serial.println(");"); Serial.print("mpu.setZGyroOffset("); Serial.print(gz_offset); Serial.println(");"); Serial.print("mpu.setXAccelOffset("); Serial.print(ax_offset); Serial.println(");"); Serial.print("mpu.setYAccelOffset("); Serial.print(ay_offset); Serial.println(");"); Serial.print("mpu.setZAccelOffset("); Serial.print(az_offset); Serial.println(");"); The output then becomes the following: Sensor readings with offsets: 4 2 16388 0 0 -2 Your offsets: mpu.setXGyroOffset(37); mpu.setYGyroOffset(-44); mpu.setZGyroOffset(26); mpu.setXAccelOffset(-1282); mpu.setYAccelOffset(-727); mpu.setZAccelOffset(1732); That way I can just copy/paste/format the code and I am done. Just a thought.
    2 points
  34. Well, if it works for you... then I guess you can read it using (mpu.dmpGetXXXXXXXX) every time you want, but be sure to read it at a faster frecuency than DMP is running, or fifo will overflow. Anyway, I haven't checked how does this (mpu.dmpGetXXXXXXXX) function work, so I am only speculating. Besides, this long wait you mention has never happened to me. Are you sure that INT pin is connected where it should be connected?
    2 points
  35. Great program you've got working here, should save me a lot of trouble! The one issue that I have is that the I2C address of the MPU6050 object is incorrectly set to 0x69 by default, this is NOT the default address of the IMU (i'm pretty sure it should be 0x68). It took me the longest time to figure out why my sensor wasn't connecting Thanks! violinuxer
    2 points
  36. Hello, I see the MPL3115A2 in the list of supported devices, but it doesn't seem to be present in the code. Even the github link on http://www.i2cdevlib.com/devices/mpl3115a2#source points to code that doesn't exist. I just got one of these so if it's really supported, that would be great. Thanks, Marc
    2 points
  37. It would be valuable to the community to have the library updated to MotionApps 5.1 (or 6.x?) based on what InvenSense has most recently published, but this is not a small endeavor. I am tied up with my main day job and a few other side projects at the moment, so it will either have to wait or someone else will have to do most of the development for now.
    1 point
  38. eyeshield21v2

    Sim5320

    Ahh one thing I would like to ask something about this device_id and reg_addr: or device addr and how to get it on MPU6050? Thanks in advance...
    1 point
  39. Hi, Question about Accelerometer Scale Sensitivity Factor wrong values reading I have read accel values 8192 at +/- 2g but its should read 1g of 16384 at sensitivity of 2g From Datasheet https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf P.29 AFS_SEL | Full Scale Range | LSB Sensitivity--------+------------------+----------------0 | +/- 2g | 16384 LSB/g1 | +/- 4g | 8192 LSB/g2 | +/- 8g | 4096 LSB/g3 | +/- 16g | 2048 LSB/g Is somethings wrong? Thanks in advance.
    1 point
  40. The output of gyro goes to a max of 32,768. If its fine what is the sensitivity factor I must be using? setFullScaleGyroRange is also set to 250 dps. Not even sure if the output should be in this range And the Z axis gyro values are erratic. Could someone help me with that too! !!
    1 point
  41. Was this ever taken forward? We're interested in this platform too.
    1 point
  42. HI Jeff... I'm Mochammad Habib Bachtiar as student of trunojoyo university in Indonesia. In this semester I have project about motion capture use a MPU6050 & Arduino Uno. but my focus is gyroscope with horizontal motion at upper arm, lower arm, and hand. so each segmen one sensor. I want ask you about that. how to modified some source code at arduino until this raw value become to angular rate. Please explain source code base from x, y & z axis.... Thank's Jeff ....
    1 point
  43. Hello, I just purchased a GY-521 breakout of the MPU-6050 and I hooked it up to my Arduino UNO. I uploaded MPU5060_DMP6 sketch and adjusted the calibration values to get all three axis close to zero when at resting position. The yaw axis works as I would expect, I turn the chip, the number changes and stays until I turn it back to the resting position, the problem however is with the pitch and roll values, when I turn the chip in these directions the number changes but then drifts back to 0 as soon as I stop moving the chip. Am I missing something? Thanks, TheHelpfulOne
    1 point
  44. Hello.. I have the small query. The code for reading accelerometer and gyro data from MPU 6050 is written by Jeff is as follow: // I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class // 10/7/2011 by Jeff Rowberg <jeff@rowberg.net> // Updates should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib // // Changelog: // 2013-05-08 - added multiple output formats // - added seamless Fastwire support // 2011-10-07 - initial release /* ============================================ I2Cdev device library code is placed under the MIT license Copyright © 2011 Jeff Rowberg Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================== */ // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files // for both classes must be in the include path of your project #include "I2Cdev.h" #include "MPU6050.h" // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation // is used in I2Cdev.h #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE #include "Wire.h" #endif // class default I2C address is 0x68 // specific I2C addresses may be passed as a parameter here // AD0 low = 0x68 (default for InvenSense evaluation board) // AD0 high = 0x69 MPU6050 accelgyro; //MPU6050 accelgyro(0x69); // <-- use for AD0 high int16_t ax, ay, az; int16_t gx, gy, gz; // uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated // list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read, // not so easy to parse, and slow(er) over UART. #define OUTPUT_READABLE_ACCELGYRO // uncomment "OUTPUT_BINARY_ACCELGYRO" to send all 6 axes of data as 16-bit // binary, one right after the other. This is very fast (as fast as possible // without compression or data loss), and easy to parse, but impossible to read // for a human. //#define OUTPUT_BINARY_ACCELGYRO #define LED_PIN 13 bool blinkState = false; void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // initialize serial communication // (38400 chosen because it works as well at 8MHz as it does at 16MHz, but // it's really up to you depending on your project) Serial.begin(38400); // initialize device //Serial.println("Initializing I2C devices..."); accelgyro.initialize(); // verify connection //Serial.println("Testing device connections..."); // Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); // use the code below to change accel/gyro offset values /* Serial.println("Updating internal sensor offsets..."); // -76 -2359 1688 0 0 0 Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76 Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359 Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688 Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0 Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0 Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0 Serial.print("\n"); accelgyro.setXGyroOffset(220); accelgyro.setYGyroOffset(76); accelgyro.setZGyroOffset(-85); Serial.print(accelgyro.getXAccelOffset()); Serial.print("\t"); // -76 Serial.print(accelgyro.getYAccelOffset()); Serial.print("\t"); // -2359 Serial.print(accelgyro.getZAccelOffset()); Serial.print("\t"); // 1688 Serial.print(accelgyro.getXGyroOffset()); Serial.print("\t"); // 0 Serial.print(accelgyro.getYGyroOffset()); Serial.print("\t"); // 0 Serial.print(accelgyro.getZGyroOffset()); Serial.print("\t"); // 0 Serial.print("\n"); */ // configure Arduino LED for pinMode(LED_PIN, OUTPUT); } void loop() { // read raw accel/gyro measurements from device accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); // these methods (and a few others) are also available //accelgyro.getAcceleration(&ax, &ay, &az); //accelgyro.getRotation(&gx, &gy, &gz); #ifdef OUTPUT_READABLE_ACCELGYRO // display tab-separated accel/gyro x/y/z values // Serial.print("a/g:\t"); int start=millis();Serial.print(start);Serial.print("\t"); Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.print(az); Serial.print("\t"); Serial.print(gx); Serial.print("\t"); Serial.print(gy); Serial.print("\t"); Serial.println(gz); #endif //#ifdef OUTPUT_BINARY_ACCELGYRO // Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF)); //Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF)); //Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF)); //Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF)); //Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF)); //Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF)); //#endif // blink LED to indicate activity blinkState = !blinkState; digitalWrite(LED_PIN, blinkState); } I just delete the thing which i don't know and made a small code as follow: #include "I2Cdev.h" #include "MPU6050.h" #include "Wire.h" MPU6050 accelgyro; int16_t ax, ay, az; int16_t gx, gy, gz; #define OUTPUT_READABLE_ACCELGYRO #define LED_PIN 13 bool blinkState = false; void setup() { Wire.begin(); Serial.begin(38400); accelgyro.initialize(); pinMode(LED_PIN, OUTPUT); } void loop() { accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); int start=millis();Serial.print(start);Serial.print("\t"); Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.print(az); Serial.print("\t"); Serial.print(gx); Serial.print("\t"); Serial.print(gy); Serial.print("\t"); Serial.println(gz); blinkState = !blinkState; digitalWrite(LED_PIN, blinkState); } Now i am not sure about the importance of the if and elseif statement (for an example) : #ifdef OUTPUT_BINARY_ACCELGYRO Serial.write((uint8_t)(ax >> 8)); Serial.write((uint8_t)(ax & 0xFF)); Serial.write((uint8_t)(ay >> 8)); Serial.write((uint8_t)(ay & 0xFF)); Serial.write((uint8_t)(az >> 8)); Serial.write((uint8_t)(az & 0xFF)); Serial.write((uint8_t)(gx >> 8)); Serial.write((uint8_t)(gx & 0xFF)); Serial.write((uint8_t)(gy >> 8)); Serial.write((uint8_t)(gy & 0xFF)); Serial.write((uint8_t)(gz >> 8)); Serial.write((uint8_t)(gz & 0xFF)); #endif Can anyone help me to understand the importance of the if and elseif condition that has been used in the Jeff's code? Thanks.
    1 point
  45. Vinesh Saini, You are commiting a BIG mistake! You CANNOT connect directly the MPU6050 to the Arduino. If you read the datasheet you will see that the highest Vcc is 3.46v!!!! (http://www.invensense.com/mems/gyro/documents/PS-MPU-6000A-00v3.4.pdf). So you will need a level shifter to connect the MPU6050 to the arduino and 3.3V suplied by the arduino. Finally you should have a look on the Arduino website http://playground.arduino.cc/Main/MPU-6050. Regards,
    1 point
  46. Hi everyone, I am using in the last months the really nice library provided by Jeff which is A M A Z I N G. Thank you man I am using it in my quadcopter and works really nice (thank you again). But there is a problem: I dont like the idea of using sensor fusion cause it is too complicated to setup with arduino and also uses too much proccessing power from my arduino. That's why I am using the DMP angle values from the MPU6050. The problem is this, after days trying to find a solution: I would like someway to obtain angles from MPU6050 DMP calling a function "get_angles()" not using interrupt pin or the buffer. The reason is that I make many other computation in arduino and frequently the buffer of MPU6050 overflows and my quad get out of control and fall. I already reduced the frequency that the buffer gets populated to the minimum but I still sometimes get overflows. That's why I would like to know if there is some way I could retrieve angles from MPU6050 using a function exactly like "mpu.getMotion6" but with angles, not with giro and accel data. Thank you so much, you helped me a lot with this great and very well documented library.
    1 point
  47. According to the 6050 register map, the FIFO is 8-bit wide buffer. How, then, is it read? The 6050 does not have any 8-bit port! In my application, I need raw sensor data for use in a micro controller that doesn't have an I2C bus...
    1 point
  48. Hi luisrodenas, thank you for your attention! I must say that I'm using an Arduino Leonardo and I'm running the sketch for calibration according to your instructions on the first post, in a plain horizontal table and completely as possible still. I'm using the Jeff's library as it is distributed with none modifications as your sketch, the only thing I changed was the I2C address to be 0x68 to work with my breakout board for MPU-6050. I ran your sketch with the default parameters: int buffersize=1000; //Amount of readings used to average, make it higher to get more precision but sketch will be slower (default:1000) int acel_deadzone=8; //Acelerometer error allowed, make it lower to get more precision, but sketch may not converge (default:8) int giro_deadzone=1; //Giro error allowed, make it lower to get more precision, but sketch may not converge (default:1) I ran it for about 10 minutes and the output I get through the serial port was recorded in the file attached. It seems to me that this condition, never occurs, so I believe that's why I can't get a sucessfull calibration from your sketch. Anyway I appreciate your help and your share of this sketch. Keep up with the good work! MPU6050_calibration_sketch_output.txt
    1 point
  49. Hi Marc, The REALACCEL numbers are calculated with respect to the orientation of the sensor itself, so that if it is flat and you move it straight up, the "Z" accel will change, but if you flip it up on one side and move it in the new relative "up" direction (along the sensor's Z axis), it will still register acceleration on the Z axis. Essentially, it is sensor-oriented acceleration which removes the effects of gravity and any non-flat/level orientation. The WORLDACCEL numbers are calculated to ignore orientation. Moving it straight up while flat will look the same as the REALACCEL numbers, but if you then flip it upside-down and do the exact same movement ("up" with respect to you), you'll get exactly the same numbers as before, even though the sensor itself is upside-down. This would be easier to explain in person with a solid object for reference, but hopefully this is enough.
    1 point
  50. Hi Ben, The numbers you are seeing appear to be all multiples of 4. This is extremely unlikely in a real-world situation, and makes me think that the way you are reading registers and/or converting data for storage in your variables has a problem with (1) register read orders, (2) byte orders, or (3) bit orders. Or, possibly, you are shifting values somehow after reading them. The various ACCEL_*OUT_H/L registers each contain 8 bits of the 16-bit raw sensor value. The _H register is the high byte (MSB), and the _L register is the low byte (LSB). If you read them independently and combine them, then you should store them into a signed 16-bit integer container something like this: int16_t accel_x = (ACCEL_XOUT_H << 8) + ACCEL_XOUT_L; Is this what you are doing, or something very close anyway?
    1 point
×
×
  • Create New...