nrf24l01 wireless mpu 6050 (gyroscopic) mouse

Hello everyone,

I am trying to make a wireless gyroscopic mouse with mpu 6050 and nrf24l01, arduino. I am having trouble programing it. I don't know how to store the x,y,z values and send it through the nrf24l01. Can anyone help me and fix my code. I have few errors in my code and I don't know how to fix it can someone tell me so I can fix it.

Thank you

reciever_gyroscopic_mouse_code.ino (627 Bytes)

transmitter_gyroscopic_mouse_code.ino (1.72 KB)

Short programs should be included in your Post using the code button </> so people don't have to download them

Transmitter

#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>
#include <Mouse.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

MPU6050 mpu;
int16_t ax, ay, az, gx, gy, gz;
int16_t accx, accy, accz;
int vx, vy;
float angle;
int readIndex = 0;
const int numReadings = 20;
int angleReadings[numReadings];
int total = 0;
float averageAngle = 0.0; 
int oldZ = 0;
int newZ = 0;
int data [1];

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
boolean buttonState = 0;

void setup() {
  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00002
  radio.openReadingPipe(1, addresses[0]); // 00001
  radio.setPALevel(RF24_PA_MIN);

Serial.begin(115200);
  Wire.begin();
  mpu.initialize();
  if (!mpu.testConnection()) {
    while (1);
  }
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    angleReadings[thisReading] = 0;
  }
}
void loop() {
 
  total = total - angleReadings[readIndex];
  angleReadings[readIndex] = angle;
  total = total + angleReadings[readIndex];
  readIndex = readIndex + 1;
  if (readIndex >= numReadings) {
    readIndex = 0;
  }
  //accx, accy, accz;
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  mpu.getAcceleration(&accx, &accy, &accz);
 
  oldZ = newZ;
  vx = (gx + 300) / 150; // "+300" because the x axis of gyroscope give values about -350 while it's not moving. Change this value if you get something different using the TEST code, chacking if there are values far from zero.
  vy = -(gz - 100) / 150; // same here about "-100"
 
  data [1] = Mouse.move(vx, vy);
  
  radio.stopListening();
  radio.write(data, sizeof(data));
    
  angle = atan2((float) ay, (float) ~ax) * (180.0 / PI);
  delay(20);
}

Receiver

#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>
#include <Mouse.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
Servo myServo;
boolean buttonState = 0;

void setup() {
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_MIN);
}

void loop() {
  delay(5);
  radio.startListening();
  if ( radio.available()) {
    while (radio.available()) {
      radio.read(data, sizeof(data));
    }
    delay(5);
  }
}

...R

You seem to be very mixed up.
What is the purpose of sending data - the receiver seems to do nothing with it? And it has no definition for the variable "data"

This (in the transmitter) seems all wrong

  data [1] = Mouse.move(vx, vy);
  
  radio.stopListening();
  radio.write(data, sizeof(data));

AFAIK Mouse.move() sends data to the PC over the USB cable.

Note also that referencing data[1] is incorrect. It should be data[0] as you have created an array with only 1 element.

I suspect what you want to do is send the X Y and Z values to the other Arduino so that it can call Mouse.move() - but I may be wrong. And if I am correct you should send all three values in an array in a single nRF24 message.

Have a look at this Simple nRF24L01+ Tutorial.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with. Start by getting the first example to work

There is also a connection test program to check that the Arduino can talk to the nRF24 it is connected to.

A common problem with nRF24 modules is insufficient 3.3v current from the Arduino 3.3v pin. This seems to be a particular problem with the nano. The high-power nRF24s (with the external antenna) will definitely need an external power supply. At least for testing try powering the nRF24 with a pair of AA alkaline cells (3v) with the battery GND connected to the Arduino GND.

If you are using the high-power nRF24s (with the external antenna) make sure there is sufficient distance between the two nRF24s so that the signal does not overwhelm the receiver - try 3 metres separation. If you are new to nRF24s it may be better to start with a pair of low power modules with the pcb antenna.

...R

Robin 2, thank you so much for your help and I will take a look at the tutorial.

I came up with the final code do you guys think it would work before I test it?

tranmitter code:

#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>
#include <Mouse.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

MPU6050 mpu;
int16_t ax, ay, az, gx, gy, gz;
int16_t accx, accy, accz;
int vx, vy;
float angle;
int readIndex = 0;
const int numReadings = 20;
int angleReadings[numReadings];
int total = 0;
float averageAngle = 0.0; 
int oldZ = 0;
int newZ = 0;
int y, x;

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
boolean buttonState = 0;

void setup() {
 radio.begin();
 radio.openWritingPipe(addresses[1]); // 00002
 radio.openReadingPipe(1, addresses[0]); // 00001
 radio.setPALevel(RF24_PA_MIN);

Serial.begin(115200);
 Wire.begin();
 mpu.initialize();
 if (!mpu.testConnection()) {
   while (1);
 }
 for (int thisReading = 0; thisReading < numReadings; thisReading++) {
   angleReadings[thisReading] = 0;
 }
}
void loop() {

 total = total - angleReadings[readIndex];
 angleReadings[readIndex] = angle;
 total = total + angleReadings[readIndex];
 readIndex = readIndex + 1;
 if (readIndex >= numReadings) {
   readIndex = 0;
 }
 //accx, accy, accz;
 mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
 mpu.getAcceleration(&accx, &accy, &accz);

 oldZ = newZ;
 vx = (gx + 300) / 150; // "+300" because the x axis of gyroscope give values about -350 while it's not moving. Change this value if you get something different using the TEST code, chacking if there are values far from zero.
 vy = -(gz - 100) / 150; // same here about "-100"

 x = vx;
 y = vy;

 typedef struct 

 {
   int x;
   int y;
   }
 controlDef;

 controlDef data;
 
 radio.stopListening();
 radio.write(&data, sizeof(data));
   
 angle = atan2((float) ay, (float) ~ax) * (180.0 / PI);
 delay(20);
}

reciever code:

#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>
#include <Mouse.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
boolean buttonState = 0;

void setup() {
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_MIN);
}

void loop() {
  delay(5);
  radio.startListening();
  if ( radio.available()) {
    while (radio.available())
    {
      int data = 0;
      int x = 0;
      int y = 0;
      radio.read(&data, sizeof(data));
      Mouse.move(x, y);
    }
    delay(5);
}
}

ardumaster112:
I came up with the final code do you guys think it would work before I test it?

Wrong order. Test first, then ask questions.

If it works you may not need to ask a question. If it does not work you will have a lot of extra information to give us about what actually happens.

The Arduino system is great for learning-by-doing.

...R