# 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安卓开发示例

## H16通讯方式
### 天空端数传接口
##### 天空端有2路串口,均具备透传功能

* 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通讯方式

### 天空端数传接口
##### 天空端有2路串口,均具备透传功能

如上图: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次
```
----