Author Topic: MPU6050 coding  (Read 19924 times)

tolson

  • Global Moderator
  • *****
  • Posts: 812
  • Karma: +19/-0
    • View Profile
    • Thomas Olson Consulting
Re: MPU6050 coding
« Reply #15 on: June 02, 2014, 02:10:26 PM »
Interesting. I don't have a modern iMAC to try it on. I'm stuck with Tiger on Dual Core. Can't upgrade and recent versions of Arduino seems to requie a newer JAVA than is available for my old machine. Anyways, can you try this...

Disconnect the DTR <-> Reset connection between the RFduino and USB so that when you connect to the USB/Serial port it doesn't reset the RFduino.

Then before running the Processing script bring up the Arduino serial monitor and verify data streaming correctly at 115200. Then kill the Arduino serial monitor and then start the Processing sketch. It won't need to send R because data will already be streaming.

Bamba

  • RFduino Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
    • View Profile
Re: MPU6050 coding
« Reply #16 on: June 02, 2014, 03:35:27 PM »
yep, that worked!
not sure what causes the USB connection not to work after a reset, but I will dig into it a little bit.
thank you for your help!
B

wesley_w_li

  • RFduino Newbie
  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Re: MPU6050 coding
« Reply #17 on: August 12, 2014, 12:40:32 AM »
I replaced "Wire.begin();" => "Wire.beginOnPins(2, 3);", it worked.
but I changed to "Wire.beginOnPins(0, 1);", it didn't work.
Someone can help me?
thanks.

tolson

  • Global Moderator
  • *****
  • Posts: 812
  • Karma: +19/-0
    • View Profile
    • Thomas Olson Consulting
Re: MPU6050 coding
« Reply #18 on: August 12, 2014, 01:10:40 AM »
Pins 0 and 1 for the most part should be treated as reserved for the UART/USB interface.
Trying to use them for I2C or other communications just leads to trouble when you want to upload a sketch or monitor a sketch with least hassle.

devwatchdog

  • RFduino Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Re: MPU6050 coding
« Reply #19 on: August 24, 2014, 09:58:42 AM »
I'd like to thank everyone involved in this thread that has worked on providing code examples.  I do have a MPU6050, but was intending to use an ADXL345B for doing some testing on motion control of servos, but the MPU6050 has a gyroscope, whereas the ADXL345B doesn't. 

I read through the datasheet on the MPU6050, and am impressed with its capabilities. I'll start slow, however, and just get the basics to work.  I'll need to do quite a bit of work on the sketches here to get the data I need.  Once I come up with something I'll let you know. 

Something I do find interesting is the Digital Motion Processing feature of the MPU6050, which allows for offloading processing to the MPU6050 from the host to which it sends data.  This could be useful when pairing the device to the RFduino. I won't look into that until later, however.

I have several RFduino shields, one being the servo shield, which I tested with a simple sketch that would randomly select one of the three servos I had connected and orient it to a randomly generated orientation.  My next step is to take data generated by the MPU6050 on one RFduino and send it to another RFduino with the servo shield, where it will control servo rotation based on the tilt of the MPU6050.  I'll start with the basics and work out from there.   

Eventually, if I get ambitious, I might write a package for Android phones to control the servos. 

devwatchdog

  • RFduino Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Re: MPU6050 coding
« Reply #20 on: August 24, 2014, 07:10:07 PM »
Hey Tolson, that tilt3 sketch appears to be working fine for me!

I checked that data is being transmitted with an app on my Android phone.  Haven't confirmed the data I'm getting is good, but I'll address that soon enough. 

After taking a closer look at the sketch and seeing it's gyroscope data, I might not have to do anything with it for the time being.  This is just a POC and more or less my way of wading into the world of RFduino.  Dunno, I haven't looked at the processing sketch at all.  Might be able to hack that into something I can use on the side with the servo shield.

devwatchdog

  • RFduino Newbie
  • *
  • Posts: 3
  • Karma: +0/-0
    • View Profile
Re: MPU6050 coding
« Reply #21 on: August 24, 2014, 08:04:23 PM »
There is is in all its glory.


tolson

  • Global Moderator
  • *****
  • Posts: 812
  • Karma: +19/-0
    • View Profile
    • Thomas Olson Consulting
Re: MPU6050 coding
« Reply #22 on: November 20, 2015, 11:53:16 AM »
A video of the myTilt3 sketch controlling a 3D object on Android or iOS using EVOthings is in the VIDEOS section...

http://forum.rfduino.com/index.php?topic=1246.0

