使用Arduino Leonardo做免驱蓝牙鼠标(手机操控)

板子使用Arduino Leonardo加HC-05串口蓝牙模块。如图所示:

                                                      

优点:

  • 32u4支持USB协议,免驱,即插即用。如果用CH341的板子还要写上位机程序,不能即插即用,而且不是每个电脑都装了CH341驱动。
  • 安装方便,只需三根杜邦线即可,VCC GND RX
  • 编程简单

缺点:

  • 成本有点高 

操作界面:

界面很简单

连接界面

操作界面:

本人没有学过java,代码是我本着C+Python=任何面向对象语言的宗旨,在github和各大网站上东拼西凑来的,有些代码是重复的,如触控板和ppt两个文件的蓝牙连接部分代码是重复的,程序能编译成功全靠强大的IDE,哪里错就改哪里。

蓝牙模块就是常见的hc-05,当然其他的应该也行。 开发板使用Arduino Leonardo的板子,不过是很小的板子,十几块钱,支持USB协议,可以直接模拟鼠标键盘。使用Arduino IDE进行编程,听说这个串口中断不太行,好像是个假的,AVR的编程没有学过,不想麻烦,于是我在中断里加了几个判断,以免接收到不完整的数据,实际使用并不影响,鼠标很顺滑。

本来想调用手机的传感器得出方位角,用Pich和Roll来映射鼠标的XY轴,结果调了一整天,试过了各种滤波的方法,首先是取队列平均值,但是队列越长,延迟越高,然后用最小二乘法拟合,发现还是不太行,于是求方差,过滤方差小的数据,最后用上了卡尔曼滤波......直至放弃,鼠标经常来回跳,幅度不大,但是很难受,而且本身也有不小的延时,没有学过PID什么的,估计是有解决办法的,我可能走了很多弯路,最后走到了绝路......

还有一个问题就是传感器数据的更新问题,normal和game的差距有点大,一个很慢一个很快。

最终还是选择了触控板,有懂安卓的可以把PPT和触控板做到一起(就是不用每一次都要返回再选择另一个模式了),触控板的代码来自网页,不过经过了大幅度的修改。

实现触控板的单击操作

我用了一个非常简单的办法,就是检测手指移动的长度,如果X和Y都小于5个像素,则发送单击信号,实测完美。双指功能没有做,不会。

if (detaX < 5 && detaY <5){
    sendSignal("*C1");
}

Arduino全部代码:

#include"Keyboard.h"
#include"Mouse.h"
int oldx = 0;
int oldy = 0;
int x = 0;
int y = 0;
//SoftwareSerial mySerial(2,3);//RX=2,TX=3
String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
void setup() {
  // put your setup code here, to run once:
//  Serial.begin(115200); //设置串口波特率9600
  Serial1.begin(115200);
//  inputString.reserve(200);
  

}

void loop() {
  
  

  if(stringComplete){




    if(inputString[0]='*'){
      
   
      if(inputString[1]=='C'){
        if(inputString[2]=='4'){
          Keyboard.press(KEY_LEFT_CTRL);
          delay(5);
          Keyboard.press(KEY_LEFT_GUI);
          delay(5);
          Keyboard.press(KEY_LEFT_ARROW);
          delay(5);
          Keyboard.release(KEY_LEFT_ARROW);
          delay(5);
          Keyboard.release(KEY_LEFT_GUI);
          delay(5);
          Keyboard.release(KEY_LEFT_CTRL);
        }
        else if(inputString[2]=='6'){
          Keyboard.press(KEY_LEFT_CTRL);
          delay(5);
          Keyboard.press(KEY_LEFT_GUI);
          delay(5);
          Keyboard.press(KEY_RIGHT_ARROW);
          delay(5);
          Keyboard.release(KEY_RIGHT_ARROW);
          delay(5);
          Keyboard.release(KEY_LEFT_GUI);
          delay(5);
          Keyboard.release(KEY_LEFT_CTRL);
        }
        else if(inputString[2]=='h'){
          keyClick(KEY_F5);
        }
        else if(inputString[2]=='u'){
          keyClick(KEY_UP_ARROW);
        }
        else if(inputString[2]=='d'){
          keyClick(KEY_DOWN_ARROW);
        }
        else if(inputString[2]=='l'){
          keyClick(KEY_LEFT_ARROW);
        }
        else if(inputString[2]=='r'){
          keyClick(KEY_RIGHT_ARROW);
        } 
        else if(inputString[2]=='e'){
          keyClick(KEY_ESC);      
          }
        else if(inputString[2]=='s'){
          Keyboard.press(KEY_RIGHT_ALT);
        }
        else if(inputString[2]=='g'){
          Keyboard.release(KEY_RIGHT_ALT);
        }
        else if(inputString[2]=='1'){
          Mouse.click(MOUSE_LEFT);
        }
        else if(inputString[2]=='2'){
          Mouse.click(MOUSE_MIDDLE);
        }
        else if(inputString[2]=='3'){
          Mouse.click(MOUSE_RIGHT);
        }
        else if(inputString[2]=='v'){
          Mouse.press(MOUSE_LEFT);
        }
        else if(inputString[2]=='^'){
          Mouse.release(MOUSE_LEFT);
        }
        
                
        else if(inputString[2]=='t'){
          keyClick(KEY_TAB);
        }
        else if(inputString[2]=='n'){
          Keyboard.press(KEY_LEFT_SHIFT);
          delay(5);
          Keyboard.press(KEY_F5);
          delay(5);
          Keyboard.release(KEY_F5);
          delay(5);
          Keyboard.release(KEY_LEFT_SHIFT);
        }
      }
            
      else{
        if(inputString[1]=='x'){
        int yl = getyindex(inputString);
        x = inputString.substring(2,yl).toInt();
        y = inputString.substring(yl+1,-1).toInt();
        int x_dist = (x-oldx);
        int y_dist = (y-oldy);
        Mouse.move(x_dist,y_dist);
        oldx=x;
        oldy=y;
       }
        
       
      }
         
}
inputString="";
  stringComplete = false;
} 
}

  
int getyindex(String a){
    for(int i=0;i<a.length();i++){
      if(a[i]=='y'){
        return i;
      }
    }
}



void keyClick(int a){
  Keyboard.press(a);
  delay(1);
  Keyboard.release(a);
}

void serialEvent1() {
  while (Serial1.available()>0) {
//    if(stringComplete){
//      inputString="";
//    }
    char inChar = (char)Serial1.read();
    
    
    if(!stringComplete){

      
      if(inputString[0]=='*'){
        inputString += inChar;
      }
      else{
         if (inChar =='*'){
            inputString="*";
         }
        
      }
    }

    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}

目前只上传了apk文件地址:https://download.csdn.net/download/weixin_43480922/12522541,有需要的话再把源码文件上传。

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值