Mouse controlado por gestos (Air Mouse) usando Arduino e acelerômetro

Tempo de leitura: 7 minutes

AIR Mouse também é chamado de mouse controlado por gestos e funciona com base em gestos manuais. Neste projeto um acelerômetro é usado para medir a inclinação da mão nas direções X e Y e move o cursor de acordo com a inclinação.

No projeto são usados dois tipos de circuito, um é o circuito transmissor e o outro é o circuito receptor. O circuito do transmissor usa a série MPU6050 de acelerômetro, que é conectado ao Arduino por meio de comunicação I2C. Os dados são transferidos para o circuito receptor usando o módulo RF, ASK433. Duas chaves também são usadas no circuito do transmissor para funcionar como clique esquerdo e clique direito.

No lado do receptor, um Arduino Leonardo é usado. O objetivo de usar o Arduino Leonardo é que ele suporte HID (Human Interface Device). HID nos permite controlar o mouse e teclado do nosso PC ou laptop.

 

Componentes

ComponenteEspecificaçãoQuantidade
ArduinoLeonardo1
ArduinoNano1
AcelerômetroMPU60501
Módulo RF433Mhz T / R1
SwitchMomentary2
SwitchDPDT3
Resistor10K2
Bateria9 Volt1
Suporte da bateria1
Cabo USB1

 

O circuito

No projeto são usados dois circuitos, um é o circuito transmissor e o outro é o circuito receptor.

 

Circuito Transmissor

O circuito do transmissor é colocado em nossas mãos. Neste circuito é utilizado o Arduino Nano, que recebe os dados do acelerômetro através da comunicação I2C. MPU6050 é usado no circuito do transmissor, que é o acelerômetro e oferece suporte à comunicação I2C. Os pinos SCL e SDA ou acelerômetro (MPU 6050) são conectados ao pino SCL e SDA do Arduino Nano, onde SCL é A5 e SDA é os pinos A4 do Arduino. MPU 6050 tem um pino INT, que é conectado ao pino de interrupção (INT0) do Arduino que é D2.

Agora os dados do acelerômetro são transferidos para o circuito receptor usando comunicação RF. Para comunicação RF, o transmissor RF é usado no lado do transmissor. O pino de dados do transmissor RF está conectado ao pino D4 do Arduino. Uma antena está conectada ao pino ANT do transmissor RF. A antena nada mais é do que um fio de núcleo único com 15 cm de comprimento.

Dois interruptores estão conectados a D11 e D13 do Arduino que são o botão esquerdo e o botão direito. Todo este circuito é alimentado por bateria de 9 volts que é conectada ao pino Vin do Arduino através de um switch.

Se você for bom em gravação de PCB, use o circuito fornecido abaixo para construir o projeto.

Se você deseja construir o circuito em PCB universal (ZERO PCB) ou placa de ensaio, use o design fornecido abaixo.

Circuito Receptor

No lado do receptor, dois componentes principais usados são o Arduino Leonardo e o receptor RF. Dois interruptores são usados para ativar/desativar o mouse e ligar/desligar a comunicação RF.

No circuito receptor, o pino de dados do receptor RF é conectado ao pino de interrupção (INT1) do Arduino, que é o pino D2.

Um interruptor é usado na linha de energia do receptor RF, que é usado para ligar/desligar o receptor RF. Outra chave também está conectada ao pino D4 do Arduino que é usado para ativar/desativar o mouse. O Arduino Leonardo é conectado ao PC por meio de um cabo USB padrão.

O circuito e o esquema de PCB são mostrados abaixo.

 

Trabalhando

No lado do transmissor, um Arduino Nano é usado como unidade de controle. O acelerômetro é conectado ao Arduino por meio de comunicação I2C que mede a aceleração gravitacional nas direções X, Y e Z, mas precisamos apenas de valores em dois eixos, então estamos usando os valores de X e Y. Duas chaves também estão conectadas ao Arduino; eles são usados para clique esquerdo e direito. O Arduino mede todos os valores, agora temos quatro valores

  1. Aceleração na direção X
  2. Aceleração na direção Y
  3. Status do clique direito
  4. Status do clique esquerdo

Todos os valores são mesclados em um número inteiro de quatro dígitos, onde cada dígito mostra cada valor.

No lado do receptor, o Arduino recebe os dados (inteiros) do transmissor e se divide em quatro valores. Arduino Leonardo suporta HID (Human Interface Device), então ele move o cursor de acordo com os valores de X e Y.

