bool Gyro_init(void) { Wire.begin(); mpu.initialize(); if (mpu.testConnection() == false) { return false; } devStatus = mpu.dmpInitialize(); if (devStatus == 0) { mpu.setXGyroOffset(X_GYRO_OFFSET); mpu.setYGyroOffset(Y_GYRO_OFFSET); mpu.setZGyroOffset(Z_GYRO_OFFSET); mpu.setXAccelOffset(X_ACCEL_OFFSET); mpu.setYAccelOffset(Y_ACCEL_OFFSET); mpu.setZAccelOffset(Z_ACCEL_OFFSET); mpu.setDMPEnabled(true); dmpReady = true; attachInterrupt(0, dmp_data_ready, RISING); mpuIntStatus = mpu.getIntStatus(); packetSize = mpu.dmpGetFIFOPacketSize(); return true; } else { return false; } }
void setup() { Wire.begin(); if (debugSerial){ Serial.begin(115200); Serial.println(F("=================== SETUP =================")); } // initialize device if (debugSerial && debugMPU6050) Serial.println(F("Initializing I2C devices...")); accelgyro.initialize(); // verify connection if (debugSerial && debugMPU6050) { Serial.println("Testing device connections..."); boolean OK = accelgyro.testConnection() ; ( OK )? Serial.println(F("MPU6050 connection successful")): Serial.println(F("MPU6050 connection failed")); } if (debugSerial){ Serial.println(F("=============== FIM SETUP =================")); } }
/* * Updates function * */ extern "C" void sf_MPU6050_2xDriver_GxAyz_Update_wrapper(const int16_T *x_vel, const int16_T *y_acc, const int16_T *z_acc, const int16_T *x_vel_2, const int16_T *y_acc_2, const int16_T *z_acc_2, real_T *xD) { /* %%%-SFUNWIZ_wrapper_Update_Changes_BEGIN --- EDIT HERE TO _END */ if(xD[0] != 1){ # ifndef MATLAB_MEX_FILE Wire.begin(); accelgyro.initialize(); accelgyro.setDLPFMode(MPU6050_DLPF_BW_42); accelgyro.setFullScaleGyroRange(MPU6050_GYRO_FS_1000); accelgyro2.initialize(); accelgyro2.setDLPFMode(MPU6050_DLPF_BW_42); accelgyro2.setFullScaleGyroRange(MPU6050_GYRO_FS_1000); #endif //done with initialization xD[0] = 1; } /* %%%-SFUNWIZ_wrapper_Update_Changes_END --- EDIT HERE TO _BEGIN */ }
bool i2cSetupGyro() { //wake up gyro //return I2Cdev::writeBit( gyroAddr, 0x6b, 6, 0b0); gyroscope.initialize(); return gyroscope.testConnection(); }
// setup AVR I2C void userSetup() { #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); Wire.setClock(400000); #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif mpu.initialize(); }
void setup() { // initialize device printf("Initializing I2C devices...\n"); accelgyro.initialize(); gettimeofday(&tv0, NULL); // verify connection printf("Testing device connections...\n"); printf(accelgyro.testConnection() ? "MPU6050 connection successful\n" : "MPU6050 connection failed\n"); }
void setup() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); //Wire.setClock(400000); // 400kHz I2C clock. Comment this line if having compilation difficulties #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // initialize serial communication Serial.begin(38400); while (!Serial); mpu.initialize(); pinMode(INTERRUPT_PIN, INPUT); send_status(MPU_INITIALIZE, STATUS_OK); // verify connection send_status(MPU_CONNECTION, mpu.testConnection() ? STATUS_OK : STATUS_FAIL); // load and configure the DMP // 0 = DMP OK // 1 = initial memory load failed // 2 = DMP configuration updates failed ua_dev_status = mpu.dmpInitialize(); send_status(DMP_INITIALIZE, ua_dev_status); // supply your own gyro offsets here, scaled for min sensitivity mpu.setXGyroOffset(120); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-185); mpu.setZAccelOffset(1688); // 1688 factory default for my test chip // make sure it worked (returns 0 if so) if (ua_dev_status == 0) { // turn on the DMP, now that it's ready mpu.setDMPEnabled(true); // enable Arduino interrupt detection attachPinChangeInterrupt(INTERRUPT_PIN, dmpDataReady, RISING); ua_mpu_interrupt_status = mpu.getIntStatus(); send_status(DMP_INTERRUPT, ua_mpu_interrupt_status); b_dmp_ready = true; // get expected DMP packet size for later comparison uh_packet_size = mpu.dmpGetFIFOPacketSize(); } // configure LED for output pinMode(LED_PIN, OUTPUT); }
/* Initialize the IMU and I2C communication */ void IMUInit(){ /* Intialize communication I2C */ Wire.begin(); /* Initialize IMU. Default resolution is set to minimum, no offsets */ IMU.initialize(); /* Get first values for accel and gyro */ IMU.getMotion6(&accel[0], &accel[1], &accel[2], &gyro[0], &gyro[1], &gyro[2]); }
void setup_IMU() { I2CInitialize(); mpu.initialize(); devStatus = mpu.dmpInitialize(); if (devStatus == 0) { mpu.setDMPEnabled(true); mpuIntStatus = mpu.getIntStatus(); dmpReady = true; packetSize = mpu.dmpGetFIFOPacketSize(); } }
void setup_IMU() { tmObjectInit(&lagedatalogsync_tmup); I2CInitialize(); mpu.initialize(); devStatus = mpu.dmpInitialize(); if (devStatus == 0) { //chThdCreateStatic(LageSyncThreadWorkingArea, sizeof(LageSyncThreadWorkingArea), NORMALPRIO, LageSyncthread, NULL); mpu.setDMPEnabled(true); mpuIntStatus = mpu.getIntStatus(); dmpReady = true; packetSize = mpu.dmpGetFIFOPacketSize(); } }
int setup() { // initialize device printf("Initializing MPU ...\n"); mpu.initialize(); // verify connection printf("Testing connection ...\n"); if (!mpu.testConnection()) { printf("MPU6050 connection failed\n"); return 1; } // load and configure the DMP printf("Flashing DMP ...\n"); devStatus = mpu.dmpInitialize(); // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready 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 dmpReady = true; // get expected DMP packet size for later comparison packetSize = mpu.dmpGetFIFOPacketSize(); printf("DMP ready\n"); printf("MPU6050 initialized!\n"); return 0; } else { // ERROR! // 1 = initial memory load failed // 2 = DMP configuration updates failed // (if it's going to break, usually the code will be 1) printf("DMP Initialization failed (code %d)\n", devStatus); return 1; } }
void setup() { mpu.initialize(); // trace_printf(mpu.testConnection() ? ("MPU6050 connection successful\n") : ("MPU6050 connection failed\n")); // load and configure the DMP // trace_printf("Initializing DMP...\n"); devStatus = mpu.dmpInitialize(); // supply your own gyro offsets here, scaled for min sensitivity mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.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 // trace_printf("Enabling DMP...\n"); mpu.setDMPEnabled(true); mpuIntStatus = mpu.getIntStatus(); // set our DMP Ready flag so the main loop() function knows it's okay to use it // trace_printf("DMP ready! Waiting for first interrupt...\n"); // trace_printf("System is running!\n"); 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) // trace_printf("DMP Initialization failed (code \n"); // trace_printf("%d\n", devStatus); } }
int mpuInit() { // initialize device logln("Initializing I2C devices..."); mpu.initialize(); // verify connection logln("Testing device connections..."); mpu.testConnection() ? logln("MPU6050 connection successful") : logln("MPU6050 connection failed"); // load and configure the DMP logln("Initializing DMP..."); devStatus = mpu.dmpInitialize(); // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready logln("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 logln("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) logln("DMP Initialization failed (code %d)", devStatus); } }
void setup() { // initialize device accelgyro.initialize(); // printf(accelgyro.testConnection() ? "MPU6050 connection successful\n" : "MPU6050 connection failed\n"); }
void imu_init() { uint8_t count = 10; // initialize device #ifdef __BOARD_YUN__ Console.println(F("Initializing I2C devices...")); #else Serial.println(F("Initializing I2C devices...")); #endif mpu.initialize(); // verify connection #ifdef __BOARD_YUN__ Console.println(F("Testing device connections...")); Console.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); #else Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); #endif /* // wait for ready Serial.println(F("\nSend any character to begin DMP programming and demo: ")); while (Serial.available() && Serial.read()); // empty buffer while (!Serial.available()); // wait for data while (Serial.available() && Serial.read()); // empty buffer again */ // load and configure the DMP #ifdef __BOARD_YUN__ Console.println(F("Initializing DMP...")); #else Serial.println(F("Initializing DMP...")); #endif do { devStatus = mpu.dmpInitialize(); // Set some offset to the MEMS mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); // make sure it worked (returns 0 if so) if (devStatus == 0) { count = 10; // turn on the DMP, now that it's ready #ifdef __BOARD_YUN__ Console.println(F("Enabling DMP...")); #else Serial.println(F("Enabling DMP...")); #endif mpu.setDMPEnabled(true); mpuIntStatus = mpu.getIntStatus(); // set our DMP Ready flag so the main loop() function knows it's okay to use it #ifdef __BOARD_YUN__ Console.println(F("DMP ready! Waiting for first interrupt...")); #else Serial.println(F("DMP ready! Waiting for first interrupt...")); #endif dmpReady = true; // get expected DMP packet size for later comparison packetSize = mpu.dmpGetFIFOPacketSize(); return; } else { // ERROR! // 1 = initial memory load failed // 2 = DMP configuration updates failed // (if it's going to break, usually the code will be 1) #ifdef __BOARD_YUN__ Console.print(F("DMP Initialization failed (code")); Console.print(devStatus); Console.println(F(")")); // New attempt message Console.println(F("Trying again")); #else Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); // New attempt message Serial.println(F("Trying again")); #endif } } while (--count); // configure LED for output pinMode(SOL_LED, OUTPUT); // Check if the configuration has failed // if (!count) { #ifdef __BOARD_YUN__ Console.println(F("DMP initializaion failed")); #else Serial.println(F("DMP initialization failed")); #endif while (true) { // Locks in infinite loop digitalWrite(SOL_LED, HIGH); delay(300); digitalWrite(SOL_LED, LOW); delay(300); } } }
int main(int argc, char **argv) { printf("MPU6050 3-axis acceleromter example program\n"); I2Cdev::initialize(); MPU6050 accelgyro ; int16_t ax, ay, az; int16_t gx, gy, gz; accelgyro.initialize(); if ( accelgyro.testConnection() ) printf("MPU6050 connection test successful\n") ; else { fprintf( stderr, "MPU6050 connection test failed! something maybe wrong, continuing anyway though ...\n"); //return 1; } // use the code below to change accel/gyro offset values /* printf("Updating internal sensor offsets...\n"); // -76 -2359 1688 0 0 0 printf("%i \t %i \t %i \t %i \t %i \t %i\n", accelgyro.getXAccelOffset(), accelgyro.getYAccelOffset(), accelgyro.getZAccelOffset(), accelgyro.getXGyroOffset(), accelgyro.getYGyroOffset(), accelgyro.getZGyroOffset()); accelgyro.setXGyroOffset(220); accelgyro.setYGyroOffset(76); accelgyro.setZGyroOffset(-85); printf("%i \t %i \t %i \t %i \t %i \t %i\n", accelgyro.getXAccelOffset(), accelgyro.getYAccelOffset(), accelgyro.getZAccelOffset(), accelgyro.getXGyroOffset(), accelgyro.getYGyroOffset(), accelgyro.getZGyroOffset()); */ printf("\n"); printf(" ax \t ay \t az \t gx \t gy \t gz:\n"); while (true) { accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); // printf(" %d \t %d \t %d \t %d \t %d \t %d\n", ax, ay, az, gx, gy, gz); // accelgyro.getAcceleration(&ax, &ay, &az); // printf(" %d \t %d \t %d \r", ax, ay, az); float axs = ax/16384.0; float ays = ay/16384.0; float azs = az/16384.0; float dxz = sqrt( axs*axs+azs*azs); float dyz = sqrt( ays*ays+azs*azs); float rotX = atan2(axs,dyz); float rotY = atan2(ays,dxz); printf(" %f \t %f \r", 180*rotX/3.14159, 180*rotY/3.14159); fflush(stdout); // fflush(stdout); bcm2835_delay(100); } return 1; }
int main(int argc, char const *argv[]) { AccelVector gravity; MPU6050 accelgyro; accelgyro.initialize(); accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_2); int16_t x=-3940, y=-0110, z=00326; int16_t gx, gy, gz; // accelgyro.getAcceleration(&x, &y,&z); gravity.x = x; gravity.y = y; gravity.z = z; float alpha = 0.5f, gyralpha = 0.9f; // for(int i=0; i<100; i++){ // accelgyro.getAcceleration(&x, &y,&z); // gravity.x = gravity.x * alpha + x * (1 - alpha); // gravity.y = gravity.y * alpha + y * (1 - alpha); // gravity.z = gravity.z * alpha + z * (1 - alpha); // usleep(50000); // } AccelVector vec, gyr; accelgyro.getMotion6(&x, &y,&z, &gx, &gy, &gz); gyr.x = gx; gyr.y = gy; gyr.z = gz; while(1) { accelgyro.getMotion6(&x, &y,&z, &gx, &gy, &gz); //accelgyro.getAcceleration(&x, &y,&z,); vec.x = vec.x * alpha + x * (1 - alpha); vec.y = vec.y * alpha + y * (1 - alpha); vec.z = vec.z * alpha + z * (1 - alpha); gyr.x = gyr.x * gyralpha + gx * (1 - gyralpha); gyr.y = gyr.y * gyralpha + gy * (1 - gyralpha); gyr.z = gyr.z * gyralpha + gz * (1 - gyralpha); printf("Total gforce now %.3f g's gyro len %.3f | Now: %05.0f %05.0f %05.0f Gyro: %05.0f %05.0f %05.0f\n", vec.getMagnitude()/16000, gyr.getMagnitude(), vec.x, vec.y, vec.z, gyr.x, gyr.y, gyr.z); usleep(50000); } // 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 MPU6050 accelgyro; accelgyro.initialize(); // load and configure the DMP printf("Initializing DMP...\n"); devStatus = accelgyro.dmpInitialize(); // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready printf("Enabling DMP...\n"); accelgyro.setDMPEnabled(true); // enable Arduino interrupt detection //Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)...")); //attachInterrupt(0, dmpDataReady, RISING); mpuIntStatus = accelgyro.getIntStatus(); // set our DMP Ready flag so the main loop() function knows it's okay to use it printf("DMP ready!\n"); dmpReady = true; // get expected DMP packet size for later comparison packetSize = accelgyro.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) printf("DMP Initialization failed (code %d)\n", devStatus); return 0; } while(1){ fifoCount = accelgyro.getFIFOCount(); if (fifoCount == 1024) { // reset so we can continue cleanly accelgyro.resetFIFO(); printf("FIFO overflow!\n"); // otherwise, check for DMP data ready interrupt (this should happen frequently) } else if (fifoCount >= 42) { // read a packet from FIFO accelgyro.getFIFOBytes(fifoBuffer, packetSize); // display Euler angles in degrees accelgyro.dmpGetQuaternion(&q, fifoBuffer); accelgyro.dmpGetGravity(&gravity, &q); accelgyro.dmpGetYawPitchRoll(ypr, &q, &gravity); printf("ypr %7.2f %7.2f %7.2f \n", ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI); } } */ return 0; }
void Test_Sensor9Axis(void) { uint8_t ch, dataVal; DEBUG_MSG_FUNC_START; while(1) { print_menu_command(); if(false == UartQueue_Serial_Is_Empty()) { ch = UartQueue_Serial_DeQueue(); printf("%c is selected\n\n", (char)ch); switch((char)ch) { case '0': break; case '1': dataVal = g_MPU_9150.getDeviceID(); printf("Device ID: 0x%02X\n", dataVal); break; case '2': // read mag - set i2c bypass enable pin to true to access magnetometer I2Cdev::writeByte(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_INT_PIN_CFG, 0x02); Delay(50); // enable the magnetometer I2Cdev::writeByte(MPU9150_RA_MAG_ADDRESS, 0x0A, 0x01); Delay(50); I2Cdev::readByte(MPU9150_RA_MAG_ADDRESS, 0, &dataVal); printf("Device ID: 0x%02X\n", dataVal); break; case '3': { int16_t ax, ay, az; int16_t gx, gy, gz; int16_t mx, my, mz; g_MPU_9150.initialize(); printf("MPU9150 initialize done.\n"); while(1) { // read raw accel/gyro measurements from device g_MPU_9150.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz); printf("ax: %d, ay: %d, az: %d, gx: %d, gy: %d, gz: %d, mx: %d, my: %d, mz: %d\n", ax, ay, az, gx, gy, gz, mx, my, mz); Delay(300); } } break; } g_print_menu_control_flag = true; if('x' == (char)ch) { break; } } } return; }
void setup() { Spark.variable("quaternionW", &quaternionW, DOUBLE); // join I2C bus (I2Cdev library doesn't do this automatically) Wire.begin(); //TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) // initialize serial communication // (115200 chosen because it is required for Teapot Demo output, but it's // really up to you depending on your project) Serial.begin(115200); while (!Serial.available()) ; // wait for Leonardo enumeration, others continue immediately // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to // the baud timing being too misaligned with processor ticks. You must use // 38400 or slower in these cases, or use some kind of external separate // crystal solution for the UART timer. // initialize device Serial.println("Initializing I2C devices..."); mpu.initialize(); // verify connection Serial.println("Testing device connections..."); Serial.println(mpu.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); // wait for ready Serial.println("\nSend any character to begin DMP programming and demo: "); while (Serial.available() && Serial.read()); // empty buffer while (!Serial.available()); // wait for data while (Serial.available() && Serial.read()); // empty buffer again // load and configure the DMP Serial.println("Initializing DMP..."); devStatus = mpu.dmpInitialize(); // supply your own gyro offsets here, scaled for min sensitivity mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.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("Enabling DMP..."); mpu.setDMPEnabled(true); // enable Arduino interrupt detection Serial.println("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("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("DMP Initialization failed (code "); Serial.print(devStatus); Serial.println(")"); } // configure LED for output pinMode(LED_PIN, OUTPUT); }
// This function initialises the MPU6050 // 655 = me shaking violently void Accel_init(void) { printf("\nInvitializing I2C devices..."); accelgyro.initialize(); }//END ACCEL_Init
void initialize_imu() { // join I2C bus (I2Cdev library doesn't do this automatically) #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); // ************************************************************** // It is best to configure I2C to 400 kHz. // If you are using an Arduino DUE, modify the variable TWI_CLOCK to 400000, defined in the file: // c:/Program Files/Arduino/hardware/arduino/sam/libraries/Wire/Wire.h // If you are using any other Arduino instead of the DUE, uncomment the following line: //TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz) //This line should be commented if you are using Arduino DUE // ************************************************************** #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE Fastwire::setup(400, true); #endif // initialize serial communication Serial.begin(250000); // 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")); // TODO: Compute these parameters // mpu.setXAccelOffset(-1600); // mpu.setYAccelOffset(-180); // mpu.setZAccelOffset(650); // mpu.setXGyroOffset(0); // mpu.setYGyroOffset(0); // mpu.setZGyroOffset(0); mpu.setFullScaleGyroRange(0); calibrate_imu(); // Magnetometer configuration mpu.setI2CMasterModeEnabled(0); mpu.setI2CBypassEnabled(1); Wire.beginTransmission(HMC5883L_DEFAULT_ADDRESS); Wire.write(0x02); Wire.write(0x00); // Set continuous mode Wire.endTransmission(); delay(5); Wire.beginTransmission(HMC5883L_DEFAULT_ADDRESS); Wire.write(0x00); Wire.write(B00011000); // 75Hz Wire.endTransmission(); delay(5); mpu.setI2CBypassEnabled(0); // X axis word mpu.setSlaveAddress(0, HMC5883L_DEFAULT_ADDRESS | 0x80); // 0x80 turns 7th bit ON, according to datasheet, 7th bit controls Read/Write direction mpu.setSlaveRegister(0, HMC5883L_RA_DATAX_H); mpu.setSlaveEnabled(0, true); mpu.setSlaveWordByteSwap(0, false); mpu.setSlaveWriteMode(0, false); mpu.setSlaveWordGroupOffset(0, false); mpu.setSlaveDataLength(0, 2); // Y axis word mpu.setSlaveAddress(1, HMC5883L_DEFAULT_ADDRESS | 0x80); mpu.setSlaveRegister(1, HMC5883L_RA_DATAY_H); mpu.setSlaveEnabled(1, true); mpu.setSlaveWordByteSwap(1, false); mpu.setSlaveWriteMode(1, false); mpu.setSlaveWordGroupOffset(1, false); mpu.setSlaveDataLength(1, 2); // Z axis word mpu.setSlaveAddress(2, HMC5883L_DEFAULT_ADDRESS | 0x80); mpu.setSlaveRegister(2, HMC5883L_RA_DATAZ_H); mpu.setSlaveEnabled(2, true); mpu.setSlaveWordByteSwap(2, false); mpu.setSlaveWriteMode(2, false); mpu.setSlaveWordGroupOffset(2, false); mpu.setSlaveDataLength(2, 2); mpu.setI2CMasterModeEnabled(1); mpu.setDLPFMode(6); }
// // main task // int main(void) { #ifdef DEBUG #if __USE_USB usbCDC ser; ser.connect(); #else CSerial ser; ser.settings(115200); #endif CDebug dbg(ser); dbg.start(); #endif /************************************************************************* * * your setup code here * **************************************************************************/ // // Load Configuration // EEPROM::read(0, &config, sizeof(config)); if ( config.length!=sizeof(config) ) { setDefault(); } // 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 mpu; // initialize device mpu.initialize(); mpu.setRate(7); mpu.setFullScaleGyroRange(MPU6050_GYRO_FS_250); mpu.setFullScaleAccelRange(MPU6050_ACCEL_FS_2); // // check device // if (mpu.testConnection()) { } // // H-Bridge // CPwm::frequency(KHZ(20)); HBridge left(PWM1, P18, P19); HBridge right(PWM2, P22, P23); left.enable(); right.enable(); BalanceRobot robot(mpu, left, right); robot.start("Robot", 168, PRI_HIGH); #ifndef DEBUG myMenu menu(mpu, robot); menu.start(); #endif while (1) { /********************************************************************** * * your loop code here * **********************************************************************/ LEDs[0] = !LEDs[0]; sleep(500); } return 0;
static void setup() { // initialize device printf("Initializing I2C devices...\n"); mpu.initialize(); // verify connection printf("Testing device connections...\n"); printf(mpu.testConnection() ? "MPU6050 connection successful\n" : "MPU6050 connection failed\n"); // load and configure the DMP printf("Initializing DMP...\n"); devStatus = mpu.dmpInitialize(); // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready printf("Enabling DMP...\n"); 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 printf("DMP ready! Waiting for first interrupt...\n"); 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) printf("DMP Initialization failed (code %d)\n", devStatus); } /* adjAccel[0] = adjAccel[1] = adjAccel[2] = 0; adjGyro[0] = adjGyro[1] = adjGyro[2] = 0; for (int i = 0; i < 20; i++) { readFIFO(); mpu.dmpGetAccel(accel, fifoBuffer); mpu.dmpGetGyro(gyro, fifoBuffer); adjAccel[0] += accel[0]; adjAccel[1] += accel[1]; adjAccel[2] += accel[2]; adjGyro[0] += gyro[0]; adjGyro[1] += gyro[1]; adjGyro[2] += gyro[2]; } adjAccel[0] /= 20; adjAccel[1] /= 20; adjAccel[2] /= 20; adjGyro[0] /= 20; adjGyro[1] /= 20; adjGyro[2] /= 20; printf("ADJUST: %d, %d, %d\n", adjAccel[0], adjAccel[1], adjAccel[2]); */ measurement.setTo(cv::Scalar(0)); kalman.transitionMatrix = *(cv::Mat_<float>(4, 4) << 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1); readFIFO(); mpu.dmpGetAccel(accel, fifoBuffer); kalman.statePre.at<float>(0) = accel[0]; kalman.statePre.at<float>(1) = accel[1]; kalman.statePre.at<float>(2) = accel[2]; kalman.statePre.at<float>(3) = 0.0; setIdentity(kalman.measurementMatrix); setIdentity(kalman.processNoiseCov, cv::Scalar::all(1e-4)); setIdentity(kalman.measurementNoiseCov, cv::Scalar::all(10)); setIdentity(kalman.errorCovPost, cv::Scalar::all(.1)); }
void* gyro_acc(void*) { //float kp = 0.00375,ki = 0.0000,kd = 0.00076; float kp = 0.0068,ki = 0.000,kd = 0.0018; //0030 0088 0014 有偏角 p0.0031偏角更大 0.0029也是 i=0 小偏角 p0.00305 d0.00143 不错 i0.0005 偏角变大 //0032 0017 float pregyro =0; float desired = 0; //double error; float integ=0;//integral积分参数 float iLimit =8 ; float deriv=0;//derivative微分参数 float prevError=0; float lastoutput=0; //float Piddeadband=0.3; // initialize device printf("Initializing I2C devices...\n"); mpu.initialize(); // verify connection printf("Testing device connections...\n"); printf(mpu.testConnection() ? "MPU6050 connection successful\n" : "MPU6050 connection failed\n"); mpu.setI2CMasterModeEnabled(false); mpu.setI2CBypassEnabled(true); // load and configure the DMP printf("Initializing DMP...\n"); devStatus = mpu.dmpInitialize(); // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready printf("Enabling DMP...\n"); 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 printf("DMP ready!\n"); 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) printf("DMP Initialization failed (code %d)\n", devStatus); } /*****************************************************/ while(1) { if (START_FLAG == 0) { delay(200); } if (START_FLAG == 1) { break; } } delay(50); for(;;) { if (!dmpReady) return 0; // get current FIFO count fifoCount = mpu.getFIFOCount(); if (fifoCount == 1024) { // reset so we can continue cleanly mpu.resetFIFO(); printf("FIFO overflow!\n"); // otherwise, check for DMP data ready interrupt (this should happen frequently) } else if (fifoCount >= 42) { // read a packet from FIFO mpu.getFIFOBytes(fifoBuffer, packetSize); // display Euler angles in degrees mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); //printf("ypr %7.2f %7.2f %7.2f ", ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI); Angle[2] = ypr[0] * 180/M_PI; Angle[1] = ypr[1] * 180/M_PI;//此为Pitch Angle[0] = ypr[2] * 180/M_PI;//此为Roll // display initial world-frame acceleration, adjusted to remove gravity // and rotated based on known orientation from quaternion mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetAccel(&aa, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); //printf("aworld %6d %6d %6d ", aaWorld.x, aaWorld.y, aaWorld.z); AngleSpeed[0] = aaWorld.x; AngleSpeed[1] = aaWorld.y; AngleSpeed[2] = aaWorld.z; /****************************读取完毕*********************************/ error = desired - Angle[0];//偏差:期望-测量值 All_Count = All_Count + 1; error = error * 0.88 + prevError * 0.12; /* if (fabs(prevError - error ) > 12) { error = prevError; }*/ integ += error * IMU_UPDATE_DT;//偏差积分,IMU_UPDATE_DT也就是每调整漏斗大小的步辐 if (integ >= iLimit)//作积分限制 { integ = iLimit; } else if (integ < -iLimit) { integ = -iLimit; } deriv = (error - prevError) / IMU_UPDATE_DT;//微分 应该可用陀螺仪角速度代替 AngleSpeed[0] = deriv; if (fabs(deriv) < 20 ) { if (fabs(deriv) < 10 ) { deriv = deriv * 0.8; } else { deriv = deriv * 0.9; } } //if(deriv //roll.deriv = -gyro;//注意是否跟自己的参数方向相反,不然会加剧振荡 //deriv = -AngleSpeed[0]; /* if (fabs(pregyro - deriv) > 20) { deriv = deriv * 0.5 + pregyro * 0.5; } */ output = (kp * error) + (ki * integ) + (kd * deriv); prevError = error;//更新前一次偏差 pregyro = deriv; if (output > 0.16) { output = 0.16; } if (output < -0.16) { output = -0.16; } Pid_Roll = output; //output = output * 0.9 + lastoutput * 0.1; if (fabs(error) < 0.3 ) { output = lastoutput * 0.5; } lastoutput = output; DutyCycle[0] = Default_Acc - output; DutyCycle[1] = Default_Acc - output; //DutyCycle[0] = Default_Acc; //DutyCycle[1] = Default_Acc; DutyCycle[2] = Default_Acc + output; DutyCycle[3] = Default_Acc + output; //DutyCycle[2] = Default_Acc; //DutyCycle[3] = Default_Acc; PWMOut(PinNumber1,DutyCycle[0]); PWMOut(PinNumber2,DutyCycle[1]); PWMOut(PinNumber3,DutyCycle[2]); PWMOut(PinNumber4,DutyCycle[3]); } } }
void* gyro_acc(void*) { int i = 0; // initialize device printf("Initializing I2C devices...\n"); mpu.initialize(); // verify connection printf("Testing device connections...\n"); printf(mpu.testConnection() ? "MPU6050 connection successful\n" : "MPU6050 connection failed\n"); mpu.setI2CMasterModeEnabled(false); mpu.setI2CBypassEnabled(true); // load and configure the DMP printf("Initializing DMP...\n"); devStatus = mpu.dmpInitialize(); // make sure it worked (returns 0 if so) if (devStatus == 0) { // turn on the DMP, now that it's ready printf("Enabling DMP...\n"); 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 printf("DMP ready!\n"); 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) printf("DMP Initialization failed (code %d)\n", devStatus); return 0; } /*****************************************************/ while(1) { if (START_FLAG == 0) { delay(200); } if (START_FLAG == 1) { break; } } delay(50); for(;;) { if (!dmpReady) return 0; // get current FIFO count fifoCount = mpu.getFIFOCount(); if (fifoCount == 1024) { // reset so we can continue cleanly mpu.resetFIFO(); printf("FIFO overflow!\n"); // otherwise, check for DMP data ready interrupt (this should happen frequently) } else if (fifoCount >= 42) { // read a packet from FIFO mpu.getFIFOBytes(fifoBuffer, packetSize); // display Euler angles in degrees mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); //printf("ypr %7.2f %7.2f %7.2f ", ypr[0] * 180/M_PI, ypr[1] * 180/M_PI, ypr[2] * 180/M_PI); Angle[2] = ypr[0] * 180/M_PI; Angle[1] = ypr[1] * 180/M_PI;//此为Pitch Angle[0] = ypr[2] * 180/M_PI;//此为Roll // display initial world-frame acceleration, adjusted to remove gravity // and rotated based on known orientation from quaternion /* mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetAccel(&aa, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q); //printf("aworld %6d %6d %6d ", aaWorld.x, aaWorld.y, aaWorld.z); //AngleSpeed[0] = aaWorld.x; //AngleSpeed[1] = aaWorld.y; //AngleSpeed[2] = aaWorld.z; */ /****************************读取完毕*********************************/ if (Inital <= 300) { Inital ++; if (Inital % 98 == 1) { Inital_Roll[i] = Angle[0]; Inital_Pitch[i] = Angle[1]; Inital_Yaw[i] = Angle[2]; printf("Roll:%.2f Pitch:%.2f Yaw:%.2f",Inital_Roll[i],Inital_Pitch[i],Inital_Yaw[i]); i++; printf("%d\n",Inital); fflush(stdout); if (i == 3) { Inital_Yaw[3] = (Inital_Yaw[0] + Inital_Yaw[1] + Inital_Yaw[2]) / 3; Inital_Roll[3] =(Inital_Roll[0] + Inital_Roll[1] + Inital_Roll[2]) / 3; Inital_Pitch[3] = (Inital_Pitch[0] + Inital_Pitch[1] + Inital_Pitch[2]) / 3; } } } else { Pid_Roll = Pid_Calc_R(Roll_Suit,Angle[0]); Pid_Pitch = Pid_Calc_P(Pitch_Suit,Angle[1]); Pid_Yaw = Pid_Calc_Y(Yaw_Suit,Angle[2],Inital_Yaw[3]); All_Count = All_Count + 1; DutyCycle[0] = Default_Acc - Pid_Roll - Pid_Pitch; //- Pid_Yaw; DutyCycle[1] = Default_Acc - Pid_Roll + Pid_Pitch; //+ Pid_Yaw; //DutyCycle[0] = Default_Acc; //DutyCycle[1] = Default_Acc; DutyCycle[2] = Default_Acc + Pid_Roll - Pid_Pitch; //+ Pid_Yaw; DutyCycle[3] = Default_Acc + Pid_Roll + Pid_Pitch; //- Pid_Yaw; //DutyCycle[2] = Default_Acc; //DutyCycle[3] = Default_Acc; PWMOut(PinNumber1,DutyCycle[0]); PWMOut(PinNumber2,DutyCycle[1]); PWMOut(PinNumber3,DutyCycle[2]); PWMOut(PinNumber4,DutyCycle[3]); } } } }
int main() { int i, last_led_update = 0; initWiring(); st7565Init(Font5x7); st7565ClearScreen(); st7565SetBrightness(12); st7565DrawString(1, 5, "Test"); for(i = 0; i < 100; i++) { st7565DrawPixel(1+i,14); } st7565Refresh(); #if KKVER == 21 Fastwire::setup(100, true); MPU6050 mpu; mpu.initialize(); #endif DDRB &= _BV(LED_PIN); // Set pin 3 of port B to output (LED pin) for(;;) { char buff[512]; if(millis() - last_led_update > 1000) { PORTB ^= _BV(LED_PIN); last_led_update = millis(); } st7565ClearScreen(); #if KKVER == 21 if(mpu.testConnection()) { st7565DrawString(1,20, "Connected"); } else { st7565DrawString(1,20, "Not connected"); } sprintf(buff, "acc_x = %d\n", mpu.getAccelerationX()); st7565DrawString(1,30, buff); #else st7565DrawString(1,20, "No ACC available"); #endif st7565Refresh(); delay(50); } return 0; }
//PROGRAM FUNCTIONS void setup_mpu6050(){ clear_i2c(); Wire.begin(); SERIAL_OUT.println("Initializing gyro..."); accelgyro.initialize(); //accelgyro.reset(); accelgyro.setSleepEnabled(false); // thanks to Jack Elston for pointing this one out! // verify connection SERIAL_OUT.println("Testing device connections..."); SERIAL_OUT.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); SERIAL_OUT.println(F("Setting clock source to Z Gyro...")); accelgyro.setClockSource(MPU6050_CLOCK_PLL_ZGYRO); //SERIAL_OUT.println(accelgyro.getClockSource(MPU6050_CLOCK_PLL_ZGYRO); SERIAL_OUT.println(F("Setting sample rate to 200Hz...")); accelgyro.setRate(0); // 1khz / (1 + 4) = 200 Hz // * | ACCELEROMETER | GYROSCOPE // * DLPF_CFG | Bandwidth | Delay | Bandwidth | Delay | Sample Rate // * ---------+-----------+--------+-----------+--------+------------- // * 0 | 260Hz | 0ms | 256Hz | 0.98ms | 8kHz // * 1 | 184Hz | 2.0ms | 188Hz | 1.9ms | 1kHz // * 2 | 94Hz | 3.0ms | 98Hz | 2.8ms | 1kHz // * 3 | 44Hz | 4.9ms | 42Hz | 4.8ms | 1kHz // * 4 | 21Hz | 8.5ms | 20Hz | 8.3ms | 1kHz // * 5 | 10Hz | 13.8ms | 10Hz | 13.4ms | 1kHz // * 6 | 5Hz | 19.0ms | 5Hz | 18.6ms | 1kHz // * 7 | -- Reserved -- | -- Reserved -- | Reserved SERIAL_OUT.println(F("Setting DLPF bandwidth")); accelgyro.setDLPFMode(MPU6050_DLPF_BW_42); SERIAL_OUT.println(F("Setting gyro sensitivity to +/- 250 deg/sec...")); accelgyro.setFullScaleGyroRange(0); //accelgyro.setFullScaleGyroRange(MPU6050_GYRO_FS_250); //accelgyro.setFullScaleGyroRange(0); // 0=250, 1=500, 2=1000, 3=2000 deg/sec //SERIAL_OUT.println(F("Resetting FIFO...")); //accelgyro.resetFIFO(); // use the code below to change accel/gyro offset values accelgyro.setXGyroOffset(XGYROOFFSET); accelgyro.setYGyroOffset(YGYROOFFSET); accelgyro.setZGyroOffset(ZGYROOFFSET); SERIAL_OUT.print(accelgyro.getXAccelOffset()); SERIAL_OUT.print("\t"); // SERIAL_OUT.print(accelgyro.getYAccelOffset()); SERIAL_OUT.print("\t"); // SERIAL_OUT.print(accelgyro.getZAccelOffset()); SERIAL_OUT.print("\t"); // SERIAL_OUT.print(accelgyro.getXGyroOffset()); SERIAL_OUT.print("\t"); // SERIAL_OUT.print(accelgyro.getYGyroOffset()); SERIAL_OUT.print("\t"); // SERIAL_OUT.print(accelgyro.getZGyroOffset()); SERIAL_OUT.print("\t"); // SERIAL_OUT.print("\n"); SERIAL_OUT.println(F("Enabling FIFO...")); accelgyro.setFIFOEnabled(true); accelgyro.setZGyroFIFOEnabled(true); accelgyro.setXGyroFIFOEnabled(false); accelgyro.setYGyroFIFOEnabled(false); accelgyro.setAccelFIFOEnabled(false); SERIAL_OUT.print("Z axis enabled?\t"); SERIAL_OUT.println(accelgyro.getZGyroFIFOEnabled()); SERIAL_OUT.print("x axis enabled?\t"); SERIAL_OUT.println(accelgyro.getXGyroFIFOEnabled()); SERIAL_OUT.print("y axis enabled?\t"); SERIAL_OUT.println(accelgyro.getYGyroFIFOEnabled()); SERIAL_OUT.print("accel enabled?\t"); SERIAL_OUT.println(accelgyro.getAccelFIFOEnabled()); accelgyro.resetFIFO(); return ; }
uint8_t initializeMPU(int16_t *accelOffsetX, int16_t *accelOffsetY,int16_t *accelOffsetZ, int16_t *currAccelX,int16_t *currAccelY,int16_t *currAccelZ){ /*MUST DECIDE WHETHER TO USE*/ /*ERROR CODES: 1: no connection of MPU in hardware 2: no DMP initialization */ uint8_t initErrorCode=0; // ================================================================ // === INITIAL SETUP === // ================================================================ // CONNECT DEVICE TO I2C BUS // join I2C bus (I2Cdev library doesn't do this automatically) Wire.begin(); // Serial.begin(38400); // while (!Serial); // // // initialize device // Serial.println(F("Initializing I2C devices...")); mpu.initialize(); // TEST MPU CONNECTION // // verify connection if( !(mpu.testConnection()) ){ /*Added MPU connection check*/ initErrorCode=1; return initErrorCode; } // Serial.println(F("Testing device connections...")); // Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); // wait for ready // Serial.println(F("\nSend any character to begin DMP programming and demo: ")); // while (Serial.available() && Serial.read()); // empty buffer // while (!Serial.available()); // wait for data // while (Serial.available() && Serial.read()); // empty buffer again // CONFIGURE MPU SETTINGS //Low pass filtering //mpu.setDLPFMode(1); //Set tap detection on XYZ axes /* dmp_set_tap_thresh(1,500); dmp_set_tap_thresh(2,500); dmp_set_tap_thresh(4,500); */ // LOAD AND CONFIGURE THE DMP uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) // Serial.println(F("Initializing DMP...")); devStatus=mpu.dmpInitialize(); // 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 2)...")); attachInterrupt(0, dmpDataReady, RISING); //mpuIntStatus = mpu.getIntStatus(); // Serial.println("MPU int status:"); // Serial.println(mpuIntStatus); // set our DMP Ready flag so function knows it's okay to use it // Serial.println(F("DMP ready!")); dmpReady = true; // get expected DMP packet size for later comparison packetSize = mpu.dmpGetFIFOPacketSize(); } else { /*Failed to intialize dmp*/ // 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(")")); initErrorCode=2; return initErrorCode; } // RUN CALIBRATION // According to manual, user should place the cube on table for 10 seconds to allow for accelerometer to calibrate // Accelerometer calibration: apply offsets int16_t tempOffsetX=0; /*CHANGED TO INT16*/ int16_t tempOffsetY=0; int16_t tempOffsetZ=0; //Get offset as average over 10 seconds uint8_t count=0; *accelOffsetX=0; *accelOffsetY=0; *accelOffsetZ=0; unsigned long startTime=millis(); while ((millis()-startTime)<10000){ mpuMonitor(currAccelX,currAccelY,currAccelZ); /*Class call added*/ tempOffsetX=(tempOffsetX+*(currAccelX)/2048); tempOffsetY=(tempOffsetY+*(currAccelY)/2048); tempOffsetZ=(tempOffsetZ+*(currAccelZ)/2048); count++; } tempOffsetX=2048*tempOffsetX/count; tempOffsetY=2048*tempOffsetY/count; tempOffsetZ=2048*tempOffsetZ/count; *accelOffsetX=tempOffsetX; *accelOffsetY=tempOffsetY; *accelOffsetZ=tempOffsetZ; //pinMode(LED_PIN,output); /*No more LEDs for failure checks*/ return initErrorCode; }
int main() { // MPU6050 object "MPU6050.h" MPU6050 accelgyro; // Kalman filter Object "Kalman.h" Kalman kalman; // Xbee serial baudrate xBee.baud(38400); pc.baud(9600); // Initialize timers Timer timer, code, encTimer; // Start timers timer.start(); code.start(); encTimer.start(); // Reset timer values timer.reset(); code.reset(); encTimer.reset(); //Encoder 1 interrupts enc1a.rise(&incrementEnc1a); enc1b.rise(&incrementEnc1b); enc1a.fall(&setEnc1aFall); enc1b.fall(&setEnc1bFall); enc2a.rise(&incrementEnc2a); enc2b.rise(&incrementEnc2b); enc2a.fall(&setEnc2aFall); enc2b.fall(&setEnc2bFall); // Debug leds myled1 = 0; myled2 = 0; myled3 = 0; // Encoder 1 initializations newTime =0; oldTime = 0; lastEncTime = 0; enc1Speed = 0; enc2Speed = 0; // MPU6050 initializations accelgyro.initialize(); accelgyro.setFullScaleGyroRange(0); accelgyro.setFullScaleAccelRange(0); // Initialize MotorShield object shield.init(); float measuredTheta , measuredRate, newTheta,calcRate; float position= 0, velocity = 0, lastPosition = 0, lastVelocity =0; float angleOffset = 0, positionOffset = 0,lastAngleoffset = 0; // Position control constants, if necessary float zoneA = 16000.0f, zoneB = 8000.0f, zoneC = 2000.0f; float multiplier = 1.0f; float zoneAscale = 600*2*multiplier, zoneBscale = 800*2*multiplier, zoneCscale = 1000*2*multiplier, zoneDscale = 1500*2*multiplier, velocityScale = 60*2*multiplier; // Serial communication buffer char buffer[40]; int i, strSize; // Control parameters float k0,k1,k2,k3,tref; float x, dotx, deltaX, deltaT, lastX = 0; // Helper variables float waittime , u, diff, dt; float error = 0,lastError = 0; int counter = 0; float pTerm = 0,dTerm = 0,iTerm = 0; while(1) { /////////////////////////////////////////// // Read serial data and update constants // /////////////////////////////////////////// i = 0; char a; while(pc.readable()){ a = pc.getc(); buffer[i++] = a; printf("%c\n", a ); myled1 = 1; wait(0.001); } strSize = i; string receive(buffer,strSize); // Changes from char to string if(strSize > 0){ printf("%s\n", receive); assignGainsFromString(&k[0], &k[1], &k[2], &k[3], &k[4],receive); } // Below is an attempt to control the robot position, // by dividing it into "zones" and changing the angle accordingly. // ///////////////////////////// // Generate encoder offset // ///////////////////////////// // position = (float)enc2total; // positionOffset = position; // //if((encTimer.read_us() - lastEncTime) > 0.0f ) { // every 100 ms // float sign = 0; // if(positionOffset > 0) sign= 1; // else sign = -1; // if(abs(positionOffset) > zoneA) angleOffset += 1.0f/zoneAscale*positionOffset; // else if(abs(positionOffset) > zoneB) angleOffset += 1.0f/zoneBscale*positionOffset; // else if(abs(positionOffset) > zoneC) angleOffset += 1.0f/zoneCscale*positionOffset; // else angleOffset += positionOffset/zoneDscale; // printf("angleOffset: %f, positionoffset: %f\n", angleOffset, positionOffset ); // // Estimate velocity // // // velocity = (position - lastPosition); // lastPosition = position; // angleOffset += velocity/velocityScale; // angleOffset = constrain(angleOffset,-10, 10); // lastAngleoffset = angleOffset; // //} // angleOffset = constrain(angleOffset,lastAngleoffset - 1, lastAngleoffset + 1); timer.reset(); /////////////////////////// // Get gyro/accel values // /////////////////////////// accelgyro.getAcceleration(&ax,&ay,&az); measuredRate = accelgyro.getRotationX()*1.0/131.0f; // Units depend on config. Right now 250o/s measuredTheta = -atan(1.0*ay/az); measuredTheta = measuredTheta*180/PI; // measured in degrees /////////////////// // Kalman Filter // /////////////////// dt = (double)(code.read_us() - oldTime)/1000000.0f; newTheta = kalman.getAngle(measuredTheta, -measuredRate, dt); //DEBUG: printf("%g \n", (double)(code.read_us() - oldTime)/1000000.0f); oldTime = code.read_us(); ////////////////// // Control loop // ////////////////// // Set control variable to zero u = 0; // Extract constants from k vector, which has the serial readings. float kp = k[0]; float ki = k[1]; float kd = k[2]; tref = k[3] - angleOffset; waittime = k[4]; if(newTheta >= 50 || newTheta <= -50){ u = 0; }else{ // Define error term error = newTheta - tref; // Proportional term pTerm = kp*error; //Integral term iTerm += ki*error*dt*100.0f; // Prevent integration windup: if(iTerm >= 100) iTerm = 100; else if (iTerm <= -100) iTerm = -100; u = -(iTerm + pTerm); // Calculated derivative based on smoothened angle. // There are two other sources for the angle here: kalman.getRate(); and measuredRate. calcRate = -(error-lastError)/dt; // Derivative term if(kd != 0) dTerm = kd*calcRate/100.0f; lastError = error; u += dTerm; // Correct for dead zone --- Did not have successful results but I'll leave it here. // int deadzone = 20; // if(u < -deadzone) u = u + deadzone; // else if(u > deadzone) u = u - deadzone; // else u = 0; // // Include saturation u = constrain(u,-400,400); // Flash LED to indicate loop if(counter % 50 == 0){ myled3 = !myled3; counter = 0; } counter++; } lastError = error; // update angle if(counter % 50 == 0){ myled3 = !myled3; // xBee.printf("%f,%f\n", newTheta,u); counter = 0; } // Set motor speed shield.setM1Speed(-(int)u); shield.setM2Speed((int)u); // DEBUG over serial port. Use with MATLAB program "serialPlot.m" to plot these results. printf("%f,%f,%f\n", measuredTheta, newTheta , u); // Hold the timer until desired sampling time is reached. while(timer.read_us() < waittime*1000); // Turn off serial transmission LED myled1 = 0; } }
void system_init() { DEBUG_PRINTF(V_MESSAGE, "Initializing WirePi.\n"); wiringPiSetup() ; pinMode(LED, OUTPUT); LED_ON; // Turn red led ON on initialization. DEBUG_PRINTF(V_MESSAGE, "Initializing timers.\n"); init_photo_timer(); if((operation_type == OPERATION_A) || (operation_type == OPERATION_B)) { init_accelgyro_timer(); } init_operation_timer(); init_led_timer(); DEBUG_PRINTF(V_MESSAGE, "Initializing accelgyro.\n"); accelgyro.initialize(); if(operation_type == OPERATION_A) // PLAN A { accelgyro_handler = &accelgyro_handler_planA; accelgyro.getAcceleration(&x, &y,&z); accel_low.x = accel_low.x * gravity_alpha + x * (1 - gravity_alpha); accel_low.y = accel_low.y * gravity_alpha + y * (1 - gravity_alpha); accel_low.z = accel_low.z * gravity_alpha + z * (1 - gravity_alpha); last_angle = accel_low.getAngleTo(gravity); max_angle = last_angle; start_accelgyro_timer(0, ACCELGYRO_TICK); } else if(operation_type == OPERATION_B) // PLAN B { accelgyro_handler = &accelgyro_handler_planB; start_accelgyro_timer(0, ACCELGYRO_TICK); } DEBUG_PRINTF(V_MESSAGE, "Initializing TCP socket.\n"); socket_tcp = TCP_Socket(host_ip, socket_port); DEBUG_PRINTF(V_MESSAGE, "Starting Timers.\n"); start_led_timer(TIMER_LED_TICK, 0); DEBUG_PRINTF(V_MESSAGE, "Initialization sleep!\n"); sleep(INITIAL_DELAY); DEBUG_PRINTF(V_MESSAGE, "System initialized!\n"); if((operation_test == TEST_NO_TCP) || (operation_test == FULL_TEST)) { DEBUG_PRINTF(V_MESSAGE, "System test!\n"); if(system_test() == false) { signalize(ERROR); DEBUG_PRINTF(V_ERROR, "Failed on System Test!\n"); while(1); } else { DEBUG_PRINTF(V_MESSAGE, "Passed on system test!\n"); } } return; }