183 lines
5.9 KiB
Arduino
183 lines
5.9 KiB
Arduino
#include <Arduino.h>
|
||
#include <WiFi.h>
|
||
#include <esp_now.h>
|
||
|
||
// 1. 16个手柄引脚定义(4个摇杆轴 + 12个按键)
|
||
// 摇杆轴引脚(模拟输入)
|
||
// 4个摇杆轴
|
||
// int joyLeftX; // 左-右,0-940 ,中心默认:423
|
||
// int joyLeftY; // 上-下,940-0 ,中心默认:425
|
||
// int joyRightX; // 左-右,0-960:中心默认:487
|
||
// int joyRightY; // 上-下,1080-0,中心默认:525
|
||
|
||
#define JOY_LEFT_X 4 // 左摇杆X轴
|
||
#define JOY_LEFT_Y 5 // 左摇杆Y轴
|
||
#define JOY_RIGHT_X 7 // 右摇杆X轴
|
||
#define JOY_RIGHT_Y 8 // 右摇杆Y轴
|
||
|
||
// 按键引脚(数字输入,需设为INPUT_PULLUP)
|
||
#define BTN_JOY_LEFT 6 // 左摇杆按压键
|
||
#define BTN_JOY_RIGHT 9 // 右摇杆按压键
|
||
#define BTN_START 0 // Start键
|
||
#define BTN_BACK 1 // Back键
|
||
#define BTN_UP 10 // 方向上键
|
||
#define BTN_DOWN 11 // 方向下键
|
||
#define BTN_LEFT 12 // 方向左键
|
||
#define BTN_RIGHT 13 // 方向右键
|
||
#define BTN_A 16 // A键
|
||
#define BTN_B 21 // B键
|
||
#define BTN_X 14 // X键
|
||
#define BTN_Y 15 // Y键
|
||
|
||
// 摇杆参数
|
||
#define DEAD_ZONE 5 // 死区范围
|
||
#define LEFT_X_CENTER 423
|
||
#define LEFT_Y_CENTER 425
|
||
#define RIGHT_X_CENTER 487
|
||
#define RIGHT_Y_CENTER 525
|
||
|
||
// 2. GamepadData结构体:16个成员对应16个参数
|
||
struct GamepadData {
|
||
// 4个摇杆轴(优化后范围:-100到100)
|
||
int joyLeftX;
|
||
int joyLeftY;
|
||
int joyRightX;
|
||
int joyRightY;
|
||
|
||
// 12个按键(布尔值:1=按下,0=未按下)
|
||
bool btnJoyLeft;
|
||
bool btnJoyRight;
|
||
bool btnStart;
|
||
bool btnBack;
|
||
bool btnUp;
|
||
bool btnDown;
|
||
bool btnLeft;
|
||
bool btnRight;
|
||
bool btnA;
|
||
bool btnB;
|
||
bool btnX;
|
||
bool btnY;
|
||
} gamepadData;
|
||
|
||
// 3. ESP-NOW相关配置
|
||
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; // 广播地址
|
||
esp_now_peer_info_t peerInfo;
|
||
|
||
|
||
// 发送状态回调函数
|
||
// void OnDataSent(const wifi_tx_info_t *tx_info, esp_now_send_status_t status) {
|
||
// // Serial.print("发送状态: ");
|
||
// // Serial.println(status == ESP_NOW_SEND_SUCCESS ? "成功" : "失败");
|
||
// }
|
||
|
||
// 4. 读取16个手柄参数的函数
|
||
void readGamepad() {
|
||
|
||
// 转换摇杆值
|
||
gamepadData.joyLeftX = analogRead(JOY_LEFT_X);
|
||
gamepadData.joyLeftY = analogRead(JOY_LEFT_Y);
|
||
gamepadData.joyRightX = analogRead(JOY_RIGHT_X);
|
||
gamepadData.joyRightY = analogRead(JOY_RIGHT_Y);
|
||
|
||
// 读取12个按键状态(INPUT_PULLUP模式:LOW=按下,转为1)
|
||
gamepadData.btnJoyLeft = (digitalRead(BTN_JOY_LEFT) == LOW);
|
||
gamepadData.btnJoyRight = (digitalRead(BTN_JOY_RIGHT) == LOW);
|
||
gamepadData.btnStart = (digitalRead(BTN_START) == LOW);
|
||
gamepadData.btnBack = (digitalRead(BTN_BACK) == LOW);
|
||
gamepadData.btnUp = (digitalRead(BTN_UP) == LOW);
|
||
gamepadData.btnDown = (digitalRead(BTN_DOWN) == LOW);
|
||
gamepadData.btnLeft = (digitalRead(BTN_LEFT) == LOW);
|
||
gamepadData.btnRight = (digitalRead(BTN_RIGHT) == LOW);
|
||
gamepadData.btnA = (digitalRead(BTN_A) == LOW);
|
||
gamepadData.btnB = (digitalRead(BTN_B) == LOW);
|
||
gamepadData.btnX = (digitalRead(BTN_X) == LOW);
|
||
gamepadData.btnY = (digitalRead(BTN_Y) == LOW);
|
||
}
|
||
|
||
void setup() {
|
||
// 初始化串口(波特率115200)
|
||
Serial.begin(115200);
|
||
|
||
// 明确设置ADC参数
|
||
analogReadResolution(12); // 12位分辨率 (0-4095)
|
||
analogSetAttenuation(ADC_11db); // 全量程0-3.3V
|
||
|
||
// 初始化12个按键引脚为上拉输入
|
||
pinMode(BTN_JOY_LEFT, INPUT_PULLUP);
|
||
pinMode(BTN_JOY_RIGHT, INPUT_PULLUP);
|
||
pinMode(BTN_START, INPUT_PULLUP);
|
||
pinMode(BTN_BACK, INPUT_PULLUP);
|
||
pinMode(BTN_UP, INPUT_PULLUP);
|
||
pinMode(BTN_DOWN, INPUT_PULLUP);
|
||
pinMode(BTN_LEFT, INPUT_PULLUP);
|
||
pinMode(BTN_RIGHT, INPUT_PULLUP);
|
||
pinMode(BTN_A, INPUT_PULLUP);
|
||
pinMode(BTN_B, INPUT_PULLUP);
|
||
pinMode(BTN_X, INPUT_PULLUP);
|
||
pinMode(BTN_Y, INPUT_PULLUP);
|
||
|
||
// 初始化WiFi为STA模式
|
||
WiFi.mode(WIFI_STA);
|
||
// 明确设置WiFi信道
|
||
WiFi.setChannel(6);
|
||
WiFi.disconnect(); // 断开自动连接
|
||
Serial.println("WiFi初始化完成");
|
||
|
||
|
||
// 初始化ESP-NOW
|
||
if (esp_now_init() != ESP_OK) {
|
||
Serial.println("ESP-NOW初始化失败");
|
||
return;
|
||
}
|
||
Serial.println("ESP-NOW初始化成功");
|
||
|
||
// 注册发送回调函数
|
||
// esp_now_register_send_cb(OnDataSent);
|
||
|
||
// 设置广播对等体(通道6)
|
||
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
|
||
peerInfo.channel = 6; // 设置WiFi通道为6
|
||
peerInfo.encrypt = false; // 不加密
|
||
|
||
// 添加对等体
|
||
if (esp_now_add_peer(&peerInfo) != ESP_OK) {
|
||
Serial.println("添加对等体失败");
|
||
return;
|
||
}
|
||
Serial.println("广播对等体添加成功,通道: 6");
|
||
}
|
||
|
||
void loop() {
|
||
// 读取手柄数据
|
||
readGamepad();
|
||
|
||
// 通过ESP-NOW发送数据
|
||
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &gamepadData, sizeof(gamepadData));
|
||
|
||
// 串口打印16个参数
|
||
Serial.print("joyLeftX:"); Serial.print(gamepadData.joyLeftX);
|
||
Serial.print(" ,joyLeftY:"); Serial.print(gamepadData.joyLeftY);
|
||
Serial.print(" ,joyRightX:"); Serial.print(gamepadData.joyRightX);
|
||
Serial.print(" ,joyRightY:"); Serial.print(gamepadData.joyRightY);
|
||
|
||
Serial.print(" ,btnJoyLeft:"); Serial.print(gamepadData.btnJoyLeft);
|
||
Serial.print(" ,btnJoyRight:"); Serial.print(gamepadData.btnJoyRight);
|
||
Serial.print(" ,btnStart:"); Serial.print(gamepadData.btnStart);
|
||
Serial.print(" ,btnBack:"); Serial.print(gamepadData.btnBack);
|
||
Serial.print(" ,btnUp:"); Serial.print(gamepadData.btnUp);
|
||
Serial.print(" ,btnDown:"); Serial.print(gamepadData.btnDown);
|
||
Serial.print(" ,btnLeft:"); Serial.print(gamepadData.btnLeft);
|
||
Serial.print(" ,btnRight:"); Serial.print(gamepadData.btnRight);
|
||
Serial.print(" ,btnA:"); Serial.print(gamepadData.btnA);
|
||
Serial.print(" ,btnB:"); Serial.print(gamepadData.btnB);
|
||
Serial.print(" ,btnX:"); Serial.print(gamepadData.btnX);
|
||
Serial.print(" ,btnY:"); Serial.print(gamepadData.btnY);
|
||
|
||
if (result == ESP_OK) {
|
||
Serial.println(" -ESPNOW OK");
|
||
} else {
|
||
Serial.println(" -ESPNOW FAILED");
|
||
}
|
||
|
||
delay(100); // 100ms刷新一次
|
||
} |