Hello buddys i have a sketch for Air mouse that i downloader and works prety well but since i implemented the joystick Code part Its givign fifo overflow! So i added a TWBR = 6, 12 and 24 and fifo overflow stopped but on all of them the cursor its jittering a bit....
I have the mpu on a pro micro...
Can you see something wrong here?
I increased the sensitivity coz i need máximum precision
Thanks!!
Part 1: (coz 900 limit words)
]
void setup() {
// join I2C bus (I2Cdev library doesn't do this automatically)
Wire.begin();
TWBR = 0;
Mouse.begin();
Keyboard.begin();
// initialize serial communication
Serial.begin(38400);
// 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(F("Initializing I2C devices..."));
mpu.initialize();
// load and configure the DMP
Serial.println(F("Initializing DMP..."));
devStatus = mpu.dmpInitialize();
// calibration
// supply your own gyro offsets here, scaled for min sensitivity
// mpu.setXGyroOffset(164);
// mpu.setYGyroOffset(-151);
// mpu.setZGyroOffset(-16);
// mpu.setXAccelOffset(-2174);
// mpu.setYAccelOffset(-162);
// mpu.setZAccelOffset(785);
// 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;
// Set the full scale range of the gyro
uint8_t FS_SEL = 0;
// mpu.setFullScaleGyroRange(FS_SEL);
// get default full scale value of gyro - may have changed from default
// function call returns values between 0 and 3
uint8_t READ_FS_SEL = mpu.getFullScaleGyroRange();
Serial.print("FS_SEL = ");
Serial.println(READ_FS_SEL);
GYRO_FACTOR = 131.0/(FS_SEL + 1);
// get default full scale value of accelerometer - may not be default value.
// Accelerometer scale factor doesn't reall matter as it divides out
uint8_t READ_AFS_SEL = mpu.getFullScaleAccelRange();
Serial.print("AFS_SEL = ");
Serial.println(READ_AFS_SEL);
//ACCEL_FACTOR = 16384.0/(READ_AFS_SEL + 1);
// Set the full scale range of the accelerometer
//uint8_t AFS_SEL = 0;
//mpu.setFullScaleAccelRange(AFS_SEL);
// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();
// get calibration values for sensors
calibrate_sensors();
set_last_read_angle_data(millis(), 0, 0, 0, 0, 0, 0);
pinMode(tcrtDetectorPin, INPUT);
pinMode(tcrtEmitterPin, OUTPUT);
// pinMode(buttonPin, INPUT);
// digitalWrite (buttonPin, HIGH);
pinMode(mouseButton, INPUT_PULLUP);
pinMode(buttonPin2, INPUT_PULLUP);
// pinMode(buttonPin2, INPUT);
// digitalWrite (buttonPin2, HIGH);
// pinMode(buttonPin3, INPUT);
// digitalWrite (buttonPin3, HIGH);
pinMode(Pul_bloquear_GYRO, INPUT_PULLUP);
}
// ================================================================
// === MAIN PROGRAM LOOP ===
// ================================================================
void loop() {
{
int clickState = digitalRead(mouseButton);
{
// if the mouse button is pressed:
if (clickState == HIGH) {
// if the mouse is not pressed, press it:
//if (!Mouse.isPressed(MOUSE_RIGHT)) {
Mouse.release(MOUSE_RIGHT);
// }
} else { // else the mouse button is not pressed:
// if the mouse is pressed, release it:
// if (Mouse.isPressed(MOUSE_RIGHT)) {
Mouse.press(MOUSE_RIGHT);
// }
}
// a delay so the mouse does not move too fast:
// delay(responseDelay);
}
int click2State = digitalRead(buttonPin2);
{
// if the mouse button is pressed:
if (click2State == HIGH) {
// if the mouse is not pressed, press it:
//if (!Mouse.isPressed(MOUSE_RIGHT)) {
Mouse.release(MOUSE_MIDDLE);
// }
} else { // else the mouse button is not pressed:
// if the mouse is pressed, release it:
// if (Mouse.isPressed(MOUSE_RIGHT)) {
Mouse.press(MOUSE_MIDDLE);
// }
}
// a delay so the mouse does not move too fast:
// delay(responseDelay);
}
digitalWrite(tcrtEmitterPin, HIGH);
//delay(1);
a = analogRead (tcrtDetectorPin);
digitalWrite(tcrtEmitterPin, LOW);
//delay(1);
b = analogRead(tcrtDetectorPin);
c = a - b;
if (a < 775) {
Mouse.press(MOUSE_LEFT);
}
else {
if (a > 775)
Mouse.release(MOUSE_LEFT);
}
}
const float RADIANS_TO_DEGREES = 57.2958; //180/3.14159
unsigned long t_now = millis();
// wait for MPU interrupt or extra packet(s) available
while (!mpuInterrupt && fifoCount < packetSize) {
// Keep calculating the values of the complementary filter angles for comparison with DMP here
// Read the raw accel/gyro values from the MPU-6050
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// Get time of last raw data read
unsigned long t_now = millis();
// Remove offsets and scale gyro data
float gyro_x = (gx - base_x_gyro)/GYRO_FACTOR;
float gyro_y = (gy - base_y_gyro)/GYRO_FACTOR;
float gyro_z = (gz - base_z_gyro)/GYRO_FACTOR;
float accel_x = ax; // - base_x_accel;
float accel_y = ay; // - base_y_accel;
float accel_z = az; // - base_z_accel;
float accel_angle_y = atan(-1*accel_x/sqrt(pow(accel_y,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES;
float accel_angle_x = atan(accel_y/sqrt(pow(accel_x,2) + pow(accel_z,2)))*RADIANS_TO_DEGREES;
float accel_angle_z = 0;
// Compute the (filtered) gyro angles
float dt =(t_now - get_last_time())/1000.0;
float gyro_angle_x = gyro_x*dt + get_last_x_angle();
float gyro_angle_y = gyro_y*dt + get_last_y_angle();
float gyro_angle_z = gyro_z*dt + get_last_z_angle();
// Compute the drifting gyro angles
float unfiltered_gyro_angle_x = gyro_x*dt + get_last_gyro_x_angle();
float unfiltered_gyro_angle_y = gyro_y*dt + get_last_gyro_y_angle();
float unfiltered_gyro_angle_z = gyro_z*dt + get_last_gyro_z_angle();
// Apply the complementary filter to figure out the change in angle - choice of alpha is
// estimated now. Alpha depends on the sampling rate...
const float alpha = 0.96;
float angle_x = alpha*gyro_angle_x + (1.0 - alpha)*accel_angle_x;
float angle_y = alpha*gyro_angle_y + (1.0 - alpha)*accel_angle_y;
float angle_z = gyro_angle_z; //Accelerometer doesn't give z-angle
// Update the saved data with the latest values
set_last_read_angle_data(t_now, angle_x, angle_y, angle_z, unfiltered_gyro_angle_x, unfiltered_gyro_angle_y, unfiltered_gyro_angle_z);
}
// 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;
// Obtain Euler angles from buffer
//mpu.dmpGetQuaternion(&q, fifoBuffer);
//mpu.dmpGetEuler(euler, &q);
// Obtain YPR angles from buffer
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
/*Serial.print("DMP:");
Serial.print(ypr[2]*RADIANS_TO_DEGREES, 2); // Serial.println(1.23456, 2) gives "1.23"
Serial.print(":");
Serial.print(-ypr[1]*RADIANS_TO_DEGREES, 2);
Serial.print(":");
Serial.println(ypr[0]*RADIANS_TO_DEGREES, 2);*/
//Mouse.move(-ypr[2]*RADIANS_TO_DEGREES, -ypr[1]*RADIANS_TO_DEGREES, 0);
float xInstruction = ypr[0]*RADIANS_TO_DEGREES;
float yInstruction;
if (MPUorientation == 1 || MPUorientation == 3){
yInstruction = ypr[2]*RADIANS_TO_DEGREES;
}else if (MPUorientation == 2 || MPUorientation == 4){
yInstruction = ypr[1]*RADIANS_TO_DEGREES;
}
float newMousePosX;
float newMousePosY;
if (MPUorientation == 1 || MPUorientation == 4){
newMousePosX = xInstruction - prevInstructionX;
newMousePosY = yInstruction - prevInstructionY;
}else if (MPUorientation == 2 || MPUorientation == 3){
newMousePosX = xInstruction - prevInstructionX;
newMousePosY = -(yInstruction - prevInstructionY);
}
if (digitalRead(Pul_bloquear_GYRO) == 1)
{
Mouse.move(newMousePosX*mouseSensitivity, newMousePosY*mouseSensitivity, 0);
}
prevInstructionX = xInstruction;
prevInstructionY = yInstruction;
}