当前位置: 首页 > news >正文

行业协会网站建设的目的成都网站建设培训

行业协会网站建设的目的,成都网站建设培训,品牌网站建设预算,网站移动端目录 前言一、导入模块二、协议相关1. CRC162. ByteUtil3. ModbusError4. ModbusErrorType5. ModbusFunction6. ModbusRtuMaster7. ByteArrayWriter8. ModbusRtuSerialPortUtil9. ModbusRtuMasterHelp 三、使用总结 前言 本篇文章主要演示android的串口通讯功能#xff0c;其… 目录 前言一、导入模块二、协议相关1. CRC162. ByteUtil3. ModbusError4. ModbusErrorType5. ModbusFunction6. ModbusRtuMaster7. ByteArrayWriter8. ModbusRtuSerialPortUtil9. ModbusRtuMasterHelp 三、使用总结 前言 本篇文章主要演示android的串口通讯功能其中需要使用serialport模块(下载链接)注意: 串口通讯需要root权限,需要将应用设置成‘android:sharedUserId“android.uid.system”’即可如果出现串口通讯无法访问设备首先看串口名称与波特率是否一致如果都一致看看是否是打开串口就失败了如果出现无权限的情况可能是Android开发板不支持与该设备通讯可以考虑让嵌入式工程师使用单片机提供通讯访问能力本篇文章只是演示android使用modbus协议具体协议理论可以参考其它文章这里不在讲解。 一、导入模块 implementation project(path: :serialport)二、协议相关 1. CRC16 package com.jujiang.fyc.myttftwo.utils.modbus;import java.util.Arrays;public class CRC16 {private static final byte[] crc16_tab_h { (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80,(byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01,(byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80,(byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0,(byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80,(byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01,(byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80,(byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00,(byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01,(byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41,(byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81,(byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,(byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x01,(byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40 };private static final byte[] crc16_tab_l { (byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01,(byte) 0xC3, (byte) 0x03, (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07,(byte) 0xC7, (byte) 0x05, (byte) 0xC5, (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C,(byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF, (byte) 0xCE, (byte) 0x0E, (byte) 0x0A,(byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09, (byte) 0x08, (byte) 0xC8,(byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB, (byte) 0xDA,(byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D,(byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7,(byte) 0x17, (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3,(byte) 0x11, (byte) 0xD1, (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31,(byte) 0xF1, (byte) 0x33, (byte) 0xF3, (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6,(byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35, (byte) 0x34, (byte) 0xF4, (byte) 0x3C,(byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F, (byte) 0x3E, (byte) 0xFE,(byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9, (byte) 0xF8,(byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B,(byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D,(byte) 0xED, (byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5,(byte) 0x27, (byte) 0xE7, (byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3,(byte) 0x23, (byte) 0xE1, (byte) 0x21, (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60,(byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3, (byte) 0xA2, (byte) 0x62, (byte) 0x66,(byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65, (byte) 0x64, (byte) 0xA4,(byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F, (byte) 0x6E,(byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9,(byte) 0xA8, (byte) 0x68, (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB,(byte) 0x7B, (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E, (byte) 0x7F, (byte) 0xBF,(byte) 0x7D, (byte) 0xBD, (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74, (byte) 0x75,(byte) 0xB5, (byte) 0x77, (byte) 0xB7, (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2,(byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71, (byte) 0x70, (byte) 0xB0, (byte) 0x50,(byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53, (byte) 0x52, (byte) 0x92,(byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95, (byte) 0x94,(byte) 0x54, (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F,(byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99,(byte) 0x59, (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89,(byte) 0x4B, (byte) 0x8B, (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F,(byte) 0x4F, (byte) 0x8D, (byte) 0x4D, (byte) 0x4C, (byte) 0x8C, (byte) 0x44, (byte) 0x84,(byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47, (byte) 0x46, (byte) 0x86, (byte) 0x82,(byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81, (byte) 0x80, (byte) 0x40 };/*** 计算CRC16校验** param data* 需要计算的数组* return CRC16校验值*/public static int compute(byte[] data) {return compute(data, 0, data.length);}/*** 校验byte数据是否是CRC16数据* return 是否成功*/public static boolean checkCRC16(byte[] data) {int size data.length;if (size 2) {return false;}byte[] oldCheckArray new byte[]{ data[size - 2], data[size - 1]};// 将数据拆分成三分byte[] bytes new byte[size - 2];System.arraycopy(data, 0, bytes, 0, size - 2);// 计算CRC校验码int crc compute(bytes);ByteArrayWriter request new ByteArrayWriter();request.writeInt16Reversal(crc);byte[] checkArray request.toByteArray();return Arrays.equals(oldCheckArray, checkArray);}/*** 计算CRC16校验** param data* 需要计算的数组* param offset* 起始位置* param len* 长度* return CRC16校验值*/public static int compute(byte[] data, int offset, int len) {return compute(data, offset, len, 0xffff);}/*** 计算CRC16校验** param data* 需要计算的数组* param offset* 起始位置* param len* 长度* param preval* 之前的校验值* return CRC16校验值*/public static int compute(byte[] data, int offset, int len, int preval) {int ucCRCHi (preval 0xff00) 8;int ucCRCLo preval 0x00ff;int iIndex;for (int i 0; i len; i) {iIndex (ucCRCLo ^ data[offset i]) 0x00ff;ucCRCLo ucCRCHi ^ crc16_tab_h[iIndex];ucCRCHi crc16_tab_l[iIndex];}int result((ucCRCHi 0x00ff) 8) | (ucCRCLo 0x00ff) 0xffff;return result;} }2. ByteUtil package com.jujiang.fyc.myttftwo.utils.modbus;public class ByteUtil {public static String toHexString(byte[] input, String separator) {if (inputnull) return null;StringBuilder sb new StringBuilder();for (int i 0; i input.length; i) {if (separator ! null sb.length() 0) {sb.append(separator);}String str Integer.toHexString(input[i] 0xff);if (str.length() 1) str 0 str;sb.append(str);}return sb.toString();}public static String toHexString(byte[] input) {return toHexString(input, );}public static byte[] fromInt32(int input){byte[] resultnew byte[4];result[3](byte)(input 24 0xFF);result[2](byte)(input 16 0xFF);result[1](byte)(input 8 0xFF);result[0](byte)(input 0xFF);return result;}public static byte[] fromInt16(int input){byte[] resultnew byte[2];result[0](byte)(input 8 0xFF);result[1](byte)(input 0xFF);return result;}public static byte[] fromInt16Reversal(int input){byte[] resultnew byte[2];result[1](byte)(input80xFF);result[0](byte)(input0xFF);return result;} }3. ModbusError package com.jujiang.fyc.myttftwo.utils.modbus;import android.text.TextUtils;public class ModbusError extends Exception {private int code;public ModbusError(int code, String message) {super(!TextUtils.isEmpty(message) ? message : Modbus Error: Exception code code);this.code code;}public ModbusError(int code) {this(code, null);}public ModbusError(ModbusErrorType type, String message) {super(type.name() : message);}public ModbusError(String message) {super(message);}public int getCode() {return this.code;} }4. ModbusErrorType package com.jujiang.fyc.myttftwo.utils.modbus;/*** 常见的Modbus通讯错误*/ public enum ModbusErrorType {ModbusError,ModbusFunctionNotSupportedError,ModbusDuplicatedKeyError,ModbusMissingKeyError,ModbusInvalidBlockError,ModbusInvalidArgumentError,ModbusOverlapBlockError,ModbusOutOfBlockError,ModbusInvalidResponseError,ModbusInvalidRequestError,ModbusTimeoutError }5. ModbusFunction package com.jujiang.fyc.myttftwo.utils.modbus;/*** 功能码十进制显示*/ public class ModbusFunction {//读线圈寄存器public static final int READ_COILS 1;//读离散输入寄存器public static final int READ_DISCRETE_INPUTS 2;//读保持寄存器public static final int READ_HOLDING_REGISTERS 3;//读输入寄存器public static final int READ_INPUT_REGISTERS 4;//写单个线圈寄存器public static final int WRITE_SINGLE_COIL 5;//写单个保持寄存器public static final int WRITE_SINGLE_REGISTER 6;//写入多个线圈寄存器public static final int WRITE_COILS 15;//写入多个保持寄存器public static final int WRITE_HOLDING_REGISTERS 16; }6. ModbusRtuMaster package com.jujiang.fyc.myttftwo.utils.modbus;// 提供协议部分功能 public class ModbusRtuMaster {/*** 组装Modbus RTU消息帧** param slave 从站地址号* param function_code 功能码* param starting_address 读取寄存器起始地址 / 写入寄存器地址 / 写入寄存器起始地址* param quantity_of_x 读取寄存器个数 / 写入寄存器个数* param output_value 需要写入单个寄存器的数值* param output_values 需要写入多个寄存器的数组* return 将整个消息帧转成byte[]* throws ModbusError Modbus错误*/synchronized byte[] execute(int slave, int function_code, int starting_address, int quantity_of_x,int output_value, int[] output_values) throws ModbusError {//检查参数是否符合协议规定if (slave 0 || slave 0xff) {throw new ModbusError(ModbusErrorType.ModbusInvalidArgumentError, Invalid slave slave);}if (starting_address 0 || starting_address 0xffff) {throw new ModbusError(ModbusErrorType.ModbusInvalidArgumentError, Invalid starting_address starting_address);}if (quantity_of_x 1 || quantity_of_x 0xff) {throw new ModbusError(ModbusErrorType.ModbusInvalidArgumentError, Invalid quantity_of_x quantity_of_x);}// 构造requestByteArrayWriter request new ByteArrayWriter();//写入从站地址号request.writeInt8(slave);//根据功能码组装数据区//如果为读取寄存器指令if (function_code ModbusFunction.READ_COILS || function_code ModbusFunction.READ_DISCRETE_INPUTS|| function_code ModbusFunction.READ_INPUT_REGISTERS || function_code ModbusFunction.READ_HOLDING_REGISTERS) {request.writeInt8(function_code);request.writeInt16(starting_address);request.writeInt16(quantity_of_x);} else if (function_code ModbusFunction.WRITE_SINGLE_COIL || function_code ModbusFunction.WRITE_SINGLE_REGISTER) {//写单个寄存器指令if (function_code ModbusFunction.WRITE_SINGLE_COIL)if (output_value ! 0) output_value 0xff00;//如果为线圈寄存器写1时为 FF 00,写0时为00 00request.writeInt8(function_code);request.writeInt16(starting_address);request.writeInt16(output_value);} else if (function_code ModbusFunction.WRITE_COILS) {//写多个线圈寄存器request.writeInt8(function_code);request.writeInt16(starting_address);request.writeInt16(quantity_of_x);//计算写入字节数int writeByteCount (quantity_of_x / 8) 1;/// 满足关系- (w /8) 1//写入数量 8 ,则写入字节数为1if (quantity_of_x % 8 0) {writeByteCount - 1;}request.writeInt8(writeByteCount);int index 0;//如果写入数据数量 8 则需要拆分开来int start 0;//数组开始位置int end 7;//数组结束位置int[] splitData new int[8];//循环写入拆分数组直到剩下最后一组 元素个数 8 的数据while (writeByteCount 1) {writeByteCount--;int sIndex 0;for (index start; index end; index) {splitData[sIndex] output_values[index];}//数据反转 对于是否要反转要看你传过来的数据如果高低位顺序正确则不用反转splitData reverseArr(splitData);//写入拆分数组request.writeInt8(toDecimal(splitData));start index;end 8;}//写入最后剩下的数据int last quantity_of_x - index;int[] tData new int[last];System.arraycopy(output_values, index, tData, 0, last);//数据反转 对于是否要反转要看你传过来的数据如果高低位顺序正确则不用反转tData reverseArr(tData);request.writeInt8(toDecimal(tData));} else if (function_code ModbusFunction.WRITE_HOLDING_REGISTERS) {//写多个保持寄存器request.writeInt8(function_code);request.writeInt16(starting_address);request.writeInt16(quantity_of_x);request.writeInt8(2 * quantity_of_x);//写入数据for (int v : output_values) {request.writeInt16(v);}} else {throw new ModbusError(ModbusErrorType.ModbusFunctionNotSupportedError, Not support function function_code);}byte[] bytes request.toByteArray();//计算CRC校验码int crc CRC16.compute(bytes);request.writeInt16Reversal(crc);bytes request.toByteArray();return bytes;}//将数组反转private int[] reverseArr(int[] arr) {int[] tem new int[arr.length];for (int i 0; i arr.length; i) {tem[i] arr[arr.length - 1 - i];}return tem;}//将int[1,0,0,1,1,0]数组转换为十进制数据private int toDecimal(int[] data) {int result 0;if (data ! null) {StringBuilder sData new StringBuilder();for (int d : data) {sData.append(d);}try {result Integer.parseInt(sData.toString(), 2);} catch (NumberFormatException e) {result -1;}}return result;} }7. ByteArrayWriter package com.jujiang.fyc.myttftwo.utils.modbus;import java.io.ByteArrayOutputStream;public class ByteArrayWriter extends ByteArrayOutputStream {public ByteArrayWriter() {super();}public void writeInt8(byte b){this.write(b);}public void writeInt8(int b){this.write((byte)b);}public void writeInt16(int n) {byte[] bytes ByteUtil.fromInt16(n);this.write(bytes, 0, bytes.length);}public void writeInt16Reversal(int n){byte[] bytesByteUtil.fromInt16Reversal(n);this.write(bytes,0,bytes.length);}public void writeInt32(int n) {byte[] bytes ByteUtil.fromInt32(n);this.write(bytes, 0, bytes.length);}public void writeBytes(byte[] bs,int len){this.write(bs,0,len);} }8. ModbusRtuSerialPortUtil package com.jujiang.fyc.myttftwo.utils.modbusimport android_serialport_api.SerialPort import com.android.jws.JwsManager import com.android.jws.JwsSerialPort import com.jujiang.fyc.myttftwo.utils.LogUtils import java.io.ByteArrayOutputStream import java.io.File import java.io.IOException import java.io.InputStream import java.io.OutputStream/*** 帮助Modbus 发送或接受数据*/ class ModbusRtuSerialPortUtil {private var jwp: SerialPort? nullprivate var inputStream: InputStream? nullprivate var outputStream: OutputStream? nullfun open(device: String, baud: Int, dataBits: Int, parity: Int, stopBit: Int) {try {// 普通串口通讯 // jwp SerialPort(File(device), rate, 0)// 设置验证位等参数jwp SerialPort(File(device), baud, parity, dataBits, stopBit)inputStream jwp!!.inputStreamoutputStream jwp!!.outputStream} catch (e: IOException) {e.printStackTrace()}}// 发送数据fun send(bytes: ByteArray, millisecond: Long, block: (ByteArray, ByteArray) - Unit) {try {LogUtils.e(bytes ${bytes.map { String.format(%02x, *arrayOfAny(it)) }})outputStream?.apply {write(bytes)flush()}Thread.sleep(millisecond)// 写入数据val size inputStream!!.available()val byteArray ByteArray(size)inputStream!!.read(byteArray)block(bytes, byteArray)} catch (e: IOException) {e.printStackTrace()}} }9. ModbusRtuMasterHelp package com.jujiang.fyc.myttftwo.utils.modbusimport kotlinx.coroutines.suspendCancellableCoroutine import kotlin.coroutines.resume/*** 实际调用类*/ class ModbusRtuMasterHelp(private val serialHelper: ModbusRtuSerialPortUtil) {private val modbusRtu: ModbusRtuMaster ModbusRtuMaster()/*** 读多个线圈寄存器* param slave 从站地址* param startAddress 起始地址* param numberOfPoints 读取线圈寄存器个数* throws ModbusError Modbus错误*/fun readCoils(slave: Int,startAddress: Int,numberOfPoints: Int,millisecond: Long 50,block: (ByteArray, ByteArray) - Unit) {val sendBytes modbusRtu.execute(slave,ModbusFunction.READ_COILS,startAddress,numberOfPoints,0,null)this.serialHelper.send(sendBytes, millisecond, block)}//读单个线圈寄存器fun readCoils(slave: Int,startAddress: Int,millisecond: Long 50,block: (ByteArray, ByteArray) - Unit) {readCoils(slave, startAddress, 1, millisecond, block)}// 异步读取并返回结果suspend fun readCoilsAsync(slave: Int,startAddress: Int,millisecond: Long 50): PairByteArray, ByteArray {return suspendCancellableCoroutine { continuation -readCoils(slave, startAddress, millisecond) { old, new -continuation.resume(Pair(old, new))}}}/*** 写单个线圈寄存器* param slave 从站地址* param address 写入寄存器地址* param value 写入值true/false)* throws ModbusError Modbus错误*/fun writeSingleCoil(slave: Int, address: Int, value: Boolean, millisecond: Long 50,block: (ByteArray, ByteArray) - Unit) {val sendBytes modbusRtu.execute(slave,ModbusFunction.WRITE_SINGLE_COIL,address,1,if (value) 1 else 0,null)this.serialHelper.send(sendBytes, millisecond, block)}// 异步写并返回结果suspend fun writeSingleCoilAsync(slave: Int, address: Int, value: Boolean, millisecond: Long 50): PairByteArray, ByteArray {return suspendCancellableCoroutine { continuation -writeSingleCoil(slave, address, value, millisecond) { old, new -continuation.resume(Pair(old, new))}}} }三、使用 class MainActivity : BaseBindingActivityActivityMainBinding({ActivityMainBinding.inflate(it) }) {private val modbusRtuSerialPortUtil by lazy { ModbusRtuSerialPortUtil() }private val modbusRtuSerialPort by lazy { ModbusRtuMasterHelp(modbusRtuSerialPortUtil) }override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 连接串口, 一定要保证串口是能正常的读写, 否则会导致后续读写操作失效, 如果提示无权限, 只能让嵌入式工程师// 使用单片机来做通讯, Android以普通串口读取方式来使用, 如果能正常读取成功, 可以采用实例方法modbusRtuSerialPortUtil.open(/dev/ttyS3, 19200, 8, 2, 1)// 同步读取线圈, 参数1: 地址; 参数2: 线圈地址; 返回参数1: 表示发送时的byte数组; 参数2: 表示设备回发的数据数组modbusRtuSerialPort.readCoils(0x01, 0x0A) { oldAray, byteArray - }// 异步读取在协程中操作即可lifecycleScope.launch(Dispatchers.IO) {// 在协程中可以读取的操作方式有很多种, 这里只演示一种, 如果只是需要读一个那可以不需要使用 async 包裹async {val (oldArray, byteArray) modbusRtuSerialPort.readCoilsAsync(0x01, 0x0A)// CRC16.checkCRC16 用于校验返回数据的后两位是否符合协议验证, 如果不符合则需要联系设备商修改if (CRC16.checkCRC16(byteArray)) {}}.await()}// 同步写数据, 参数1: 地址; 参数2: 线圈地址; 参数3: 需要写入的内容,线圈操作类似于按钮,所以只需要true/false即可;// 返回参数1: 表示发送时的byte数组; 参数2: 表示设备回发的数据数组// 异步写入这里就不在演示了, 目前没涉及到需要异步写入的需求modbusRtuSerialPort.writeSingleCoil(0x01, 0x00, true) { oldAray, byteArray -// 校验两次数据是否相等,不相等即表示操作失败if (oldAray.contentEquals(byteArray)) {}}} }总结 本篇文章主要记录Android使用modbus协议, 其中遇到了按照本篇文章中的方式去读取后会提示无权限的情况或写入数据无返回, 对该情况的推测是串口的打开是成功的但是没有写入数据到设备中, 因为如果串口没打开或打开失败会抛出异常, 通过协调之后得到的结论是设备并不支持Android主板, 解决方案是让嵌入式工程师使用单片机做一个中间层单片机只负责与设备连接与数据写入操作, Android这边按照modbus协议发送数据给单片机, 单片机将数据发送给设备, 设备回发数据后单片机读取数据后写入数据, Android读取数据拿到实际结果, 该方案可以解决实际问题。
http://www.hkea.cn/news/14322848/

