2

For my head mouse project which is based on the voice recognition module V3.1 for left click, double click, right-click operations, I am facing a problem. I am using 433Mhz Radio Frequency one-way Transceiver for sending data. When I use the MPU 6050 accelerometer and gyroscope for mouse cursor movement and the voice recognition module together on only one Arduino board, the mouse cursor moves smoothly and the voice commands work smoothly. But when I use the 433Mhz RF one-way transmitter for one Arduino board to calculate the mouse movement and figure out the voice command to send it in a wireless manner and receive the values and voice commands using the receiver module of the rf433 Mhz, the mouse cursor starts to lag. It doesn't move smoothly. Please help me solve the problem. The code and circuit diagram are given below:

RF 433 Mhz Transmitter Circuit of Arduino Micro with Elechouse Voice Recog Module V3.1 and MPU6050 motion gyro-accel IMU with

RF 433Mhz receiver circuit using Arduino micro

Transmitter.ino

  /*433 MHz RF Module Transmitter Demonstration 1
  RF-Xmit-Demo-1.ino
  Demonstrates 433 MHz RF Transmitter Module
  Use with Receiver Demonstration 1
 
  DroneBot Workshop 2018
  https://dronebotworkshop.com
*/
 
// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library
#include <SPI.h>
#include <SoftwareSerial.h>
#include "VoiceRecognitionV3.h"
#include <Mouse.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>

VR myVR(8,9);    // 9:RX 8:TX

uint8_t records[7]; // save record
uint8_t buf[64];

MPU6050 mpu;
int16_t ax, ay, az, gx, gy, gz, oax, oay, oaz, ogx, ogy, ogz;
int16_t vx, vy;
//
#define leftRecord    (0)
#define rightRecord   (1)
#define doubleRecord  (2)

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf     --> command length
           len     --> number of parameters
