Mech-Snake

两种PS2遥控器兼容性设置

两种用于遥控机器人PS2手柄的兼容设置细节

两种遥控器的对比

图一中描述的遥控器处理器为ESP32S2,可以通过程序下载口对手柄遥控器进行个性化编程。无线通信采用JDY-41模块,JDY-41手册标称通信距离为150米(无遮挡环境)。

图一:JDY-41无线通信手柄遥控器

对比JDY-41手柄,RC-TANK手柄不可进行个性化编程,但RC-TANK手柄的摇杆校正功能及匹配上位机软件较为健全。
对两款手柄进行兼容性设计的原因有三:

1. RC-TANK手柄的无线信号接收器需要特殊匹配,且接收器在正常工作时发热严重,且不能通过手柄控制当前机器人的无线控制方式(由手柄切换至计算机)。
2. RC-TANK手柄的成本是JDY-41的4倍。
3. RC-TANK不能通过编程对手柄内部的指示灯,振动器等配件进行个性化控制,对控制机器人进行操作反馈不友好。

基于以上原因,在后续开展的遥控试验中,将使用JDY-41遥控器逐步替代。通过个性化编程方式,将JDY-41按键及摇杆对应的无线传输数据帧格式与RC-TANK的进行兼容,以此达到平行替换目的。

图二:RC-TANK无线通信手柄遥控器
## 数据帧协议兼容

RC-TANK无线通信协议

通信数据帧的格式:帧头 + 通信代码 + 帧长度 + 数据 + 校验
数据帧长度:13

帧头:2 字节,固定为 0xAAAA,用于表示一次通信的开始,或者区分不同数据帧。
通信代码:1 字节,用来区分通信的类型(详见通信代码表)
帧长度:1 字节,本次通信数据帧长度,指包含帧头、通信代码、帧长度、数据和校验在内的总长度。
数据:若干字节,数据载荷,长度可变。
校验:16 位 CRC 校验值,MODBUS 格式。
通信代码表 #1
通信代码 说明
0x01 遥控指令,这是一条从手柄发往接收机的指令。手柄通过这条指令将摇杆、按键、手柄电量在内的所有信息发送给接收机,接收机再通过串口输出。发送频率为 50Hz。
0x09 反馈指令,这是一条从接收机发往手柄的指令,用来触发手柄震动。用户通过接收机的串口把这条指令发送给接收机,然后接收机通过无线发送给手柄,手柄发出震动。没有发送频率限制,用户可以根据需要去触发手柄震动。
0x15 下行透传指令,上位机通过 USB 把指令发送给手柄,手柄将指令发送给接收机,然后接收机通过串口输出。注意:长度不可以超过 26 字节。
0x1D 上行透传指令,用户通过接收机的串口把这条指令发送给接收机,然后接收机通过无线发送给手柄,手柄通过 USB 接口输出该指令。注意:长度不可以超过 26 字节
CRC16校验公式 #2
CRC 算法 多项式公式 宽度 多项式 初始值 异或值 输入反转 输出反转
MODBUS x16 + x15 + x2 + 1 16 8005 0xFFFF 0x0000 true true

CRC 算法的参考程序,见例程或校准软件。CRC16 计算页面链接(注意选 MODBUS 算法)https://www.23bei.com/tool-59.html

以下代码块为CRC16-modbus CRC校验代码(CRC-16-modbus (LSB-MSB)):
CRC16-modbus 头文件

#ifndef _CRC_16_H_
#define _CRC_16_H_
#include <arduino.h>
void update_crc(uint8_t* crc_sum, uint8_t *data_blk_ptr, uint8_t data_blk_size);
#endif

CRC16-modbus 源文件


/*standard CRC check cpp files*/
//CRC-16-modbus (LSB-MSB)
//calculation tools online:https://www.23bei.com/tool-59.html
//mode: CRC-16(Modbus)
#include "CRC16.h"

/*--------------------------------------------------------------------*/
/**
  * function: Modbus CRC16(LSB-MSB) calculation
  * update in 2022/03/17
  *   input paramenter: 
  *         data_blk_ptr: inital address of waiting calculation data, 
  *         usDataLen: length of data frame
  *   output parameter:
  *         crc_sum: CRC16-modbus results' inital address
  *   returned value:
  *         checked result - TRUE or FALSE (bool)   
  */
void update_crc(uint8_t* crc_sum, uint8_t *data_blk_ptr, uint8_t data_blk_size)
{
      unsigned int i;
      unsigned short crc = 0xFFFF;
      unsigned short crcl;

      while(data_blk_size--){
            crc ^= *data_blk_ptr++;
            for (i = 0; i < 8; ++i){
                  if (crc & 1)
                        crc = (crc >> 1) ^ 0xA001;
                  else
                        crc = (crc >> 1);
            }
      }
      crcl = crc;
      crc_sum[1] = (unsigned char)(crc>>8);
      crc_sum[0] = (unsigned char)(crcl);
}

/*----------------------End of file----------------------------------*/

RC-TANK手柄通信示例