Johnny1010

  • RFduino Newbie
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
Re: MPU6050 coding
« Reply #23 on: October 04, 2016, 04:50:58 AM »
Hi Tolson,

I wanted to ask that at what dmp frequency did you run the MPU6050? I am running the dmp at 200 Hz and I get random acceleration values after 20-30 seconds. The values then might get corrected on their own. Sometimes bluetooth disconnection can also take place. This doesn't happen when I run the dmp at 100 Hz. Here is the code. I made some changes in the MPU6050_6Axis_MotionApps20.h file regarding the dmp frequency and making it run at 16g.

Code: [Select]
#include<RFduinoBLE.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"

#include "Wire.h"

MPU6050 mpu;

int check = 0;
int previous = 0;
char output[20];
unsigned long previousMillis;
float acc;

#define OUTPUT_READABLE_REALACCEL

// 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

int panot = 0;
// 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
uint32_t timer; //it's a timer, saved as a big-ass unsigned int.  We use it to save times from the "micros()" command and subtract the present time in microseconds from the time stored in timer to calculate the time for each loop.

// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

int count = 0;
int acceleration[10];
int counter = 0;


// ================================================================
// ===               INTERRUPT DETECTION ROUTINE                ===
// ================================================================

volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
int dmpDataRead(uint32_t ulPin) {
  mpuInterrupt = true;
}



// ================================================================
// ===                      INITIAL SETUP                       ===
// ================================================================

void setup() {
 
  RFduinoBLE.advertisementData = "abc";
  RFduinoBLE.deviceName = "abc";
  RFduinoBLE.txPowerLevel = +4;
  RFduinoBLE.begin();


override_uart_limit = true;

Wire.speed = 400;
  Wire.begin();


  Serial.begin(250000);
  // Serial.begin(9600);
  while (!Serial); // wait for Leonardo enumeration, others continue immediately


  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();


  mpu.setXGyroOffset(145); //220
  mpu.setYGyroOffset(8);  //76
  mpu.setZGyroOffset(38);  //-85
  mpu.setXAccelOffset(1192); // 1688 factory default for my test chip
  mpu.setYAccelOffset(-484); // 1688 factory default for my test chip
  mpu.setZAccelOffset(2202); // 1688 factory default for my test chip //1788

  mpu.setFullScaleAccelRange(3);

  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)..."));
    pinMode(2, INPUT);
    RFduino_pinWakeCallback(2, HIGH, dmpDataRead);
    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 {

    Serial.print(F("DMP Initialization failed (code "));
    Serial.print(devStatus);
    Serial.println(F(")"));
  }


}


//void RFduinoBLE_onReceive(char *data, int len)
//{
//
//  if (data[0] == 'a')
//  {
//    acceleration[count]=acc*100;
//  }
//  count++;
// 
//}

void RFduinoBLE_onDisconnect()
{

  RFduino_systemReset();

}

// ================================================================
// ===                    MAIN PROGRAM LOOP                     ===
// ================================================================

void loop() {

  if (!dmpReady) return;

  // wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt && fifoCount < packetSize) {

  }

  // 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;

#ifdef OUTPUT_READABLE_REALACCEL
    // display real acceleration, adjusted to remove gravity
    mpu.dmpGetQuaternion(&q, fifoBuffer);
    mpu.dmpGetAccel(&aa, fifoBuffer);
    mpu.dmpGetGravity(&gravity, &q);
    mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
    acc = sqrt(sq(aaReal.x) + sq(aaReal.y) + sq(aaReal.z));
    acc = (acc / 2048) * 9.8;
   
    Serial.println(acc);
   
      if(count==9)
      {
      acceleration[count]=counter;
      }
      else
      {
      acceleration[count]=acc*10;
      }
      count++;
      if(count==10)
      {
      counter++;
      for (int i = 0; i < 10; i++){
      for (int j = 0; j < 2; j++){
        output[2*i+j]=(char)(acceleration[i] >> (8*j) & 0xFF);
      }
      count=0;
      }
      RFduinoBLE.send(output,20);
      /*  for (int i=0;i<10;i++)
      {
      Serial.println(acceleration[i]);

      }
      Serial.println("");
    */

    }


#endif




  }

}

« Last Edit: October 04, 2016, 05:16:26 AM by Johnny1010 »

tolson

  • Global Moderator
  • *****
  • Posts: 812
  • Karma: +19/-0
    • View Profile
    • Thomas Olson Consulting
Re: MPU6050 coding
« Reply #24 on: October 04, 2016, 02:52:20 PM »
Jeff warns that running faster than 100 Hz is noisy. Priority radio interruptions add to the difficulty to handle the data. I think my project was fine at 20 Hz.