Accelerometer mouse not acting like a mouse

Hi

I’m trying to use my Pro Micro MPU9250 as a hands free mouse. I based it on the Adafruit sketch here

It compiles fine, I get the sensor data, but no mouse function.

/*

*/
#include <Mouse.h>
#include <Wire.h>
#include <MPU9250.h>

MPU9250 IMU(Wire,0x68);
float axb = IMU.getAccelBiasX_mss();
float ayb = IMU.getAccelBiasY_mss();
int readSensor();
float ax = IMU.getAccelX_mss();
float ay = IMU.getAccelY_mss();

const int XACCEL_MIN = 0.1;             
const int XACCEL_MAX = 8.0;                           
const int XMOUSE_RANGE = 25.0;  
const int XMOUSE_SCALE = 1; 

const int YACCEL_MIN = XACCEL_MIN;
const int YACCEL_MAX = XACCEL_MAX;
const int YMOUSE_RANGE = XMOUSE_RANGE;
const int YMOUSE_SCALE = 1;

const int FLIP_AXES = true;

float lerp(float x, float x0, float x1, float y0, float y1) {
  if (x <= x0) {
    return y0;
  }
  else if (x >= x1) {
    return y1;
  }
  return y0 + (y1-y0)*((x-x0)/(x1-x0));
}

void setup() {
  int status;
  Wire.begin();
  IMU.begin();
  Serial.begin(115200);
  IMU.setAccelRange(MPU9250::ACCEL_RANGE_8G);
  IMU.calibrateAccel();
  float getAccelBiasX_mss();
  float getAccelBiasY_mss();
  float getAccelScaleFactorX();
  float getAccelScaleFactorY();
  

  void setAccelCalX(float bias, float scaleFactor);
  void setAccelCalY(float bias, float scaleFactor);
  Serial.print("Status: ");
  Serial.println(status);
  Mouse.begin();
}

void loop() {
  IMU.readSensor();
  Serial.print("Ax\t");
  Serial.println(IMU.getAccelX_mss(),6);
  Serial.println("\t");
  Serial.print("Ay\t");
  Serial.println(IMU.getAccelY_mss(),6);
  
  delay(2000);
  
  float x_mag = abs(ax);
  float x_mouse = lerp(x_mag, XACCEL_MIN, XACCEL_MAX, 0.0, XMOUSE_RANGE);
  float y_mag = abs(ay);
  float y_mouse = lerp(y_mag, YACCEL_MIN, YACCEL_MAX, 0.0, YMOUSE_RANGE);
  
    if (ax < 0) {
    x_mouse *= -1.0;
  }
  if (ay < 0) {
    y_mouse *= -1.0;
  }
 
  x_mouse = floor(x_mouse*XMOUSE_SCALE);
  y_mouse = floor(y_mouse*YMOUSE_SCALE);
  

  if (!FLIP_AXES) {
    Mouse.move((int)x_mouse, (int)y_mouse, 0);
  }
  else {
    Mouse.move((int)y_mouse, (int)x_mouse, 0);
  }

}

Have you tried with simple sketch with Mouse only to make sure your PC recognize it?

I have, it does recognize it

Now try printing out "x_mouse" and "y_mouse" to make sure that they are not both 0.

  delay(2000);

Looks like a very lazy mouse that lays down on the job 99.9% of the time.

x and y are both reading 0.000000

Feargaill:
x and y are both reading 0.000000

const int XACCEL_MIN = 0.1;             
const int XACCEL_MAX = 8.0;                           
const int XMOUSE_RANGE = 25.0;  
const int XMOUSE_SCALE = 1;

Some are not ints

Do you think switching const int to #define will help?

Now you need to go through what we call "debugging" to see why your program is not doing what you are expected. Generally, you want to print out a variable before and after it is modified. Most of the time you will see the problem.

float axb = IMU.getAccelBiasX_mss();
float ayb = IMU.getAccelBiasY_mss();
int readSensor();
float ax = IMU.getAccelX_mss();
float ay = IMU.getAccelY_mss();

It is pointless to call methods in the MPU9250 class before you have called the begin() method on an instance of the class.

The function prototype there is useless, too.

  float getAccelBiasX_mss();
  float getAccelBiasY_mss();
  float getAccelScaleFactorX();
  float getAccelScaleFactorY();

  void setAccelCalX(float bias, float scaleFactor);
  void setAccelCalY(float bias, float scaleFactor);

Why are you defining function prototypes in setup()?

PaulS:

float axb = IMU.getAccelBiasX_mss();

float ayb = IMU.getAccelBiasY_mss();
int readSensor();
float ax = IMU.getAccelX_mss();
float ay = IMU.getAccelY_mss();



It is pointless to call methods in the MPU9250 class before you have called the begin() method on an instance of the class.

The function prototype there is useless, too.



float getAccelBiasX_mss();
  float getAccelBiasY_mss();
  float getAccelScaleFactorX();
  float getAccelScaleFactorY();

void setAccelCalX(float bias, float scaleFactor);
  void setAccelCalY(float bias, float scaleFactor);



Why are you defining function prototypes in setup()?

For calibration that I never did

The real problem is that you are trying to run before learning to crawl. Start with the simpler examples that come with Arduino; learn the language and special features of the board before jumping in so deeply.

For example, this line of code declares and sets XACCEL_MIN to be the integer zero, which is probably not what you intended.

const int XACCEL_MIN = 0.1;

Use float variables for fractional values.