0x01 指令:该指令是所有指令中最重要的指令,只有理解它的含义,才可以弄清楚手柄是如何控制其他设备的。指令中所有数据均为 16 进制,下边给出 0x01 指令的具体示例:
示例: AA AA 01 0D DF 7F 7F 7F 7F 00 00 D7 51
第 1、2 字节 0xAA,0xAA 为帧头,标志着一帧数据的开始。
第 3 字节 0x01 为命令代码。
第 4 字节 0x0D 为帧长度,这条指令长度为 13 个字节,用 16 进制表示就是 0x0D。
第 5 字节 0xDF 表示手柄电池此时的电压,计算公式:(0xDF +200)÷100=4.23V,此时手柄电池电压为 4.23V,其它值时以此类推。手柄低电量提醒电压为 3.8V,自动关机电压为3.75V。
第 6 字节为模拟通道 1,对应手柄左侧摇杆的水平方向,取值范围为 0x00~0xFF,中值为 0x7F。摇杆往左打极限值为 0xFF,往右打极限值为 0x00。
第 7 字节为模拟通道 2,对应手柄左侧摇杆的垂直方向,取值范围为 0x00~0xFF,中值为 0x7F。摇杆往下打极限值为 0xFF,往上打极限值为 0x00。
第 8 字节为模拟通道 3,对应手柄右侧摇杆的水平方向,取值范围为 0x00~0xFF,中值为 0x7F。摇杆往左打极限值为 0xFF,往右打极限值为 0x00。
第 9 字节为模拟通道 4,对应手柄右侧摇杆的垂直方向,取值范围为 0x00~0xFF,中值为 0x7F。摇杆往下打极限值为 0xFF,往上打极限值为 0x00。
第 10、11 字节,这两个字总共 16 位,对应手柄的 16 个通道。从最高位第 16 位到第 1 位,依次是:L2、L1、LU、LL、LD、LR、SE、ST、RL、RD、RR、RU、R1、R2、R-KEY、L-KEY。其中 R-KEY 和 L-KEY 为摇杆往下按对应的按键。
第 12、13 字节为校验值,计算前 11 个字节的 CRC16 校验值得到 0x51D7,按照小端模式,低字节 0xD7,高字节 0x51 依次排列。

0x09 指令:接收机发往该指令给手柄,用于触发手柄震动。
示例:AA AA 09 07 01 0E 32
第 1、2 字节 0xAA,0xAA 为帧头,标志着一帧数据的开始。
第 3 字节 0x09 为命令代码。
第 4 字节 0x07 为帧长度,这条指令长度为 7 个字节。
第 5 字节 0x01 表示触发手柄左侧电机振动,如果要触发右侧电机则应为 0x02。该字节只能取 0x01 或者 0x02。
第 6、7 字节为校验值,计算前 5 个字节的 CRC16 校验值得到 0x320E,按照小端模式,低字节 0x0E,高字节 0x32 依次排列。

0x15 指令:上位机通过手柄透传给接收机的数据,然后通过接收机的串口输出。
示例:AA AA 15 07 00 0E 34
第 1、2 字节 0xAA,0xAA 为帧头,标志着一帧数据的开始。
第 3 字节 0x15 为命令代码。
第 4 字节 0x07 为帧长度,这条指令长度为 7 个字节。
第 5 字节 0x00 上位机发出的数据,字节长度可变,但不可超过 26 字节。因为一次通信最多发送 32 字节数据,其他部分已占据 6 字节。
第 6、7 字节为校验值,计算前 5 个字节的 CRC16 校验值得到 0x340E,按照小端模式,低字节 0x0E,高字节 0x34 依次排列。

0x1D 指令:用户通过接收机的串口把这条指令发送给接收机,然后接收机通过无线发送给手柄,手柄通过 USB 口输出给上位机。
示例:AA AA 1D 07 00 8F F6
第 1、2 字节 0xAA,0xAA 为帧头,标志着一帧数据的开始。
第 3 字节 0x1D 为命令代码。
第 4 字节 0x07 为帧长度,这条指令长度为 7 个字节。
第 5 字节 0x00 接收机透传给上位机的数据,字节长度可变,但不可超过 26 字节。因为一次通信最多发送 32 字节数据,其他部分已占据 6 字节。
第 6、7 字节为校验值,计算前 5 个字节的 CRC16 校验值得到 0xF68F,按照小端模式,低字节 0x8F,高字节 0xF6 依次排列。

兼容内容

兼容分两部分组成,首先是按键的IO口对应编码兼容,其次是和摇杆对应的ADC采集数值映射关系
由于JDY-41遥控器并没有开源硬件,固按键对应IO口,需要通过实验得出与RC-TANK相同顺序,其正确的IO顺序如下表所示:

兼容的IO对应 #3
按键位置 L2 L1 LU LL LD LR SE ST RL RD RR RU R1 R2 R-KEY L-KEY
对应IOK口 10 11 12 13 14 15 16 21 17 33 34 35 45 18 6 7

注: JDY-41手柄按键值未按下为高,应取反,与RC-TANK兼容。

摇杆ADC数值采集兼容中,由于JDY-41手柄的摇杆硬件设置与RC-TANK不同,固摇杆在对应动作上,ADC数值按照如下图所示做映射。

图三:摇杆数据趋势图

通过以上方式,让两个手柄在对无线控制机器人数据帧完全兼容。

posted on 2023-02-14 21:07  peter1990  阅读(455)  评论(0编辑  收藏  举报