相关文章:

  • 营销型的网站域名做网站和做公众号
  • 做网站还需要兼容ie6吗网站程序定制
  • 怎么在网站做推广拼多多福利券小程序怎么赚钱
  • 滕州住房城乡建设局网站支付网站搭建
  • 江西建设网官方网站大数据营销平台
  • 如何申请一个免费的网站空间磁县网站建设
  • 交互网站怎么做网站备案工作
  • 做防护信息的网站网站可以做2个公司的吗
  • 网站建设的主要内容包括廊坊做网站公司哪家好
  • 大连华南网站建设微信网站公众平台
  • 优化 网站访问速度wordpress时光轴页面
  • dw做旅游网站教程dedecms做网站教程
  • 知名营销网站开发全国文明城市创建工作
  • 策划案网站构成怎么写网站建设培训班南宁
  • 大兴德艺网站建设做固定背景网站
  • 微网站怎么搭建微信公众号怎么做文章排版
  • 购物网站流量怎么做厦门网站建设设计
  • php红酒网站建设百度一下移动版首页
  • 包头北京网站建设网站维护的主要内容包括
  • 珠海网站建设网络公司怎么样hyperx wordpress 汉化
  • 网站开发语言比较清晰化网站
  • 买链接网站网站首页的重要性
  • 西安网站运营如何在网站添加代码
  • 承德网站建设作用wordpress添加404页面模板
  • eclipce做网站北京住房建设部网站首页
  • 怎么在虚拟主机上发布网站音乐网站怎么做精准关键词
  • 一家专门做特卖的网站手机版成都网站建站
  • 虚拟机做门户网站如何绑定域名手机网站空间申请
  • 用ps个人网站怎么做网站建设初学者教程
  • 阿里云突发性能适用于做网站吗wordpress免费模板带演示数据