基于M5StickC的两种蓝牙键盘实现
本帖最后由 沧海笑1122 于 2020-2-11 11:32 编辑【基于M5StickC的两种蓝牙键盘实现】这次不讲故事了,代码比较简单,直接上代码了。接线都写在备注里面了,请玩家参考。
一、游戏摇杆+按键套装+m5stickc的ble键盘实现
/**
* This example turns the ESP32 into a Bluetooth LE keyboard that writes the words, presses Enter, presses a media key and then Ctrl+Alt+Delete
*/
//==M5StickC +摇杆按键游戏套件模拟ble键盘
//==date:2020-02-09
//==借鉴: // (1) M5StickC的官方display & IMU demo// (2) 感谢https://github.com/T-vK/ESP32-BLE-Keyboard
// (3) 感谢https://mc.dfrobot.com.cn/thread-298175-1-1.html
// 谢谢作者zoologist提醒,需要修改\ESP32-BLE-Keyboard-master\BleKeyboard.cpp 文件,
//在前面插入HIDINPUT 和HIDOUTPUT的定义:
//==功能:BLE键盘使能、四个键盘方向键模拟,玩家可以离开电脑,用游戏按键控制目标,如俄罗斯方块。
//==使用方法: 将摇杆键盘套件的四个方向键以及摇杆的中间KEY连接到m5stickc上。打开C之后,
// 新增PC的蓝牙设备,可以找到一个esp32 ble keyboard,配对后即可连接使用,摇杆的中间KEY是使能键,
// 按一次开启BLE键盘功能,再按一次则不使能,可循环。
//=====
//=====
//==========M5stickc init
#include <M5StickC.h>
#include <BleKeyboard.h>
BleKeyboard bleKeyboard;
//=========键盘硬件设置
int enableButton = 36; // 摇杆按键,用作键盘功能使能按键,m5stickC G36
int upButton = 26; // 上方按键,G26
int downButton = 33; // 下方按键,G33
int leftButton = 0; // 左按键,G0
int rightButton =32;// 右按键,G32
int uppreviousButtonState = HIGH; // up之前按键状态
int downpreviousButtonState = HIGH; // down之前按键状态
int leftpreviousButtonState = HIGH; // left之前按键状态
int rightpreviousButtonState = HIGH; // right之前按键状态
boolean enable = false; // 模拟鼠标功能是否可用
boolean lastEnableButtonState = HIGH; // 上一次使能按键读值
//======================
void setup() {
// 初始化按键引脚,如果没有上拉电阻,需要使用INPUT_PULLUP
pinMode(upButton, INPUT);
pinMode(downButton, INPUT);
pinMode(leftButton, INPUT);
pinMode(rightButton, INPUT);
pinMode(enableButton, INPUT);
Serial.begin(115200);
Serial.println("Starting BLE work!");
// M5 init
Serial.begin(115200);
M5.begin();
M5.update();
M5.Lcd.setRotation(1);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(1);
M5.Lcd.setCursor(30, 20);
M5.Lcd.println("M5StickC init.");
// bleKeyboard
bleKeyboard.begin();
//lcd
}
void loop() {
if(bleKeyboard.isConnected()) {
M5.Lcd.setCursor(30, 20);
M5.Lcd.println(" ");
M5.Lcd.setCursor(30, 20);
M5.Lcd.println("BKConnected..");
Serial.println("Sending 'Hello world'...");
// 使能按键按一次使能,再按一次不使能
boolean EnableButtonState = digitalRead(enableButton);
if ((EnableButtonState == LOW) && (EnableButtonState != lastEnableButtonState)) {
enable = !enable;
}
lastEnableButtonState = EnableButtonState;//使能键用于下一次比较
if (enable) {
//=====读UP按键状态
int upbuttonState = digitalRead(upButton);
// 如果up按键状态改变,且当前按键状态为高电平
if ((upbuttonState != uppreviousButtonState) && (upbuttonState == HIGH)) {
bleKeyboard.write(KEY_UP_ARROW);
}
// 保存up当前按键状态,用于下一次比较
uppreviousButtonState = upbuttonState;
//=====读DOWN按键状态
int downbuttonState = digitalRead(downButton);
// 如果down按键状态改变,且当前按键状态为高电平
if ((downbuttonState != downpreviousButtonState) && (downbuttonState == HIGH)) {
bleKeyboard.write(KEY_DOWN_ARROW);
}
// 保存down当前按键状态,用于下一次比较
downpreviousButtonState = downbuttonState;
//=====读LEFT按键状态
int leftbuttonState = digitalRead(leftButton);
// 如果left按键状态改变,且当前按键状态为高电平
if ((leftbuttonState != leftpreviousButtonState) && (leftbuttonState == HIGH)) {
bleKeyboard.write(KEY_LEFT_ARROW);
}
// 保存left当前按键状态,用于下一次比较
leftpreviousButtonState = leftbuttonState;
//=====读RIGHT按键状态
int rightbuttonState = digitalRead(rightButton);
// 如果right按键状态改变,且当前按键状态为高电平
if ((rightbuttonState != rightpreviousButtonState) && (rightbuttonState == HIGH)) {
bleKeyboard.write(KEY_RIGHT_ARROW);
}
// 保存right当前按键状态,用于下一次比较
rightpreviousButtonState = rightbuttonState;
}
}
}
二、基于M5StickC姿态传感器的ble体感键盘
//=====M5StickC BLE 体感键盘
//=date:2020-02-09
//=借鉴:
// (1) M5StickC的官方display & IMU demo
// (2)感谢https://github.com/T-vK/ESP32-BLE-Keyboard
// (3)感谢https://mc.dfrobot.com.cn/thread-298175-1-1.html ,
// 谢谢作者zoologist提醒,需要修改\ESP32-BLE-Keyboard-master\BleKeyboard.cpp 文件,
// 在前面插入HIDINPUT 和HIDOUTPUT的定义:
//=功能:实现up-down-left-right四个方向键的体感模拟
//= buttonA(表面M5大按钮)为使能键,按一次可以进入模拟键盘,再按一次就退出模拟键盘,以此类推
//=使用方法:在PC打开蓝牙设备,找到esp32_bleKeyboard,配对,观察显示连接后,按动C上的使能按钮,
// 开始模拟四个方向键,每个姿态模拟一次键盘按动,需要回到水平位置后开始下一个姿态。
#include <M5StickC.h>
#include <BleKeyboard.h>
BleKeyboard bleKeyboard;
//===姿态数据
float accX = 0;
float accY = 0;
float accZ = 0;
//=========键盘硬件设置
boolean uppreviousButtonState= false; // up之前按键状态
boolean downpreviousButtonState = false; // down之前按键状态
boolean leftpreviousButtonState = false; // left之前按键状态
boolean rightpreviousButtonState = false; // right之前按键状态
boolean upButtonState= false; //姿态传感器判断的up状态,下同
boolean downButtonState= false;//
boolean leftButtonState= false;//
boolean rightButtonState= false;//
boolean enable = false; // 模拟键盘功能是否可用
boolean lastEnableButtonState = false; // 上一次使能按键读值
boolean EnableButtonState=false; //使能按钮状态,按动A键后,为true
//======================
void setup() {
// M5 init
Serial.begin(115200);
M5.begin();
M5.update();
M5.Lcd.setRotation(1);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextSize(1);
M5.Lcd.setCursor(30, 20);
M5.Lcd.println("ARROW");
M5.Lcd.setCursor(0, 30);
// M5.Lcd.println("X Y Z");
M5.MPU6886.Init();
// bleKeyboard
bleKeyboard.begin();
}
void loop() {
if(bleKeyboard.isConnected()) {//判断蓝牙键盘是否与PC连接
M5.Lcd.setCursor(30, 20);
M5.Lcd.println(" ");
M5.Lcd.setCursor(30, 20);
M5.Lcd.println("BKConnected..");
if(M5.BtnA.wasPressed())
{
Serial.println("BtnAwasPressed...");
EnableButtonState = true;
// 使能按键按一次使能,再按一次不使能
if ((EnableButtonState == true) && (EnableButtonState != lastEnableButtonState)) {
enable = true;
M5.Lcd.setCursor(30, 20);
M5.Lcd.println(" ");
M5.Lcd.setCursor(30, 20);
M5.Lcd.println("Enable..");
}
else
{
enable = false;
}
lastEnableButtonState = enable;//使能键用于下一次比较
//Serial.print("enable=");
//Serial.println(enable);
}
if (enable) {
getimu(); //读取各个姿态用于判断
//Serial.println("getimu...");
//Serial.print(upButtonState);
//Serial.println(uppreviousButtonState);
//=====读UP按键状态
// 如果up按键状态改变,且当前判定满足up条件
if ((upButtonState != uppreviousButtonState) && (upButtonState ==true)) {
//Serial.println("up");
bleKeyboard.write(KEY_UP_ARROW);
}
// 保存up当前按键状态,用于下一次比较
uppreviousButtonState = upButtonState;
//=====读DOWN按键状态
// 如果down按键状态改变,且当前判定满足down条件
if ((downButtonState != downpreviousButtonState) && (downButtonState == true)) {
bleKeyboard.write(KEY_DOWN_ARROW);
//Serial.println("down");
}
// 保存down当前按键状态,用于下一次比较
downpreviousButtonState = downButtonState;
//=====读LEFT按键状态
// 如果left按键状态改变,且当前判定满足left条件
if ((leftButtonState != leftpreviousButtonState) && (leftButtonState == true)) {
bleKeyboard.write(KEY_LEFT_ARROW);
//Serial.println("left");
}
// 保存left当前按键状态,用于下一次比较
leftpreviousButtonState = leftButtonState;
//=====读RIGHT按键状态
// 如果right按键状态改变,且当前判定满足right条件
if ((rightButtonState != rightpreviousButtonState) && (rightButtonState == true)) {
bleKeyboard.write(KEY_RIGHT_ARROW);
//Serial.println("right ");
}
// 保存right当前按键状态,用于下一次比较
rightpreviousButtonState = rightButtonState;
}
}
M5.update();
delay(10);
}
void getimu(){ //获取各种姿态子程序
//-900~900是x/y针对水平姿态的+-90的数值,玩家可以自己设置灵敏区域
//delay(10)可以自行设置反应时间
M5.MPU6886.getAccelData(&accX,&accY,&accZ);
//M5.Lcd.setCursor(0, 45);
//M5.Lcd.printf("%.2f %.2f %.2f ",accX * 1000,accY * 1000, accZ * 1000);
if ((accX * 1000>-350) and (accX * 1000<250) and (accY * 1000>-350) and (accX * 1000<350)){//手腕水平放置
//M5.Lcd.setCursor(30, 20);
//M5.Lcd.println(" ");
//M5.Lcd.setCursor(30, 20);
//M5.Lcd.println("NONE");
leftButtonState = false;
rightButtonState = false;
downButtonState = false;
upButtonState=false;
}
if (accX * 1000>350) {
M5.Lcd.setCursor(30, 20);
M5.Lcd.println(" ");
M5.Lcd.setCursor(30, 20);
M5.Lcd.println("LEFT");
leftButtonState = true;
}
if (accX * 1000<-450) {
M5.Lcd.setCursor(30, 20);
M5.Lcd.println(" ");
M5.Lcd.setCursor(30, 20);
M5.Lcd.println("RIGHT");
rightButtonState = true;
}
if (accY * 1000>450) {
// M5.Lcd.setCursor(30, 20);
// M5.Lcd.println(" ");
// M5.Lcd.setCursor(30, 20);
// M5.Lcd.println("DOWN");
downButtonState = true;
}
if (accY * 1000<-450) {
//M5.Lcd.setCursor(30, 20);
//M5.Lcd.println(" ");
//M5.Lcd.setCursor(30, 20);
//M5.Lcd.println("UP");
upButtonState= true;
}
delay(10);
}
小结:
就用户体验而言,方案一肯定体验更好。方案二(体感方案)可以说是一种方法的尝试,供参加参考。
这个特殊艰难的日子,不放弃前进的脚步。
沧海合十。祝愿安康平顺。
分享上述两组代码以及修改过的ble keyvborad库。
顶个贴:lol 沧海笑出品,必是精品!
页:
[1]