电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
开源自制的6通道航模遥控器,超简单不超过100行代码
分 享
扫描二维码分享
开源自制的6通道航模遥控器,超简单不超过100行代码
航模遥控器
开源
电子芯吧客
关注
发布时间: 2020-09-17
丨
阅读: 3935
前言 前段时间跟着LOLI大神的教程制作了LOLI三代控,效果很好。但是,由于LOLI三代控的接收机带有数据回传功能,也就是接收机的无线模块也承担了发射数据功能,所以接收机也要使用带有功率放大芯片的NRF24L01模块才能实现远距离通信,这不仅抬高了成本还带来了体积的增加。于是笔者打算自制一个较简单的6通道航模遥控器,正好手上有一个没有接收机的天地飞-06X,决定对其进行改造,一番查阅资料后用Arduino Pro Mini开发板实现了基础的功能,效果还不错。 #### 1.材料清单 - USB转TTL模块*1 - Arduino Pro Mini开发板*2 - NRF24L01无线通信模块*2 - ams1117-3.3电压转换芯片1个 - 100uF电解电容*2 - 104电容*2 - 三脚开关*4 - 10k电阻*1,20k电阻*1 - 导线及插针若干 #### 2. 硬件部分 按照原理图焊接电路,尽情飞线叭,有条件的话可以设计PCB做的好看一些。 a)遥控器端 遥控器端负责发送数据,所以使用可以无线透传2000m的NRF24L01无线通信模块; ![](https://cf01.ickimg.com/bbsimages/202009/55cfbcfd03da3807a5ba032326cb91cf.png) ![](https://cf01.ickimg.com/bbsimages/202009/ef00599ef1e0b01766c3840dfe1c52e6.png) 笔者的飞线不忍直视 ,100m的NRF24L01模块不够用,果断换了2000m的。 ![](https://cf01.ickimg.com/bbsimages/202009/efede38b3695a2e26a2dc2f4981950d6.png) ![](https://cf01.ickimg.com/bbsimages/202009/640020d009327e709e169badbbaf6acf.png) b)接收机端 接收机端负责接收数据,使用100m的NRF24L01无线通信模块足够了。 ![](https://cf01.ickimg.com/bbsimages/202009/9888baf53a7d6c67dfe404685f7e635a.png) ![](https://cf01.ickimg.com/bbsimages/202009/713e88209ca18eb40fad0b05489360d6.png) ![](https://cf01.ickimg.com/bbsimages/202009/4cb99308c672dadc271a6d3a6374dc52.png) ![](https://cf01.ickimg.com/bbsimages/202009/f13e35b87027a3f9a0fe1905335ce41e.png) 3. 软件部分 a)遥控器端 将USB转TTL模块连接电脑,引脚接线如下: TX0--RXD RX1--TXD VCC--3V3 GND--GND 打开Arduino IDE,选择遥控器端的程序打开,这里要下载RF24封装库,下载方法如下: 项目》加载库》管理库,打开库管理器 ![](https://cf01.ickimg.com/bbsimages/202009/e6dd4c1cac9b13c2ec87674371d18f76.png) 输入RF24搜索,选择图中的库进行安装,安装完毕后点击关闭; ![](https://cf01.ickimg.com/bbsimages/202009/5a7f617dc8449a2c2c0c9de6506830d6.png) 烧写程序之前,要先选择自己的开发板型号,如下图,处理器选择自己的开发板类型,端口选择USB转TTL所在的端口号 ![](https://cf01.ickimg.com/bbsimages/202009/23fb4276695f87b78f415596f1008158.png) 点击上传,烧写程序; ![](https://cf01.ickimg.com/bbsimages/202009/094bda1ae6e15cf795987235d846e79f.png) 通信地址可以改为自己喜欢的地址,每个位是十六进制(0~9、A~F) ; ![](https://cf01.ickimg.com/bbsimages/202009/d500ac5928fa9cb6272d677e3f5a7504.png) 向各个方向拨动摇杆,通过串口监视器查看输出值,然后把每个通道的最小值、 中值、最大值填入程序中,最后再上传一次代码。 ![](https://cf01.ickimg.com/bbsimages/202009/b95e7e811feef788d7040d58ea04a538.png) 完整的Arduino代码如下: ```c /@@* ArduinoProMini-6通道发射器 * by Bilibili 蔡子CaiZi * * A0~5 -> 模拟输入,2~5 -> 通道正反开关 * A6 -> 电压检测 * 6 -> 蜂鸣器 * * NRF24L01 | Arduino * CE -> 7 * CSN -> 8 * MOSI -> 11 * MISO -> 12 * SCK -> 13 * IRQ -> 无连接 * VCC -> 小于3.6V * GND -> GND */ #include
#include
#include
const uint64_t pipeOut = 0xBBBBBBBBB; //为何这么多B币?与接收器中相同的地址进行通信 RF24 radio(7, 8); // SPI通信,引脚对应关系:CE ->7,CSN ->8 struct Signal { byte roll; byte pitch; byte throttle; byte yaw; byte gyr; byte pit; }; Signal data; void ResetData() { data.roll = 127; // 横滚通道AIL(中心点127) data.pitch = 127; // 俯仰通道ELE data.throttle = 0; // 信号丢失时,关闭油门THR data.yaw = 127; // 航向通道RUD data.gyr = 0; //第五通道 data.pit = 0; //第六通道 } void setup() { radio.begin(); radio.openWritingPipe(pipeOut);//pipeOut通信地址 radio.stopListening(); //发射模式 ResetData();//初始化6个通道值 Serial.begin(115200); pinMode(2,INPUT);//正反通道开关为数字输入 pinMode(3,INPUT); pinMode(4,INPUT); pinMode(5,INPUT); pinMode(6,OUTPUT);//蜂鸣器推挽输出 if (analogRead(A6)*3.28*3/1023<5){//调整3校准电压检测,5为报警电压 for(int i=0;i<3;i++){ digitalWrite(6,HIGH);//蜂鸣器响 delay(100); digitalWrite(6,LOW); delay(100); } } else{ digitalWrite(6,HIGH);//蜂鸣器响 delay(100); digitalWrite(6,LOW); } } // 将ADC获取的0~1023转换到0~255 int chValue(int val, int lower, int middle, int upper, bool reverse) { val = constrain(val, lower, upper);//将val限制在lower~upper范围内 if ( val < middle ) val = map(val, lower, middle, 0, 128); else val = map(val, middle, upper, 128, 255); return ( reverse ? 255 - val : val ); } void loop() { Serial.print("\t");Serial.print(analogRead(A0));//将数据通过串口输出 Serial.print("\t");Serial.print(analogRead(A1)); Serial.print("\t");Serial.print(analogRead(A2)); Serial.print("\t");Serial.println(analogRead(A3)); // 需要对摇杆的最值、中值进行设置 data.roll = chValue( analogRead(A0), 59, 517, 882, digitalRead(2)); data.pitch = chValue( analogRead(A1), 115, 525, 896, digitalRead(3)); data.throttle = chValue( analogRead(A2), 145, 522, 920, digitalRead(4)); data.yaw = chValue( analogRead(A3), 70, 530, 925, digitalRead(5)); data.gyr = chValue( analogRead(A4), 0, 510, 1020, false ); data.pit = chValue( analogRead(A5), 0, 510, 1020, false ); radio.write(&data, sizeof(Signal));//将数据发送出去 // Serial.print("\t");Serial.print(data.roll); // Serial.print("\t");Serial.print(data.pitch); // Serial.print("\t");Serial.print(data.throttle); // Serial.print("\t");Serial.print(data.yaw); // Serial.print("\t");Serial.print(data.gyr); // Serial.print("\t");Serial.println(data.pit); } ``` b)接收机端 接收机端的下载操作与遥控器端的操作基本相同,这里不再赘述了,完整代码如下: ```c /@@* ArduinoProMini-6通道接收机 * by Bilibili 蔡子CaiZi * * PWM输出 -> 引脚2~6、9 * * NRF24L01 | Arduino * CE -> 7 * CSN -> 8 * MOSI -> 11 * MISO -> 12 * SCK -> 13 * IRQ -> 无连接 * VCC -> 小于3.6V * GND -> GND */ #include
#include
#include
#include
int ch_width_1 = 0, ch_width_2 = 0, ch_width_3 = 0, ch_width_4 = 0, ch_width_5 = 0, ch_width_6 = 0; Servo ch1; Servo ch2; Servo ch3; Servo ch4; Servo ch5; Servo ch6; struct Signal { byte roll; byte pitch; byte throttle; byte yaw; byte gyr; byte pit; }; Signal data; const uint64_t pipeIn = 0xBBBBBBBBB;//与发射端地址相同 RF24 radio(7, 8); void ResetData() { data.roll = 127; // 横滚通道中心点(254/2 = 127) data.pitch = 127; // 俯仰通道 data.throttle = 0; // 信号丢失时,关闭油门 data.yaw = 127; // 航向通道 data.gyr = 0; //第五通道 data.pit = 0; //第六通道 } void setup() { //设置PWM信号输出引脚 ch1.attach(2); ch2.attach(3); ch3.attach(4); ch4.attach(5); ch5.attach(6); ch6.attach(9); //配置NRF24L01模块 ResetData(); radio.begin(); radio.openReadingPipe(1,pipeIn);//与发射端地址相同 radio.startListening(); //接收模式 pinMode(LED_BUILTIN,OUTPUT);//LED推挽输出 digitalWrite(LED_BUILTIN,HIGH); Serial.begin(115200); } unsigned long lastRecvTime = 0; void recvData() { while ( radio.available() ) { radio.read(&data, sizeof(Signal));//接收数据 lastRecvTime = millis(); //当前时间ms } } void loop() { recvData(); unsigned long now = millis(); if ( now - lastRecvTime > 1000 ) { ResetData(); //两次接收超过1s表示失去信号,输出reset值 // Serial.print("无信号"); digitalWrite(LED_BUILTIN,HIGH); } else{ digitalWrite(LED_BUILTIN,LOW); } ch_width_1 = map(data.roll, 0, 255, 1000, 2000);// 将0~255映射到1000~2000,即1ms~2ms/20ms的PWM输出 ch_width_2 = map(data.pitch, 0, 255, 1000, 2000); ch_width_3 = map(data.throttle, 0, 255, 1000, 2000); ch_width_4 = map(data.yaw, 0, 255, 1000, 2000); ch_width_5 = map(data.gyr, 0, 255, 1000, 2000); ch_width_6 = map(data.pit, 0, 255, 1000, 2000); Serial.print("\t");Serial.print(ch_width_1); Serial.print("\t");Serial.print(ch_width_2); Serial.print("\t");Serial.print(ch_width_3); Serial.print("\t");Serial.print(ch_width_4); Serial.print("\t");Serial.print(ch_width_5); Serial.print("\t");Serial.println(ch_width_6); // 将PWM信号输出至引脚 ch1.writeMicroseconds(ch_width_1);//写入us值 ch2.writeMicroseconds(ch_width_2); ch3.writeMicroseconds(ch_width_3); ch4.writeMicroseconds(ch_width_4); ch5.writeMicroseconds(ch_width_5); ch6.writeMicroseconds(ch_width_6); } ``` 实际拉距测试中,无线传输500m没有压力。现在只是实现了基础的6通道遥控功能,后期再不断优化改进,计划改进方向: 1. 遥控器端,加入OLED显示屏+按键检测,方便人机交互操作; 2. 接收机端,加入SBUS输出、PPM输出。 原文来自:蔡子CaiZi(b站专栏)
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
2
)
电子芯吧客
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交