*/
void printSignature(uint8_t *buf, int len)
{
  int i;
  for(i=0; i<len; i++){
    if(buf[i]>0x19 && buf[i]<0x7F){
      Serial.write(buf[i]);
    }
    else{
      Serial.print("[");
      Serial.print(buf[i], HEX);
      Serial.print("]aurav");
    }
  }
}

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf  -->  VR module return value when voice is recognized.
             buf[0]  -->  Group mode(FF: None Group, 0x8n: User, 0x0n:System
             buf[1]  -->  number of record which is recognized.
             buf[2]  -->  Recognizer index(position) value of the recognized record.
             buf[3]  -->  Signature length
             buf[4]~buf[n] --> Signature
*/
void printVR(uint8_t *buf)
{
  Serial.println("VR Index\tGroup\tRecordNum\tSignature");
  Serial.print(buf[2], DEC);
  Serial.print("\t\t");

  if(buf[0] == 0xFF){
    Serial.print("NONE");
  }
  else if(buf[0]&0x80){
    Serial.print("UG ");
    Serial.print(buf[0]&(~0x80), DEC);
  }
  else{
    Serial.print("SG ");
    Serial.print(buf[0], DEC);
  }
  Serial.print("\t");

  Serial.print(buf[1], DEC);
  Serial.print("\t\t");
  if(buf[3]>0){
    printSignature(buf+4, buf[3]);
  }
  else{
    Serial.print("NONE");
  }
  Serial.println("\r\n");
}

struct dataStruct{
  int16_t moveX;
  int16_t moveY;
  int flag;
  }myData;

byte tx_buf[sizeof(myData)] = {0};
 
// Create Amplitude Shift Keying Object
RH_ASK rf_driver;
int flag = 15;
 
void setup()
{


   /** initialize */
  
  Wire.begin();
  mpu.initialize();
  if (!mpu.testConnection()) {
    while (1);
    }
    
  myVR.begin(9600);
  Serial.begin(115200);
  Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample");
  
    
  if(myVR.clear() == 0){
    Serial.println("Recognizer cleared.");
  }else{
    Serial.println("Not find VoiceRecognitionModule.");
    Serial.println("Please check connection and restart Arduino.");
    while(1);
  }
  
  if(myVR.load((uint8_t)leftRecord) >= 0){
    Serial.println("leftRecord loaded");
  }
  
  if(myVR.load((uint8_t)rightRecord) >= 0){
    Serial.println("rightRecord loaded");
  }

  if(myVR.load((uint8_t)doubleRecord) >= 0){
    Serial.println("doubleRecord loaded");
  }
  
  
    // Initialize ASK Object
    rf_driver.init();
    if(!rf_driver.init()) Serial.println("Init failed");
    

    
}
 
void loop()
{

  int ret;

  ret = myVR.recognize(buf, 50);
    const char *msg = "Welcome to the Workshop!";

  if(ret>0){
  
  switch(buf[1]){
    
    case leftRecord:
    flag = 0;
    break;
    
    case rightRecord:
    flag = 1;
    break;

    case doubleRecord:
    flag = 2;
    break;
            
    default:
    flag=3;
    Serial.println("Record function undefined");
    break;
    }
    /** voice recognized */
    printVR(buf);
  }
  
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
    
  oax = ax+72;
  oay = ay-382;
  oaz = az-505;
  ogx = gx+99;
  ogy = gy-29;
  ogz = gz-50;

  vx = gx/200;  
  vy = -gz/200;
  myData.moveX = vx;
  myData.moveY = vy;
  myData.flag = flag;

  memcpy(tx_buf, &myData, sizeof(myData));
  byte bufSize = sizeof(myData);
  Serial.println("movX\tmovY\tmovZ\toax\toay\toaz\togx\togy\togz\tvx\tvy:");
  Serial.print(myData.moveX, HEX);
  Serial.print("\t");
  Serial.print(myData.moveY, HEX);
  Serial.print("\t");
  Serial.print(myData.flag, HEX);
  Serial.print("\t");
  Serial.print(oax, DEC);
  Serial.print("\t");
  Serial.print(oay, DEC);
  Serial.print("\t");
  Serial.print(oaz, DEC);
  Serial.print("\t");
  Serial.print(ogx, DEC);
  Serial.print("\t");
  Serial.print(ogy, DEC);
  Serial.print("\t");
  Serial.print(ogz, DEC);
  Serial.print("\t");
  Serial.print(vx, HEX);
  Serial.print("\t");
  Serial.println(vy, HEX);

  rf_driver.printBuffer("Buffer values [vx, vy, status flag respectively]: ", tx_buf, bufSize); //each value is 16 bit. and serail monitor will show in 8 + 8 = 16 bit format
    rf_driver.send((uint8_t *)tx_buf, bufSize);
    //Serial.println();
    rf_driver.waitPacketSent();

    flag = 15;
    delay(1);
    
}

Receiver.ino

// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library
#include <SPI.h>
#include <Mouse.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>

#define leftRecord    (0)
#define rightRecord   (1)
#define doubleRecord  (2)
// Create Amplitude Shift Keying Object
RH_ASK rf_driver;

struct dataStruct{
  int moveX, moveY, flag;
  }myData;
 
void setup()
{
    // Initialize ASK Object
    Wire.begin();
    rf_driver.init();
    // Setup Serial Monitor
    Serial.begin(115200);
    if(!rf_driver.init()) Serial.println("Init failed");
}
 
void loop()
{
    // Set buffer to size of expected message
    uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
    uint8_t buflen = sizeof(buf);
    // Check if received packet is correct size
    if (rf_driver.recv(buf, &buflen))
    {
      int i;

      // Message with a good checksum received, dump it.
  rf_driver.printBuffer("Got:", buf, buflen);
        memcpy(&myData, buf, sizeof(myData));
        Serial.println("");
      
        Serial.print("moveX: ");
        Serial.print(myData.moveX);
      
        Serial.print("  moveY: ");
        Serial.print(myData.moveY);
      
        Serial.print("  Command Status: ");
        Serial.print(myData.flag);
      
      // Message received with valid checksum
      Serial.print(" Message Received: ");
      Serial.println((char*)buf);

      Mouse.move(myData.moveX, myData.moveY);

  if(myData.flag!=15){
  
  switch(myData.flag){
    
    case leftRecord:
    Mouse.click(MOUSE_LEFT);
    delay(10);
    break;
    
    case rightRecord:
    Mouse.click(MOUSE_RIGHT);
    delay(10);
    break;

    case doubleRecord:
    Mouse.click(MOUSE_LEFT);
    Mouse.click(MOUSE_LEFT);
    delay(10);
    break;          
    default:
    break;
    }
      
    }
}
}
0
1

In general, you want to stream some data. and the mouse lag is one of the main obstacles in data streams; lag. so many classic causes such as buffer over-runs and timing problems come to mind.

The cheap 433MHz modules are not a good choice in case of streams. they lack any robust protocol, ACKing and security.

I would do this things to make it better:

  • use a better transmitter. maybe the cheap nRF24L01 ones.
  • use a bigger buffer
  • use two threads on the transmitter side. (e.g. use something like this, but two threads). one thread to collect data and writing it to a buffer, the next one to send data using nrf. furtunately, the nRF24 can send up to 32Bytes in one buffer transmission and the SPI interface is fast enough to fill it's buffer as quick as possible.
  • if you have to, use another thread to calculate movements from MPU6050. so you don't have to read it continuouesly and send all that raw data to reciever. you may use some interpolation on the receiver side though.
2
  • But when I use the nRF24L01 the Arduino turns on and then turns off. I've tried this with the Arduino Leonardo as well as the Micro. How can I fix this? It also causes power surges and overheating occassionally. – Nahian Rifaat Jul 26 '20 at 15:41
  • make sure the power pins are correct. this problem is mainly due to VCC/GND pins being swaped – Tirdad Sadri Nejad Jul 26 '20 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.