基于M5StickC的两种蓝牙键盘实现-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 3111|回复: 2

基于M5StickC的两种蓝牙键盘实现

[复制链接]
发表于 2020-2-10 22:36 | 显示全部楼层 |阅读模式
本帖最后由 沧海笑1122 于 2020-2-11 11:32 编辑

【基于M5StickC的两种蓝牙键盘实现】  这次不讲故事了,代码比较简单,直接上代码了。接线都写在备注里面了,请玩家参考。
微信图片_20200210222700.jpg
一、游戏摇杆+按键套装+m5stickc的ble键盘实现
[mw_shl_code=arduino,true]/**
* 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;  
  }  

  }

}
[/mw_shl_code]

二、基于M5StickC姿态传感器的ble体感键盘
[mw_shl_code=arduino,true]
//=====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);
}
[/mw_shl_code]

小结:
就用户体验而言,方案一肯定体验更好。方案二(体感方案)可以说是一种方法的尝试,供参加参考。

这个特殊艰难的日子,不放弃前进的脚步。
沧海合十。祝愿安康平顺。

分享上述两组代码以及修改过的ble keyvborad库。
uploadcodes.rar (4.01 KB, 下载次数: 5)
ESP32-BLE-Keyboard_fixed.rar (9.25 KB, 下载次数: 6)








发表于 2020-4-11 19:18 | 显示全部楼层
沧海笑出品,必是精品!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-29 00:14 , Processed in 0.095439 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表