FastBond4挑战部分-基于ESP32S2实现RC遥控器
基于 ESP32-S2-WROVER-N4R2 模块的RC遥控器,专用于坦克模型或其它多通道遥控设备。该遥控器支持最多 16个控制通道,采用 ESP-NOW 无线通信协议,具备低延迟、高响应、多输入源等特点。
标签
ESP32
物联网
控制
乐鑫
遥控器
FastBond4
ESP-NOW
RC遥控
航模遥控
RC
鲜de芒果
更新2026-04-13
6
KiCad文件
全屏

一、项目介绍

本项目设计并实现了一款基于 ESP32-S2-WROVER-N4R2 模块的RC遥控器,专用于坦克模型或其它多通道遥控设备。该遥控器支持最多 16个控制通道,采用 ESP-NOW 无线通信协议,具备低延迟、高响应、多输入源等特点。硬件上集成了摇杆、电位器、按键等多种输入方式,并预留了SPI/I2C扩展接口,便于后续功能升级。项目基于 PlatformIO 平台开发,代码结构清晰,易于维护与二次开发。


1.1 硬件介绍

本遥控器硬件核心为 ESP32-S2-WROVER-N4R2 模组,其主要外围电路包括:

  • 2路摇杆输入:每路摇杆提供 X、Y 两个模拟轴,共实现 4通道模拟输入。
  • 2路电位器输入:独立线性电位器,用于调节额外模拟量(如油门微调、舵量比例)。
  • 2路摇杆按键:按压摇杆触发,可作为数字开关。
  • 8路独立按键:用于模式切换、功能触发等。
  • 供电系统:默认支持 1S锂电池(3.7V~4.2V);若更换LDO芯片(如从3.3V LDO换为宽压型),可支持2S电池(7.4V)。
  • 预留接口
    • SPI 2.4G模拟接口(可外接NRF24L01等)
    • SPI显示模块接口
    • I2C OLED接口(如SSD1306)


1.2 功能概览

功能项

说明

通道数

最大支持16通道数据发送,当前硬件提供6个模拟通道 + 10个数字通道(可配置为开关通道)

无线协议

ESP-NOW(点对点或广播,低功耗、低延迟)

输入设备

2×摇杆(4轴)、2×电位器、2×摇杆按键、8×独立按键

状态指示

(可选)通过预留I2C接口连接OLED显示通道值及连接状态

开发平台

PlatformIO + Arduino 框架

供电方式

1S锂电池(未集成则外部充电)


1.3 设计思路

  1. 模块化输入采集:每个输入设备(摇杆、电位器、按键)独立读取,软件中统一转换为0~255或0~100%的标准化数值。
  2. 通道映射:物理输入可灵活映射到16个逻辑通道中,例如摇杆左X→通道1,左Y→通道2,电位器1→通道5等。
  3. 低延迟通信:ESP-NOW无需连接路由器,直接MAC层通信,延迟<10ms,适合实时遥控。
  4. 扩展性:预留SPI/I2C接口,未来可增加显示屏、2.4G备份链路、舵机反馈等。


二、功能实现

2.1 硬件设计

硬件框图


2.2 软件流程图

2.3 软件代码实现

以下为核心代码片段(基于PlatformIO + Arduino框架)。


2.3.1. 数据结构定义

定义控制数据包结构体(与接收端约定一致):

struct Data_Package {
uint8_t leftJoystickX; // 左摇杆 X
uint8_t leftJoystickY; // 左摇杆 Y
uint8_t rightJoystickX; // 右摇杆 X
uint8_t rightJoystickY; // 右摇杆 Y
uint8_t leftJoystickBtn:1; // 左摇杆按键
uint8_t rightJoystickBtn:1; // 右摇杆按键
uint8_t leftSwitch1:1; // 左按键开关1
uint8_t leftSwitch2:1; // 左按键开关2 和 左按键开关1 反相
uint8_t rightSwitch1:1; // 右按键开关1
uint8_t rightSwitch2:1; // 右按键开关2 和 右按键开关1 反相
uint8_t leftPotentiometer; // 左电位器
uint8_t rightPotentiometer; // 右电位器
};


2.3.2. 初始化ESP-NOW

// 初始化 ESP-NOW
Serial.println("Initializing ESP-NOW...");
delay(100);
WiFi.mode(WIFI_STA);
Serial.println("InitESPNow");
// Init ESPNow with a fallback logic
InitESPNow();

// 设置发送数据回调函数
esp_now_register_send_cb(OnDataSent);


2.3.3. 模拟输入读取(ADC)

