/********* 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 compiled for: Arduino Mega - Source Code created on: 2024-06-21 07:46:57 ********* Pleasedontcode.com **********/ /****** SYSTEM REQUIREMENTS *****/ /****** SYSTEM REQUIREMENT 1 *****/ /* Create a head tracking system with MPU6050 */ /* gyroscope (I2C: SDA D20, SCL D21, Interrupt D2) */ /* and PPMEncoder library. Ensure accurate data */ /* capture and encoding for real-time head movement */ /* tracking. Send out data in ppm format. */ /****** SYSTEM REQUIREMENT 2 *****/ /* when i press the push button, all gyro axis get */ /* set to center so all channels are centered with it */ /****** END SYSTEM REQUIREMENTS *****/ /****** DEFINITION OF LIBRARIES *****/ #include #include //https://github.com/jrowberg/i2cdevlib #include "PPMEncoder.h" //https://github.com/schinken/PPMEncoder /****** FUNCTION PROTOTYPES *****/ void setup(void); void loop(void); void dmpDataReady(void); /***** DEFINITION OF DIGITAL INPUT PINS *****/ const uint8_t gyro_MPU6050_Interrupt_PIN_D2 = 2; const uint8_t centerbutton_PushButton_PIN_D3 = 3; const uint8_t ppm_Output_PIN_D10 = 10; /***** 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*****/ MPU6050 mpu; /****** GLOBAL VARIABLES *****/ bool dmpReady = false; uint8_t mpuIntStatus, devStatus, fifoBuffer[64]; uint16_t packetSize, fifoCount; Quaternion q; VectorFloat gravity; float ypr[3]; volatile bool mpuInterrupt = false; /****** INTERRUPT HANDLER *****/ void dmpDataReady() { mpuInterrupt = true; } void setup(void) { // put your setup code here, to run once: pinMode(gyro_MPU6050_Interrupt_PIN_D2, INPUT); pinMode(centerbutton_PushButton_PIN_D3, INPUT_PULLUP); #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.begin(); Wire.setClock(400000); #endif Serial.begin(115200); while (!Serial); Serial.println(F("Initializing I2C devices...")); mpu.initialize(); pinMode(gyro_MPU6050_Interrupt_PIN_D2, INPUT); Serial.println(F("Testing device connections...")); Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed")); Serial.println(F("\nSend any character to begin DMP programming and demo: ")); while (!Serial.available()); while (Serial.available() && Serial.read()); Serial.println(F("Initializing DMP...")); devStatus = mpu.dmpInitialize(); mpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1788); if (devStatus == 0) { mpu.CalibrateAccel(6); mpu.CalibrateGyro(6); mpu.PrintActiveOffsets(); Serial.println(F("Enabling DMP...")); mpu.setDMPEnabled(true); 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(); Serial.println(F("DMP ready! Waiting for first interrupt...")); dmpReady = true; packetSize = mpu.dmpGetFIFOPacketSize(); } else { Serial.print(F("DMP Initialization failed (code ")); Serial.print(devStatus); Serial.println(F(")")); } // Initialize PPM encoder ppmEncoder.begin(ppm_Output_PIN_D10); } void loop(void) { // put your main code here, to run repeatedly: if (!dmpReady) return; if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer)) { mpu.dmpGetQuaternion(&q, fifoBuffer); mpu.dmpGetGravity(&gravity, &q); mpu.dmpGetYawPitchRoll(ypr, &q, &gravity); 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); // Map Yaw, Pitch, Roll to PPM channels ppmEncoder.setChannel(0, map(ypr[0] * 180/M_PI, -180, 180, PPMEncoder::MIN, PPMEncoder::MAX)); ppmEncoder.setChannel(1, map(ypr[1] * 180/M_PI, -90, 90, PPMEncoder::MIN, PPMEncoder::MAX)); ppmEncoder.setChannel(2, map(ypr[2] * 180/M_PI, -90, 90, PPMEncoder::MIN, PPMEncoder::MAX)); // Check if the center button is pressed if (digitalRead(centerbutton_PushButton_PIN_D3) == LOW) { // Center all gyro axis mpu.setXGyroOffset(0); mpu.setYGyroOffset(0); mpu.setZGyroOffset(0); } } } /* END CODE */