jremington you're probably right, I'm trying.

I’m trying to calibrate my mpu and it show some axes are not registering, am I doing something wrong? Could it be I’m using a 6050 library on an 9250? I attached a screenshot of the monitor.

/*
 *  Mandatory includes
 */
#include <Arduino.h>
#include <TinyMPU6050.h>

/*
 *  Constructing MPU-6050
 */
MPU6050 mpu (Wire);

/*
 *  Method that prints everything
 */
void PrintGets () {
  // Shows offsets
  Serial.println("--- Offsets:");
  Serial.print("AccX Offset = ");
  Serial.println(mpu.GetAccXOffset());
  Serial.print("AccY Offset = ");
  Serial.println(mpu.GetAccYOffset());
  Serial.print("AccZ Offset = ");
  Serial.println(mpu.GetAccZOffset());
  Serial.print("GyroX Offset = ");
  Serial.println(mpu.GetGyroXOffset());
  Serial.print("GyroY Offset = ");
  Serial.println(mpu.GetGyroYOffset());
  Serial.print("GyroZ Offset = ");
  Serial.println(mpu.GetGyroZOffset());
  // Shows raw data
  Serial.println("--- Raw data:");
  Serial.print("Raw AccX = ");
  Serial.println(mpu.GetRawAccX());
  Serial.print("Raw AccY = ");
  Serial.println(mpu.GetRawAccY());
  Serial.print("Raw AccZ = ");
  Serial.println(mpu.GetRawAccZ());
  Serial.print("Raw GyroX = ");
  Serial.println(mpu.GetRawGyroX());
  Serial.print("Raw GyroY = ");
  Serial.println(mpu.GetRawGyroY());
  Serial.print("Raw GyroZ = ");
  Serial.println(mpu.GetRawGyroZ());
  // Show readable data
  Serial.println("--- Readable data:");
  Serial.print("AccX = ");
  Serial.print(mpu.GetAccX());
  Serial.println(" m/s²");
  Serial.print("AccY = ");
  Serial.print(mpu.GetAccY());
  Serial.println(" m/s²");
  Serial.print("AccZ = ");
  Serial.print(mpu.GetAccZ());
  Serial.println(" m/s²");
  Serial.print("GyroX = ");
  Serial.print(mpu.GetGyroX());
  Serial.println(" degrees/second");
  Serial.print("GyroY = ");
  Serial.print(mpu.GetGyroY());
  Serial.println(" degrees/second");
  Serial.print("GyroZ = ");
  Serial.print(mpu.GetGyroZ());
  Serial.println(" degrees/second");
  // Show angles based on accelerometer only
  Serial.println("--- Accel angles:");
  Serial.print("AccelAngX = ");
  Serial.println(mpu.GetAngAccX());
  Serial.print("AccelAngY = ");
  Serial.println(mpu.GetAngAccY());
  Serial.print("AccelAngZ = ");
  Serial.println(mpu.GetAngAccZ());
  // Show angles based on gyroscope only
  Serial.println("--- Gyro angles:");
  Serial.print("GyroAngX = ");
  Serial.println(mpu.GetAngGyroX());
  Serial.print("GyroAngY = ");
  Serial.println(mpu.GetAngGyroY());
  Serial.print("GyroAngZ = ");
  Serial.println(mpu.GetAngGyroZ());
  // Show angles based on both gyroscope and accelerometer
  Serial.println("--- Filtered angles:");
  Serial.print("FilteredAngX = ");
  Serial.println(mpu.GetAngX());
  Serial.print("FilteredAngY = ");
  Serial.println(mpu.GetAngY());
  Serial.print("FilteredAngZ = ");
  Serial.println(mpu.GetAngZ());
  // Show filter coefficients
  Serial.println("--- Angle filter coefficients:");
  Serial.print("Accelerometer percentage = ");
  Serial.print(mpu.GetFilterAccCoeff());
  Serial.println('%');
  Serial.print("Gyroscope percentage = ");
  Serial.print(mpu.GetFilterGyroCoeff());
  Serial.println('%');
  // Show accel/gyro deadzones
  Serial.println("--- Deadzone:");
  Serial.print("Accelerometer deadzone = ");
  Serial.print(mpu.GetAccelDeadzone());
  Serial.println(" m/s²");
  Serial.print("Gyroscope deadzone = ");
  Serial.print(mpu.GetGyroDeadzone());
  Serial.println(" degrees/second");
}

/*
 *  Setup
 */
void setup() {

  // Initialization
  mpu.Initialize();

  // Calibration
  Serial.begin(9600);
  Serial.println("=====================================");
  Serial.println("Starting calibration...");
  mpu.Calibrate();
  Serial.println("Calibration complete!");
}

/*
 *  Loop
 */
void loop() {
  
  PrintGets();
  delay(30000); // 30 sec delay

}

I attached a screenshot of the monitor.

That was stupid. Why would you waste time taking, and posting, a picture of text, when it is so much easier to copy and paste text AS TEXT here, where it would actually be usable?

Could it be I'm using a 6050 library on an 9250?

Why on earth would you do THAT?

Feargaill:
I’m trying to calibrate my mpu and it show some axes are not registering, am I doing something wrong? Could it be I’m using a 6050 library on an 9250? I attached a screenshot of the monitor.

  • Mandatory includes
    */
    #include <Arduino.h>
    #include <TinyMPU6050.h>

Sometimes it can be about the key. Like does your house key fit into your automobile ignition? Get an MPU9250 library and run the example.