int potValues[NUMBER_OF_POT_SAMPLES];
int potValues2[NUMBER_OF_POT_SAMPLES];
int potValues3[NUMBER_OF_POT_SAMPLES];
int potValues4[NUMBER_OF_POT_SAMPLES];
// 连续采样 NUMBER_OF_POT_SAMPLES 个数据,间隔 DELAY_BETWEEN_SAMPLES 毫秒。这里不应该这样做,虽然没有什么大问题,但会使的采样慢,导致整个运行效率过低 TODO 待优化
for (int i = 0 ; i < NUMBER_OF_POT_SAMPLES ; i++) {
potValues[i] = analogRead(LEFT_JOYSTICK_X_PIN);
potValues2[i] = analogRead(LEFT_JOYSTICK_Y_PIN);
potValues3[i] = analogRead(RIGHT_JOYSTICK_X_PIN);
potValues4[i] = analogRead(RIGHT_JOYSTICK_Y_PIN);
delay(DELAY_BETWEEN_SAMPLES);
}
// 计算 左 摇杆 X 轴采样均值。
int potValue = 0;
for (int i = 0 ; i < NUMBER_OF_POT_SAMPLES ; i++) {
potValue += potValues[i];
}
potValue = potValue / NUMBER_OF_POT_SAMPLES;
LX_read = map(potValue, 0, 4095, 0, 255);
// 计算 左 摇杆 Y 轴采样均值。
int potValue2 = 0;
for (int i = 0 ; i < NUMBER_OF_POT_SAMPLES ; i++) {
potValue2 += potValues2[i];
}
potValue2 = potValue2 / NUMBER_OF_POT_SAMPLES;
LY_read = map(potValue2, 0, 4095, 255, 0);

// 计算 右 摇杆 X 轴采样均值。
int potValue3 = 0;
for (int i = 0 ; i < NUMBER_OF_POT_SAMPLES ; i++) {
potValue3 += potValues3[i];
}
potValue3 = potValue3 / NUMBER_OF_POT_SAMPLES;
RX_read = map(potValue3, 0, 4095, 255, 0);

// 计算 右 摇杆 Y 轴采样均值。
int potValue4 = 0;
for (int i = 0 ; i < NUMBER_OF_POT_SAMPLES ; i++) {
potValue4 += potValues4[i];
}
potValue4 = potValue4 / NUMBER_OF_POT_SAMPLES;
RY_read = map(potValue4, 0, 4095, 255, 0);


2.3.4. 通道映射与发送

data.leftJoystickX = LX_to_send;
data.leftJoystickY = LY_to_send;
data.rightJoystickX = RX_to_send;
data.rightJoystickY = RY_to_send;
data.leftJoystickBtn = !digitalRead(LEFT_JOYSTICK_BUTTON_PIN);
data.rightJoystickBtn = !digitalRead(RIGHT_JOYSTICK_BUTTON_PIN);
data.upBtnLeft = !digitalRead(LEFT_UP_BUTTON_PIN);
data.downBtnLeft = !digitalRead(LEFT_DOWN_BUTTON_PIN);
data.leftBtnLeft = !digitalRead(LEFT_LEFT_BUTTON_PIN);
data.rightBtnLeft = !digitalRead(LEFT_RIGHT_BUTTON_PIN);
data.upBtnRight = !digitalRead(RIGHT_UP_BUTTON_PIN);
data.downBtnRight = !digitalRead(RIGHT_DOWN_BUTTON_PIN);
data.leftBtnRight = !digitalRead(RIGHT_LEFT_BUTTON_PIN);
data.rightBtnRight = !digitalRead(RIGHT_RIGHT_BUTTON_PIN);
data.leftPotentiometer = 255 - map(lp, 120, 4095, 0, 255);
data.rightPotentiometer = map(rp, 120, 4095, 0, 255);

// 发送数据 send data
void sendData() { //uint8_t data
esp_now_send(broadcastAddress, (uint8_t *) &data, sizeof(data));
}


三、功能展示

硬件展示

原理图


PCB 3D预览


PCB实物


实测效果

  1. 模拟通道响应:摇杆和电位器线性度良好,ADC 12位分辨率,经映射后输出0~255连续变化。
  2. 数字按键:8个独立按键及摇杆按键无抖动误触发(软件已做简单去抖)。
  3. 无线通信:ESP-NOW在开阔地有效距离约100米,数据丢包率低于1%(每1000包重传小于10次)。
  4. 通道数验证:通过串口监视器打印发送的16个通道值,全部可正确接收并解析。


测试环境使用一块 Seeed Studio XIAO ESP32C3 开发板作为接收机,接收遥控器发送的 ESPNOW 数据包并通过串口发送至上位机,上位机以图形方式展示各通道的数值。


四、总结

遇到的问题

  1. 忘记增加板载充电电路(TP4056等),无法实现Type-C直充还是有些不太方便的。
  2. 摇杆的质量比较差,每过一段时间就会出现飘移的现象。
  3. 右电位器在旋转到最小位置时会出现跳变,导致采集到的数值0偶尔会跳变成为255。


心得体会

本项目成功基于ESP32-S2设计并实现了一款功能完备、扩展性强的RC遥控器。6个模拟输入 + 10个数字输入,满足大多数坦克、机器人、航模控制需求。 ESP-NOW协议在保证低延迟的同时,具备较好的抗干扰能力。通道映射、数据比例均可通过修改代码灵活调整,便于适配不同接收机。本项目代码已开源,所有原理图及PlatformIO工程文件均可提供,可作为DIY遥控器或教学实验平台使用。


最后,感谢硬禾学堂联合 DigiKey 推出的这次活动!此次活动带给我许多宝贵实践经验和机会,在此表示感谢!


五、参考资料

附件下载
fastbond4-transmitter.zip
PlatformIO 工程源码
ProPrj_ESP32S2遥控器_2026-04-10-2026-04-10_132720.zip
KiCAD 9.0 工程备份
团队介绍
业余电子爱好者
团队成员
业余电子爱好者
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号