Circuito Air Mouse usando Arduino e acelerômetro

Transmissor PCB

 

PCB receptor

 

Código

Neste projeto dois Arduino são usados, um no lado do transmissor e o outro no lado do receptor.

 

Código do Transmissor

#include <Wire.h>
#include <MPU6050.h>
#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

MPU6050 mpu;

int Lclick = 11;
int Rclick = 13;

void setup() 
{
  Serial.begin(115200);
  while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
  {
    Serial.println("Could not find a valid MPU6050 sensor, check wiring!");
    delay(500);
  }
  
  checkSettings();


  mySwitch.enableTransmit(4);

  pinMode(Lclick, INPUT);
  pinMode(Rclick, INPUT);
}

void checkSettings()
{
  Serial.println();
  
  Serial.print(" * Sleep Mode:            ");
  Serial.println(mpu.getSleepEnabled() ? "Enabled" : "Disabled");
  
  Serial.print(" * Clock Source:          ");
  switch(mpu.getClockSource())
  {
    case MPU6050_CLOCK_KEEP_RESET:     Serial.println("Stops the clock and keeps the timing generator in reset"); break;
    case MPU6050_CLOCK_EXTERNAL_19MHZ: Serial.println("PLL with external 19.2MHz reference"); break;
    case MPU6050_CLOCK_EXTERNAL_32KHZ: Serial.println("PLL with external 32.768kHz reference"); break;
    case MPU6050_CLOCK_PLL_ZGYRO:      Serial.println("PLL with Z axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_YGYRO:      Serial.println("PLL with Y axis gyroscope reference"); break;
    case MPU6050_CLOCK_PLL_XGYRO:      Serial.println("PLL with X axis gyroscope reference"); break;
    case MPU6050_CLOCK_INTERNAL_8MHZ:  Serial.println("Internal 8MHz oscillator"); break;
  }
  
  Serial.print(" * Accelerometer:         ");
  switch(mpu.getRange())
  {
    case MPU6050_RANGE_16G:            Serial.println("+/- 16 g"); break;
    case MPU6050_RANGE_8G:             Serial.println("+/- 8 g"); break;
    case MPU6050_RANGE_4G:             Serial.println("+/- 4 g"); break;
    case MPU6050_RANGE_2G:             Serial.println("+/- 2 g"); break;
  }  

  Serial.print(" * Accelerometer offsets: ");
  Serial.print(mpu.getAccelOffsetX());
  Serial.print(" / ");
  Serial.print(mpu.getAccelOffsetY());
  Serial.print(" / ");
  Serial.println(mpu.getAccelOffsetZ());
  
  Serial.println();
}

void loop()
{
  //Vector rawAccel = mpu.readRawAccel();
  Vector normAccel = mpu.readNormalizeAccel();

  int xval =normAccel.XAxis/3 + 5;
  int yval =normAccel.YAxis/3 + 5;

  int RCval = digitalRead(Rclick);
  int LCval = digitalRead(Lclick);

  int T = 1000*xval + 100*yval + 10*RCval + LCval;
 
  mySwitch.send(T, 24);


  //delay(10);
}


No lado do transmissor, três arquivos de cabeçalho são usados e você pode baixar as bibliotecas a partir do link

h: já anexado
h: Para acelerômetro MPU6050: https://github.com/jarzebski/Arduino-MPU6050
h: Para transmissor RF e módulo receptor: https://github.com/sui77/rc-switch

“RCSwitch” é declarado na linha 5 e MPU6050 é declarado na linha 7. Dois inteiros são declarados para clique esquerdo e direito.

Em “void setup()” “serial.begin(115200)” é usado para monitor serial. Da linha 16 a 20 “mpu6050” é verificado, isso ajuda a verificar a fiação. Depois disso, uma função “checkSettings()” é usada para verificar a configuração de “MPU6050”. Depois disso, “mySwitch.enableTransmit(4)” é usado para Habilitar o transmissor (módulo transmissor de RF) que está conectado ao pino D4 do Arduino. No final, a função “pinMode” é usada para declarar o clique esquerdo e direito como entrada.

Um “void cleckSetting()” é declarado, ele é usado para verificar a configuração de “MPU6050”. Esta função é muito longa e complicada, por isso não discutimos esta parte.

No “void loop()” a aceleração gravitacional (aceleração normalizada) é lida no acelerômetro. Na linha 72 e 73, os valores de X e Y são salvos em números inteiros que são valores processados.

Nas linhas 75 e 76, o status do clique esquerdo e direito é lido e salvo em números inteiros. Agora todos os inteiros são mesclados na linha 78 e salvos em um inteiro e os dados são transmitidos na linha 80 pelo módulo RF.

 

Código do Receptor

 

#include <RCSwitch.h>
#include "Mouse.h"

RCSwitch mySwitch = RCSwitch();

int rvalue,a,b,c,d; 
float xReading,yReading;

void setup() {
  Serial.begin(115200);
  mySwitch.enableReceive(1);  // Receptor na interrupção 0 => que é o pino # 2
  Mouse.begin();
  pinMode(5,INPUT);
}

void loop() {
  if (mySwitch.available()) {
    
    int value = mySwitch.getReceivedValue();
    
    if (value == 0) {
    } 
    else {     
       rvalue = mySwitch.getReceivedValue();
    }

    a = (rvalue) % 10;
    b = (rvalue/10) % 10;
    c = (rvalue/100) % 10;
    d = (rvalue/1000) % 10;

    if (d == 1 ){xReading =  3;}
    if (d == 2 ){xReading =  2;}
    if (d == 3 ){xReading =  0;}
    if (d == 4 ){xReading =  0;}
    if (d == 5 ){xReading =  0;}
    if (d == 6 ){xReading =  0;}
    if (d == 7 ){xReading = -2;}
    if (d == 8 ){xReading = -3;}

    if (c == 1 ){yReading =  3;}
    if (c == 2 ){yReading =  2;}
    if (c == 3 ){yReading =  0;}
    if (c == 4 ){yReading =  0;}
    if (c == 5 ){yReading =  0;}
    if (c == 6 ){yReading =  0;}
    if (c == 7 ){yReading = -2;}
    if (c == 8 ){yReading = -3;}

    mySwitch.resetAvailable();
  }

  if (digitalRead(5) == LOW){
    Mouse.move(xReading, yReading, 0);
    //delay(2);
    }


  if (a == 1) {
    if (!Mouse.isPressed(MOUSE_LEFT)) {
      Mouse.press(MOUSE_LEFT);
    }
  }
  else {
    if (Mouse.isPressed(MOUSE_LEFT)) {
      Mouse.release(MOUSE_LEFT);
    }
   }


  if (b == 1) {
    if (!Mouse.isPressed(MOUSE_RIGHT)) {
      Mouse.press(MOUSE_RIGHT);
    }
  }
  else {
    if (Mouse.isPressed(MOUSE_RIGHT)) {
      Mouse.release(MOUSE_RIGHT);
    }
   }
}

No início do código, dois arquivos de cabeçalho são usados, o primeiro é usado para o módulo RF e o outro (Mouse.h) é usado para o mouse do computador.

Na linha 4, “RCSwitch” é denominado “mySwitch”. Alguns inteiros são declarados na linha 6 onde “rvalue” é usado para dados recebidos e “a”, “b”, “c” e “d” são os quatro valores após quebrar o “rvalue”. Dois flutuadores também são declarados pelo nome “xReading” e “yReading”.

Em “void setup()” “mySwitch.enableReceived” é usado para habilitar o receptor. Depois disso, “mouse.begin” é usado para iniciar o mouse. “PinMode“ é usado para declarar o pino D5 como entrada.

No “void loop()” uma condição “if” é usada, o processo entra em loop quando os dados estão disponíveis na comunicação RF. Agora os dados recebidos são atribuídos em um inteiro “rvalue”. Na linha 23 a 26, os dados recebidos (rvalue) são divididos em quatro inteiros “a”, “b”, “c” e “d”. Onde “c” e “d” são o valor da aceleração na direção xey, “a” e “b” são o status do clique esquerdo e direito.

Da linha 28 à linha 44, os valores de “xReading” e “yReading” são declarados de acordo com os valores “c” e “d”. Na linha 46, a comunicação RF é reiniciada.

Da linha 49 para a linha 51 o cursor é movido de acordo com os valores de “xReading” e “yReading”, funcionará quando a chave (conectada ao pino D4) estiver BAIXA. No final, o clique esquerdo e direito é pressionado de acordo com os valores de “a” e “b”.