板子使用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,有需要的话再把源码文件上传。