# COM_SkydroidDemo **Repository Path**: hilbertw/SkydroidDemo ## Basic Information - **Project Name**: COM_SkydroidDemo - **Description**: H16及H30安卓开发示例 - **Primary Language**: Android - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 13 - **Created**: 2025-04-04 - **Last Updated**: 2025-04-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 云卓 Demo 简介: - 1.RCSDKDemo: [遥控器SDK及Demo(推荐)](https://gitee.com/skydroid/rcsdk-demo) - 2.SkydroidFpvTest: [适用于T10,T12,H12,H30串口连接方式 ](https://gitee.com/skydroid/SkydroidFpvTest) - 3.SkydroidH12Demo: [H12数传图传SDKDemo(旧版,不推荐,后续不再维护)](https://gitee.com/skydroid/SkydroidH12Demo) - 4.SkydroidDemo: [H16及H30安卓开发示例](https://gitee.com/skydroid/SkydroidDemo) - 5.FPVPlayerDemo: [云卓图传播放器Demo](https://gitee.com/skydroid/fpv-player-demo) | Demo | RCSDK | SkydroidFpvTest | SkydroidH12Demo
旧版 | SkydroidDemo | FPV-Player
网口 图传 | | :----: | :----: | :----: | :----: | :----: | :----: | | 适用于 |H12、H12Pro、H16
后续会新增H30| T10、T12、H12、H30 | T10、T12、H12 | H16、H30 | H12Pro、H16、H30 | | T10,T12图传 | ✘ | ✔
USB 图传 | ✔
USB 图传 | ✘ | ✘ | | H12数传 | ✔ | ✔ | ✔ | ✘ | ✘ | | H12图传 | ✘ | ✔
串口 图传 | ✔
串口 图传 | ✘ | ✘ | | H12Pro数传 | ✔ | ✘ | ✘ | ✘ | ✘ | | H12Pro图传 | ✘ | ✘ | ✘ | ✘ | ✔ | | H16数传 | ✔ | ✘ | ✘ | ✔
舵量、手型 | ✘ | | H16图传 | ✘ | ✘ | ✘ | ✔
网口 图传 | ✔ | | H30数传 | ✔ | ✔ | ✘ | ✔
舵量、手型、信号 | ✘ | | H30图传 | ✘ | ✘ | ✘ | ✔
网口 图传 | ✔ | | 遥控调参 | ✔
支持助手功能 | ✘ | ✘ | ✘ | ✘ | | 云台控制 | ✘ | ✔ | ✘ | ✘ | ✔ | --- # H16及H30安卓开发示例 ![封面](screenshot/H16demo.png) ## H16通讯方式 ### 天空端数传接口 ##### 天空端有2路串口,均具备透传功能 ![alt ](screenshot/H16Receiver.png) * uart0地址:通过本地 UDP 14551 端口接收数据,通过本地 UDP 14552 端口发送数据。 默认波特率 57600 * uart1 地址:通过本地 UDP 13551 端口接收数据,通过本地 UDP 13552 端口发送数据。 默认波特率 115200 ##### 串口调用示例代码 1. 创建连接 ``` try { var datagramSocket = DatagramSocket(14551) datagramSocket.connect(InetAddress.getByName("127.0.0.1"), 14552) } catch (e: IOException) { e.printStackTrace() } ``` 2. 读取数据 ``` var buffer = ByteArray(256) var receivePacket = DatagramPacket(buffer , buffer.size) datagramSocket.receive(receivePacket) ``` 3. 发送数据 ``` var data = "hello uart0".toByteArray() var packet = DatagramPacket( data, data.size) packet.data = data datagramSocket?.send(packet) ``` 4. 关闭连接 ``` datagramSocket.close() ``` ---- ### 遥控器通讯串口 ##### 获取遥控器相关数据 与遥控器通讯采用LocalSocket交互方式。数据传输私有协议,详情请见协议文档 * uart0:用于获取遥控器舵量值,bindCode为"uart0app";uart0为单向通讯,只用来读取摇杆舵量值,不支持数据的写入。 * uart3:用于 读取设置手型, 获取遥控器SN;bindCode为"uart3app",connectCode为"uart3endpoint";双向通讯可收发 ##### LocalSocket调用示例代码 1. 创建连接 ``` try { var localSocket = LocalSocket(LocalSocket.SOCKET_DGRAM) localSocket.bind(LocalSocketAddress("uart3app")) //uart0 单向通讯 所以不需要 调用connect localSocket.connect(LocalSocketAddress("uart3endpoint")) } catch (e: IOException) { e.printStackTrace() } ``` 2. 读取数据 ``` try { var buffer = ByteArray(1024) localSocket.inputStream.read(buffer) } catch (e: IOException) { e.printStackTrace() } ``` 3. 发送数据 ``` try { var buffer = ByteArray(1024) localSocket.outputStream.write(buffer) } catch (e: IOException) { e.printStackTrace() } ``` 4. 关闭连接 ``` try { localSocket?.shutdownInput() } catch (e: IOException) { e.printStackTrace() } try { localSocket?.shutdownOutput() } catch (e: IOException) { e.printStackTrace() } try { localSocket?.close() } catch (e: IOException) { e.printStackTrace() } try { localSocket?.inputStream?.close() } catch (e: IOException) { e.printStackTrace() } try { localSocket?.outputStream?.close() } catch (e: IOException) { e.printStackTrace() } ``` ---- ### 遥控器通讯协议 遥控器通讯协议分为2种 1. 用于解析遥控器舵量,帧头为"SKYDROID:" (目前只用在舵量上) ``` 遥控器回复: "SKYDROID:" + 0xB1 + 数据len + 数据 + SUM(BCC异或校验) ``` 2. 用于获取设置手型等,帧头为"fengyingdianzi:" ``` 帧格式:“fengyingdianzi:” + FUN + LEN + DATA + SUM “fengyingdianzi:” 帧头,字符串 FUN 功能字,可以是 0x00到0xFF,代表帧的含义; LEN DATA的长度(不包括帧头、FUN、LEN、SUM)。 DATA 数据,1~255字节 SUM 包括帧头一直到DATA最后一字节的BCC校验和,uint8格式 例: APP发送: “fengyingdianzi:” + 0xA9 +2 + Option1 + Option2 +SUM 遥控器回复: “fengyingdianzi:” + 0xA9 + 2 + ‘O’ + ‘K’ + SUM ``` --- ## H30通讯方式 ![封面](screenshot/H30demo.png) ### 天空端数传接口 ##### 天空端有2路串口,均具备透传功能 ![alt ](screenshot/H30Receiver.png) 如上图:1号接口 表示uart0,1号接口表示 uart1 * uart0地址:通过TCP 访问192.168.144.101:14550端口进行数据收发 默认波特率 57600 * uart1 地址:通过TCP 访问192.168.144.101:14551端口进行数据收发 默认波特率 115200 ##### 串口调用示例代码 1. 创建连接 ``` val CONNECTION_TIMEOUT = 20 * 1000 //20s try { var socket = Socket() socket.connect(new InetSocketAddress("192.168.144.101", 14550), CONNECTION_TIMEOUT); var outputStream:BufferedOutputStream = BufferedOutputStream((socket.getOutputStream())) var inputStream:BufferedInputStream = BufferedInputStream((socket.getInputStream())) } catch (e: IOException) { e.printStackTrace() } ``` 2. 读取数据 ``` var buffer = ByteArray(256)//数组长度自定义 inputStream.read(buffer) ``` 3. 发送数据 ``` var data = "hello uart0".toByteArray() outputStream.write(buffer); outputStream.flush(); ``` 4. 关闭连接 ``` inputStream.close() outputStream.close() socket.close() ``` ### 遥控器通讯串口 ##### 获取遥控器相关数据 与遥控器通讯采用硬件串口交互方式。数据传输私有协议,详情请见协议文档 * uart path "/dev/ttyMSM1",uart baudrate "57600" ##### 串口调用示例代码 1. 创建连接 ``` var mSerialPortConnection = SerialPortConnection.newBuilder("/dev/ttyMSM1", 57600).build() mSerialPortConnection?.setDelegate(object : SerialPortConnection.Delegate { override fun received(bytes: ByteArray, size: Int) { //数据回调 } override fun connect() { //连接成功回调 } }) //打开串口 mSerialPortConnection?.openConnection() ``` 2. 发送数据 ``` var data = "hello uart0".toByteArray() mSerialPortConnection?.sendData() ``` 3. 关闭连接 ``` mSerialPortConnection?.closeConnection() ``` ### 遥控器通讯协议 遥控器通讯协议 1. 用于获取设置手型等,帧头为"fengyingdianzi:" ``` 帧格式:“fengyingdianzi:” + FUN + LEN + DATA + SUM “fengyingdianzi:” 帧头,字符串 FUN 功能字,可以是 0x00到0xFF,代表帧的含义; LEN DATA的长度(不包括帧头、FUN、LEN、SUM)。 DATA 数据,1~255字节 SUM 包括帧头一直到DATA最后一字节的BCC校验和,uint8格式 例: APP发送: “fengyingdianzi:” + 0xA9 +2 + Option1 + Option2 +SUM 遥控器回复: “fengyingdianzi:” + 0xA9 + 2 + ‘O’ + ‘K’ + SUM ``` ### H30信号强度 1. 创建连接 ``` mSocketATGCS = SocketAT("192.168.144.66",5051) mSocketATGCS?.openConnect() ``` 2. 读取数据(目前数据主要来源于dapr,其中signalStrength为信号强度百分比) ``` mSocketATGCS?.setRadioParameterListener(object:SocketAT.RadioParameterListener{ override fun onDrprListener(datas1: DRPR, datas2: DRPR, signalStrength: Int) { //解析后 的drpr数据 Log.e("onDrprListener","index:${datas1.index},rssi:${datas1.rssi},rsrp:${datas1.rsrp},rsrq:${datas1.rsrq},snr:${datas1.snr}") Log.e("onDrprListener","index:${datas2.index},rssi:${datas2.rssi},rsrp:${datas2.rsrp},rsrq:${datas2.rsrq},snr:${datas2.snr}") } override fun onDaprListener(datas1: DAPR, datas2: DAPR, signalStrength: Int) { //解析后 的dapr数据 Log.e("onDrprListener","index:${datas1.index},rssi:${datas1.rssi},rsrp:${datas1.rsrp},rsrq:${datas1.rsrq},snr:${datas1.snr}") Log.e("onDrprListener","index:${datas2.index},rssi:${datas2.rssi},rsrp:${datas2.rsrp},rsrq:${datas2.rsrq},snr:${datas2.snr}") } }) ``` 3. 发送数据 ``` mSocketATGCS?.queryVersion()// 查询版本 mSocketATGCS?.startReportGCS()// 开启上报 信号强度 mSocketATGCS?.stopReportGCS()// 停止上报 信号强度 ``` 4. 关闭连接 ``` mSocketATGCS?.stopReportGCS() ``` ---- # 遥控器协议: ---- ## 格式 ``` "fengyingdianzi:" + FUN + LEN + DATA + SUM fengyingdianzi: 帧头,需要转为bytes(66 65 6E 67 79 69 6E 67 64 69 61 6E 7A 69); FUN 功能字,可以是 0xA1到0xFF,代表帧的含义; LEN DATA的长度(不包括帧头、FUN、LEN、SUM); DATA SUM 包括帧头一直到DATA最后一字节的BCC校验和,uint8格式; ``` ## 通讯方式 ``` H12 串口:/dev/ttyHS1 波特率:921600 H12Pro 串口:/dev/ttyHS0 波特率:115200 H16、H16Pro 通讯方式为LocalSocket uart0:用于获取遥控器舵量值,bindCode为"uart0app";uart0为单向通讯,只用来读取摇杆舵量值,不支持数据的写入。 uart3:用于 读取设置手型, 获取遥控器SN等;bindCode为"uart3app",connectCode为"uart3endpoint";双向通讯可收发 H30 串口:/dev/ttyMSM1 波特率:57600 ``` ## 左右手切换 支持产品:T12,H12,H12Pro,H16,H16Pro,H30 ``` 设置参数 APP发送 "fengyingdianzi:" + 0xA9 + 0x02 + Option1 + Option2 + SUM 遥控器回复 "fengyingdianzi:" + 0xA9 + 0x02 + 'O' + 'K' + SUM ``` ``` 读取参数 APP发送 "fengyingdianzi:" + 0xA9 + 0x02 + 'R' + 0x01 + SUM 遥控器回复 "fengyingdianzi:" + 0xA9 + 0x02 + Option1 + Option2 + SUM ``` 参数|值 ---|--- Option1|0,1 Option2|0,1 ``` 美国手: Option1 = 1 Option2 = 0 通道1 X2 通道2 Y2 不反向 通道3 Y1 不反向 通道4 X1 ``` ``` 日本手: Option1 = 0 Option2 = 1 通道1 X2 通道2 Y1 反向 通道3 Y2 反向 通道4 X1 ``` ``` 反美国手: Option1 = 0 Option2 = 0 通道1 X1 通道2 Y2 反向 通道3 Y1 反向 通道4 X2 ``` ``` 反日本手: Option1 = 1 Option2 = 1 通道1 X1 通道2 Y1 不反向 通道3 Y2 不反向 通道4 X2 ``` ## 获取摇杆感量(请求式) 支持产品:H12,H12Pro,H30 ``` APP发送 "fengyingdianzi:" + 0xB1 + 0x02 + 'R' + 0x01 + SUM 遥控器回复 "fengyingdianzi:" + 0xB1 + 32 + 0x05 + 0xDC + //CH1 数据1500, 舵量1.5ms 0x05 + 0xDC + //CH2 数据1500, 0x03 + 0xE8 + //CH3 数据1000, 舵量1ms 0x07 + 0xD0 + //CH4 数据2000, 舵量2ms 0x05 + 0xDC + //CH5 数据1500, 0x05 + 0xDC + //CH6 数据1500, 0x05 + 0xDC + //CH7 数据1500, 0x05 + 0xDC + //CH8 数据1500, 0x05 + 0xDC + //CH9 数据1500, 0x05 + 0xDC + //CH10 数据1500, 0x05 + 0xDC + //CH11 数据1500, 0x05 + 0xDC + //CH12 数据1500, 0x00 + 0x00 + //CH13 数据0, 0代表该通道无数据 0x00 + 0x00 + //CH14 数据0, 0x00 + 0x00 + //CH15 数据0, 0x00 + 0x00 + //CH16 数据0, + SUM ``` ## 获取摇杆感量(遥控器主动发送) 支持产品:H16,H16Pro ``` 遥控器主动发送 "SKYDROID:" + 0xB1 + 32 + 0x03 + 0xEA + //CH1 数据1500, 舵量1.5ms 0x03 + 0xEA + //CH2 数据1500, 0x00 + 0xCA + //CH3 数据1000, 舵量1ms 0x07 + 0x0A + //CH4 数据2000, 舵量2ms 0x03 + 0xEA + //CH5 数据1500, 0x03 + 0xEA + //CH6 数据1500, 0x03 + 0xEA + //CH7 数据1500, 0x03 + 0xEA + //CH8 数据1500, 0x03 + 0xEA + //CH9 数据1500, 0x03 + 0xEA + //CH10 数据1500, 0x03 + 0xEA + //CH11 数据1500, 0x03 + 0xEA + //CH12 数据1500, 0x03 + 0xEA + //CH13 数据1500, 0x03 + 0xEA + //CH14 数据1500, 0x03 + 0xEA + //CH15 数据1500, 0x03 + 0xEA + //CH16 数据1500, + SUM DATA格式:CH1_H + CH1_L + CH2_H + CH2_L + …… + CH15_H + CH15_L + CH16_H + CH16_L (16bit整形,先发高8位,再发低8位) Sbus 202 = 1000us PPM Sbus 1002 = 1500us PPM Sbus 1802 = 2000us PPM ppm=sbus*5/8+874 通道CH1~CH16数据范围:900~2100。 通道数据每秒钟发送100次 ``` ## 序列号 支持产品:T12,H12,H12Pro,H16,H16Pro,H30 ``` APP发送 "fengyingdianzi:" + 0xB4 + 0x02 + 'R' + 0x01 + SUM 遥控器回复 "fengyingdianzi:" + 0xB5 + LEN + DATA + SUM DATA为序列号 ``` ## 获取硬件和固件版本 支持产品:T12,H12,H12Pro,H16,H16Pro,H30 ``` APP发送 "fengyingdianzi:" + 0xA1 + 0x02 + 'R' + 0x01 + SUM 遥控器回复 "fengyingdianzi:" + 0xA0 + 5 + 2 + 1 + 'M' + '1' + '2' + SUM 软件号两位 2.1 硬件字符串M12 "fengyingdianzi:" + 0xA0 + 7 + 1 + 0 + 'M' + '1' + '2' + 'H' + 'D' + SUM 软件号两位 1.0 硬件字符串M12HD ``` ## 遥控器通道值设置 支持产品:H12Pro,H16,H16Pro,H30 ``` 参数读取 APP发送 "fengyingdianzi:" + 0xA2 + 0x02 + 'R' + 0x01 + SUM 遥控器回复 "fengyingdianzi:" + 0xE2 + LEN + DATA + SUM 例: "fengyingdianzi:" + 0xE2 + 80 + 1 + 110 + 150 + 190 + 1 + //通道1 映射 + 最小舵量1100 + 中间舵量1500 + 最大舵量1900 + 正 2 + 110 + 150 + 190 + 0 + //通道2 映射 + 最小舵量1100 + 中间舵量1500 + 最大舵量1900 + 反 3 + 110 + 150 + 190 + 1 + //通道3 映射 + 最小舵量1100 + 中间舵量1500 + 最大舵量1900 + 正 4 + 110 + 150 + 190 + 1 + //通道4 映射 + 最小舵量1100 + 中间舵量1500 + 最大舵量1900 + 正 7 + 110 + 150 + 190 + 1 + //通道5 映射 + 最小舵量1100 + 中间舵量1500 + 最大舵量1900 + 正 ...... +SUM 参数设置 APP发送 "fengyingdianzi:" + 0xE3 + LEN + DATA + SUM 遥控器回复: "fengyingdianzi:" + 0xE3 + 2 + 'O' + 'K' + SUM ``` ## H12遥控器通道值设置 支持产品:H12 ``` 读取参数 APP发送 "fengyingdianzi:" + 0xA2 + 2 + 'R' + 1 + SUM 遥控器回复 "fengyingdianzi:" + 0xA2 + LEN(72) + DATA + SUM 或 "fengyingdianzi:" + 0xA2 + 2 + 'N' + 'O' + SUM 例: "fengyingdianzi:" + 0xA2 +72 + 11 + 110 + 150 + 190 + 1 + 0 + 通道1 映射X2 +最小舵量1100 +中间舵量1500 +最大舵量1900 +正 +失控保持 12 + 110 + 150 + 190 + 0 + 0 + 通道2 映射Y2 +最小舵量1100 +中间舵量1500 +最大舵量1900 +反 +失控保持 10 + 110 + 150 + 190 + 1 + 90 + 通道3 映射Y1 +最小舵量1100 +中间舵量1500 +最大舵量1900 +正 +失控舵量900 9 + 110 + 150 + 190 + 1 + 150 + 通道4 映射X1 +最小舵量1100 +中间舵量1500 +最大舵量1900 +正 +失控舵量1500 5 + 110 + 150 + 190 + 1 + 0 + 通道5 映射E +最小舵量1100 +中间舵量1500 +最大舵量1900 +正 +失控保持 6 + 110 + 150 + 190 + 1 + 0 + 13 + 110 + 150 + 190 + 1 + 0 + 14 + 110 + 150 + 190 + 1 + 0 + 1 + 110 + 150 + 190 + 1 + 0 + 2 + 110 + 150 + 190 + 1 + 0 + 3 + 110 + 150 + 190 + 1 + 0 + 4 + 110 + 150 + 190 + 1 + 0 + +SUM 参数设置 APP发送 "fengyingdianzi:" + 0xA3 + LEN + DATA + SUM 遥控器回复: "fengyingdianzi:" + 0xA3 + 2 + 'O' + 'K' + SUM 或 "fengyingdianzi:" + 0xA3 + 2 + 'N' + 'O' + SUM ``` ## H12信号强度 支持产品:H12 ``` 遥控器主动发送 //信号强度100% "fengyingdianzi:" + 0xB0 + 3 + '1' + '0' + '0' + SUM //信号强度60% "fengyingdianzi:" + 0xB0 + 3 + '0' + '6' + '0' + SUM 信号强度为0~100。遥控器每秒钟发送1次 ``` ----