# COM_SkydroidDemo **Repository Path**: skydroid/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**: 4 - **Forks**: 13 - **Created**: 2023-06-05 - **Last Updated**: 2026-03-10 ## 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() ``` ----