package yaokong; import java.nio.ByteBuffer; import java.nio.ByteOrder; import chuankou.SerialPortService; import chuankou.sendmessage; /** * Control06.java - 遥控割草刀盘升降指令类 * * 指令类型: 0x06 * 功能: 控制割草机刀盘的升降高度 * * 数据格式: * 升降值(1字节): -100~100,正数表示向上提升 * 保留字段(3字节): 0x00填充 * * 示例用法: * 1. 提升刀盘50%: Control06.buildBladeCommandHex("50") * 2. 降低刀盘30%: Control06.buildBladeCommandHex("-30") * 3. 发送提升指令: Control06.sendBladeUpIfDebugSerialOpen(50) * 4. 发送降低指令: Control06.sendBladeDownIfDebugSerialOpen(30) */ public class Control06 { private static final int MAX_BLADE_VALUE = 100; private static final int MIN_BLADE_VALUE = -100; private static final int BLADE_STEP = 10; // 默认步进值 private static int currentBladeHeight = 0; // 当前刀盘高度百分比 /** * 构建遥控割草刀盘升降指令(指令类型0x06)的HEX格式字符串 * * @param bladeValueStr 刀盘高度值字符串,范围-100到100,正数表示向上提升 * @return 刀盘升降指令的HEX格式字符串 */ public static String buildBladeCommandHex(String bladeValueStr) { int bladeValue = parseBladeValue(bladeValueStr); byte[] commandBytes = buildBladeCommandBytes((byte) bladeValue); return bytesToHex(commandBytes); } /** * 构建遥控割草刀盘升降指令的字节数组 * * @param bladeValue 刀盘高度值:-100~100,正数表示向上提升 * @return 刀盘升降指令的字节数组 */ public static byte[] buildBladeCommandBytes(byte bladeValue) { // 验证刀盘高度范围 if (bladeValue < -100 || bladeValue > 100) { throw new IllegalArgumentException("刀盘高度值必须在-100到100之间"); } int dataLength = 4; // 升降值1字节 + 保留字段3字节 ByteBuffer buffer = ByteBuffer.allocate(14); // 总长度14字节 buffer.order(ByteOrder.LITTLE_ENDIAN); // 帧头 buffer.put(BluetoothProtocol.FRAME_HEADER); // 指令类型 (0x06) buffer.put((byte) 0x06); // 数据长度 buffer.putShort((short) dataLength); // 序列号 short sequence = (short) BluetoothProtocol.getNextSequence(); buffer.putShort(sequence); // 刀盘高度值 buffer.put(bladeValue); // 保留字段 (3字节,全部填0) buffer.put((byte) 0x00); buffer.put((byte) 0x00); buffer.put((byte) 0x00); // 计算CRC16(从指令类型开始到数据内容结束) byte[] dataForCRC = new byte[9]; ByteBuffer tempBuffer = ByteBuffer.allocate(9); tempBuffer.order(ByteOrder.LITTLE_ENDIAN); tempBuffer.put((byte) 0x06); // 指令类型 tempBuffer.putShort((short) dataLength); // 数据长度 tempBuffer.putShort(sequence); // 序列号 tempBuffer.put(bladeValue); // 刀盘高度值 tempBuffer.put((byte) 0x00); // 保留字段1 tempBuffer.put((byte) 0x00); // 保留字段2 tempBuffer.put((byte) 0x00); // 保留字段3 dataForCRC = tempBuffer.array(); int crc = CRC16.calculateCRC16(dataForCRC, 0, dataForCRC.length); buffer.putShort((short) crc); // 帧尾 buffer.put((byte) 0x0D); return buffer.array(); } /** * 当调试串口打开时发送提升刀盘指令 * * @param value 提升百分比值(0-100) * @return 发送成功返回true,否则返回false */ public static boolean sendBladeUpIfDebugSerialOpen(int value) { int targetHeight = Math.min(currentBladeHeight + value, MAX_BLADE_VALUE); return sendBladeHeightIfDebugSerialOpen(targetHeight); } /** * 当调试串口打开时发送降低刀盘指令 * * @param value 降低百分比值(0-100) * @return 发送成功返回true,否则返回false */ public static boolean sendBladeDownIfDebugSerialOpen(int value) { int targetHeight = Math.max(currentBladeHeight - value, MIN_BLADE_VALUE); return sendBladeHeightIfDebugSerialOpen(targetHeight); } /** * 当调试串口打开时发送刀盘归零指令 * * @return 发送成功返回true,否则返回false */ public static boolean sendBladeResetIfDebugSerialOpen() { return sendBladeHeightIfDebugSerialOpen(0); } /** * 快捷方法:构建提升刀盘指令 * * @param value 提升百分比值(0-100) * @return 提升指令的HEX字符串 */ public static String bladeUp(int value) { int targetValue = Math.min(Math.max(value, 0), MAX_BLADE_VALUE); return buildBladeCommandHex(String.valueOf(targetValue)); } /** * 快捷方法:构建降低刀盘指令 * * @param value 降低百分比值(0-100) * @return 降低指令的HEX字符串 */ public static String bladeDown(int value) { int targetValue = Math.max(Math.min(-value, 0), MIN_BLADE_VALUE); return buildBladeCommandHex(String.valueOf(targetValue)); } /** * 解析刀盘高度值字符串 */ private static int parseBladeValue(String bladeStr) { try { int value = Integer.parseInt(bladeStr.trim()); if (value < MIN_BLADE_VALUE || value > MAX_BLADE_VALUE) { throw new IllegalArgumentException("刀盘高度值必须在-100到100之间"); } return value; } catch (NumberFormatException e) { throw new IllegalArgumentException("刀盘高度值必须是整数: " + bladeStr); } } /** * 发送刀盘高度控制指令(内部方法) */ private static boolean sendBladeHeightIfDebugSerialOpen(int targetHeight) { SerialPortService service = sendmessage.getActiveService(); if (service == null || !service.isOpen()) { return false; } byte[] payload = buildBladeCommandBytes((byte) targetHeight); // 调试:打印发送的数据 System.out.println("发送刀盘升降指令: " + bytesToHex(payload)); boolean success = sendmessage.sendViaActive(payload); if (success) { currentBladeHeight = targetHeight; } return success; } /** * 获取当前刀盘高度 * * @return 当前刀盘高度百分比(-100到100) */ public static int getCurrentBladeHeight() { return currentBladeHeight; } /** * 重置刀盘高度为0 */ public static void resetBladeHeight() { currentBladeHeight = 0; } /** * 字节数组转换为HEX字符串 */ private static String bytesToHex(byte[] bytes) { StringBuilder hexString = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(bytes[i] & 0xFF); if (hex.length() == 1) { hexString.append('0'); } hexString.append(hex); if (i < bytes.length - 1) { hexString.append(' '); } } return hexString.toString().toUpperCase(); } /** * 测试函数:验证刀盘升降指令构建 */ public static void testBuildBladeCommand() { System.out.println("=== 测试刀盘升降指令构建 ==="); // 测试1:提升指令 byte[] cmd1 = buildBladeCommandBytes((byte)50); System.out.println("提升50%: " + bytesToHex(cmd1)); // 测试2:降低指令 byte[] cmd2 = buildBladeCommandBytes((byte)-30); System.out.println("降低30%: " + bytesToHex(cmd2)); // 测试3:归零指令 byte[] cmd3 = buildBladeCommandBytes((byte)0); System.out.println("归零: " + bytesToHex(cmd3)); } }