CCCPaste

"MPU6050 PPM" rev_12

/********* Pleasedontcode.com **********

	Pleasedontcode thanks you for automatic code generation! Enjoy your code!

	- Terms and Conditions:
	You have a non-exclusive, revocable, worldwide, royalty-free license
	for personal and commercial use. Attribution is optional; modifications
	are allowed, but you're responsible for code maintenance. We're not
	liable for any loss or damage. For full terms,
	please visit pleasedontcode.com/termsandconditions.

	- Project: "MPU6050 PPM"
	- Source Code NOT compiled for: Arduino Mega
	- Source Code created on: 2024-06-22 05:50:04

********* Pleasedontcode.com **********/

/****** SYSTEM REQUIREMENTS *****/
/****** SYSTEM REQUIREMENT 1 *****/
	/* convert mpu6050 data to ppm and send out for head */
	/* tracking */
/****** END SYSTEM REQUIREMENTS *****/

/****** DEFINITION OF LIBRARIES *****/
#include 
#include   //http://github.com/schinken/PPMEncoder
#include   //https://github.com/jrowberg/i2cdevlib

/****** FUNCTION PROTOTYPES *****/
void setup(void);
void loop(void);

/***** DEFINITION OF DIGITAL INPUT PINS *****/
const uint8_t gyro_MPU6050_Interrupt_PIN_D2 = 2;

/***** DEFINITION OF I2C PINS *****/
const uint8_t gyro_MPU6050_I2C_PIN_SDA_D20 = 20;
const uint8_t gyro_MPU6050_I2C_PIN_SCL_D21 = 21;
const uint8_t gyro_MPU6050_I2C_SLAVE_ADDRESS = 104;

/****** DEFINITION OF LIBRARIES CLASS INSTANCES*****/
PPMEncoder ppmEncoder;  // Instantiate the PPMEncoder object
MPU6050 mpu;  // Instantiate the MPU6050 object

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

Quaternion q;           // [w, x, y, z]         quaternion container
VectorFloat gravity;    // [x, y, z]            gravity vector
float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

volatile bool mpuInterrupt = false;  // Indicates whether MPU interrupt pin has gone high

void dmpDataReady() {
    mpuInterrupt = true;
}

void setup(void) {
  // Initialize I2C
  Wire.begin();
  Wire.setClock(400000);  // 400kHz I2C clock

  // Initialize serial communication
  Serial.begin(115200);
  while (!Serial);

  // Initialize MPU6050
  Serial.println(F("Initializing I2C devices..."));
  mpu.initialize();
  pinMode(gyro_MPU6050_Interrupt_PIN_D2, INPUT);

  // 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(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) {
      // Calibration Time: generate offsets and calibrate our MPU6050
      mpu.CalibrateAccel(6);
      mpu.CalibrateGyro(6);
      mpu.PrintActiveOffsets();
      Serial.println(F("Enabling DMP..."));
      mpu.setDMPEnabled(true);

      // Enable Arduino interrupt detection
      Serial.print(F("Enabling interrupt detection (Arduino external interrupt "));
      Serial.print(digitalPinToInterrupt(gyro_MPU6050_Interrupt_PIN_D2));
      Serial.println(F(")..."));
      attachInterrupt(digitalPinToInterrupt(gyro_MPU6050_Interrupt_PIN_D2), dmpDataReady, RISING);
      mpuIntStatus = mpu.getIntStatus();

      // Set our DMP ready flag
      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(")"));
  }

  // Initialize the PPM encoder on pin 10
  ppmEncoder.begin(10);
}

void loop(void) {
  // If DMP is not ready, exit
  if (!dmpReady) return;

  // Wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt && fifoCount < packetSize) {
      // Do nothing
  }

  // 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 Yaw, Pitch, and Roll values
      mpu.dmpGetQuaternion(&q, fifoBuffer);
      mpu.dmpGetGravity(&gravity, &q);
      mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);

      // Convert Yaw, Pitch, and Roll to PPM signals
      int yawPPM = map(ypr[0] * 180/M_PI, -180, 180, PPMEncoder::MIN, PPMEncoder::MAX);
      int pitchPPM = map(ypr[1] * 180/M_PI, -180, 180, PPMEncoder::MIN, PPMEncoder::MAX);
      int rollPPM = map(ypr[2] * 180/M_PI, -180, 180, PPMEncoder::MIN, PPMEncoder::MAX);

      // Set PPM channels
      ppmEncoder.setChannel(0, yawPPM);
      ppmEncoder.setChannel(1, pitchPPM);
      ppmEncoder.setChannel(2, rollPPM);

      // Print Yaw, Pitch, and Roll values for debugging
      Serial.print("ypr\t");
      Serial.print(ypr[0] * 180/M_PI);
      Serial.print("\t");
      Serial.print(ypr[1] * 180/M_PI);
      Serial.print("\t");
      Serial.println(ypr[2] * 180/M_PI);
  }
}

/* END CODE */