增加手柄震动功能,右扳机按下时,触发震动,连接时震动,断开时震动,跳跃落地时震动
This commit is contained in:
1 parent
e33a6b894d
commit
0ef2bb0d7f
6 files changed
+439
-251
No files matched your search
@@ -1,46 +1,137 @@
|
||||
/* ---------------------------------
|
||||
* 蓝牙手柄(Xbox)模块
|
||||
* 包含:蓝牙实体、状态变量、连接处理函数
|
||||
* 不包含:手柄数据解析逻辑(processControllerData)
|
||||
------------------------------------- */
|
||||
#ifndef XBOX_BLUETOOTH_H
|
||||
#define XBOX_BLUETOOTH_H
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <XboxSeriesXControllerESP32_asukiaaa.hpp> // Xbox手柄库
|
||||
#include <XboxSeriesXControllerESP32_asukiaaa.hpp>
|
||||
|
||||
/************ Xbox手柄全局实体 *************/
|
||||
// 连接目标手柄的MAC地址(保持原地址不变)
|
||||
/************ 全局实体与状态变量 *************/
|
||||
XboxSeriesXControllerESP32_asukiaaa::Core xboxController("0a:27:12:5c:71:79");
|
||||
XboxSeriesXHIDReportBuilder_asukiaaa::ReportBase repo;
|
||||
|
||||
// 跟踪手柄连接状态(用于检测首次连接和断开)
|
||||
bool wasConnected = 0; // 是否链接
|
||||
|
||||
// 震动状态机(关键:记录当前处于震动的哪个阶段)
|
||||
enum VibrateState {
|
||||
VIBRATE_OFF, // 未震动
|
||||
VIBRATE_STARTED, // 已发送开启指令,等待关闭
|
||||
VIBRATE_TRIGGER // 扳机键震动状态(单独管理)
|
||||
};
|
||||
VibrateState vibrateState = VIBRATE_OFF;
|
||||
unsigned long vibrateStartMs = 0; // 震动开始的时间戳
|
||||
const unsigned long KEY_VIBRATE_DURATION = 200; // 按键震动持续时间
|
||||
const unsigned long TRIGGER_VIBRATE_DURATION = 300; // 扳机震动持续时间
|
||||
|
||||
/************ 外部函数声明 *************/
|
||||
// 声明主文件中的数据处理函数(在主文件中实现)
|
||||
extern void processControllerData(const XboxControllerNotificationParser& data);
|
||||
|
||||
/************ 蓝牙手柄核心函数 *************/
|
||||
/************ 核心函数 *************/
|
||||
|
||||
// 初始化蓝牙手柄(供主文件setup()调用)
|
||||
void xboxControllerInit() {
|
||||
// 启动蓝牙连接
|
||||
xboxController.begin();
|
||||
vibrateState = VIBRATE_OFF; // 初始化状态
|
||||
}
|
||||
|
||||
// 处理蓝牙手柄通知(循环调用,保持连接并接收数据)
|
||||
void process_xbox_notif() {
|
||||
xboxController.onLoop(); // 维持蓝牙连接状态
|
||||
// 非阻塞震动状态更新(必须在主循环中调用)
|
||||
void updateXboxVibration() {
|
||||
unsigned long currentMs = millis();
|
||||
|
||||
if (xboxController.isConnected()) {
|
||||
if (xboxController.isWaitingForFirstNotification()) {
|
||||
// 可添加调试信息(如"等待手柄数据...")
|
||||
} else {
|
||||
// 接收数据后,调用主文件的解析函数
|
||||
processControllerData(xboxController.xboxNotif);
|
||||
// 处理按键震动的"开启→等待→关闭"流程
|
||||
if (vibrateState == VIBRATE_STARTED) {
|
||||
// 检查是否达到震动持续时间
|
||||
if (currentMs - vibrateStartMs >= KEY_VIBRATE_DURATION) {
|
||||
// 执行原函数中delay后的关闭逻辑
|
||||
repo.v.power.center = 0;
|
||||
repo.v.power.shake = 0;
|
||||
xboxController.writeHIDReport(repo);
|
||||
vibrateState = VIBRATE_OFF; // 回到未震动状态
|
||||
}
|
||||
}
|
||||
// 处理扳机键震动的关闭逻辑
|
||||
else if (vibrateState == VIBRATE_TRIGGER) {
|
||||
if (currentMs - vibrateStartMs >= TRIGGER_VIBRATE_DURATION) {
|
||||
repo.v.power.center = 0;
|
||||
repo.v.power.shake = 0;
|
||||
xboxController.writeHIDReport(repo);
|
||||
vibrateState = VIBRATE_OFF;
|
||||
}
|
||||
} else {
|
||||
// 可添加调试信息(如"手柄未连接")
|
||||
}
|
||||
}
|
||||
|
||||
#endif // XBOX_BLUETOOTH_H
|
||||
|
||||
// 按键震动(完整复现原逻辑的非阻塞版本)
|
||||
void XboxKeyVibration() {
|
||||
// 若正在震动,先重置状态(避免重复触发导致混乱)
|
||||
if (vibrateState != VIBRATE_OFF) {
|
||||
repo.v.power.center = 0;
|
||||
repo.v.power.shake = 0;
|
||||
xboxController.writeHIDReport(repo);
|
||||
}
|
||||
|
||||
// 执行原函数中delay前的开启逻辑
|
||||
repo.setAllOff();
|
||||
repo.v.select.center = true;
|
||||
repo.v.select.left = true;
|
||||
repo.v.select.right = true;
|
||||
repo.v.select.shake = true;
|
||||
repo.v.power.center = 20; // 30% power
|
||||
repo.v.power.shake = 20;
|
||||
repo.v.timeActive = 10; // x/100 second
|
||||
xboxController.writeHIDReport(repo);
|
||||
|
||||
// 记录开始时间,进入"等待关闭"状态(替代delay(250))
|
||||
vibrateState = VIBRATE_STARTED;
|
||||
vibrateStartMs = millis();
|
||||
}
|
||||
|
||||
// 扳机键震动(同样保留完整时序)
|
||||
void XboxtrigRTVibration() {
|
||||
static uint16_t TrigMax = XboxControllerNotificationParser::maxTrig;
|
||||
uint8_t power = (uint8_t)((float)xboxController.xboxNotif.trigRT / TrigMax * 100) * 0.5;
|
||||
|
||||
// 若扳机键松开,直接关闭震动
|
||||
if (power == 0) {
|
||||
repo.v.power.center = 0;
|
||||
repo.v.power.shake = 0;
|
||||
xboxController.writeHIDReport(repo);
|
||||
vibrateState = VIBRATE_OFF;
|
||||
return;
|
||||
}
|
||||
|
||||
// 执行开启震动逻辑
|
||||
repo.setAllOff();
|
||||
repo.v.select.center = true;
|
||||
repo.v.select.left = true;
|
||||
repo.v.select.right = true;
|
||||
repo.v.select.shake = true;
|
||||
repo.v.power.center = power;
|
||||
repo.v.power.shake = power;
|
||||
repo.v.timeActive = 10;
|
||||
xboxController.writeHIDReport(repo);
|
||||
|
||||
// 进入扳机震动状态,等待关闭
|
||||
vibrateState = VIBRATE_TRIGGER;
|
||||
vibrateStartMs = millis();
|
||||
}
|
||||
|
||||
void process_xbox_notif() {
|
||||
xboxController.onLoop();
|
||||
if (xboxController.isConnected() && !xboxController.isWaitingForFirstNotification()) {
|
||||
if(!wasConnected){ // 原来未链接,现在链接成功
|
||||
XboxKeyVibration();
|
||||
wasConnected = 1;
|
||||
}
|
||||
processControllerData(xboxController.xboxNotif);
|
||||
}else{
|
||||
if(wasConnected){ // 原来是链接成功的,说明断了
|
||||
XboxKeyVibration();
|
||||
wasConnected = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // XBOX_BLUETOOTH_H
|
||||
Reference in new issue
Block a user