更新记录

1.0.8(2024-10-15)

  1. 优化SLIP协议逻辑

1.0.7(2024-10-15)

  1. 修复新基座iOS兼容问题

1.0.6(2024-10-15)

  1. 修复新基座Android打包问题
查看更多

平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.6.8,Android:4.4,iOS:9,HarmonyNext:不确定
钉钉小程序 快手小程序 飞书小程序 京东小程序
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari

进制转换、编码转换(ASCII)、modbus、crc(多种类型)、整形工具类(高低位、大小端)、获取文件数据,常用于串口、蓝牙、socket、UDP等字节数据转换

集成插件

  1. 拷贝demo示例的AndroidManifest.xml到项目根目录(用到了文件读写时需要,没用到文件读写忽略此步骤)
  2. 集成插件步骤请参考https://www.cnblogs.com/wenrisheng/p/18323027

编码转换


import {
    EncodeUtils
} from "@/uni_modules/wrs-uts-modbuscrchex"
  • 编码

let str = "银行byteArray为字节数组"; // E993B6E8A18C627974654172726179E4B8BAE5AD97E88A82E695B0E7BB84
let charsetName = "UTF_8"
// 编码
let codeStr = EncodeUtils.encode(str, charsetName)
this.showMsg("encode str:" + str + " encodeStr:" + codeStr)

charsetName:

  • UTF_8:utf8编码,也就是我们常用的ASCII编码,支持所有端

  • US_ASCII:仅支持ios、android

  • ISO_8859_1:仅支持ios、android

  • UTF_16BE:仅支持ios、android

  • UTF_16LE:仅支持ios、android

  • UTF_16:仅支持ios、android

  • UTF_32:仅支持ios

  • UTF_32BE:仅支持ios

  • UTF_32LE:仅支持ios

  • 解码


// 解码
let decodeStr = EncodeUtils.decode(codeStr, charsetName)
this.showMsg("decode str:" + codeStr + " decodeStr:" + decodeStr)

crc校验


import {
    CRCUtils,HexUtils
} from "@/uni_modules/wrs-uts-modbuscrchex"
  • CRC8

let data = "5A A5 01 00 26 00 D2 BB B6 FE C8 FD CB C4 CE E5 C1 F9 C6 DF B0 CB BE C5 CA AE 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39"
// 去掉十六进制的空格
let hex = data.replace(/\s+/g, "")
// 转换的十六进制数组
let array = HexUtils.hexToArray(hex)
let params = {
    data: array, // 数据
    mode: "CRC8_TYPE_defaultCrc" // 校验算法,参考下面说明
}
let result = CRCUtils.getCRC8(params)

mode(crc校验算法)取之类型有:

  • CRC8_TYPE_defaultCrc

  • CRC8_TYPE_cdma2000

  • CRC8_TYPE_darc

  • CRC8_TYPE_dvbS2

  • CRC8_TYPE_ebu

  • CRC8_TYPE_iCode

  • CRC8_TYPE_itu

  • CRC8_TYPE_maxim

  • CRC8_TYPE_rohc

  • CRC8_TYPE_wcdma

  • CRC16


let data = "5A A5 01 00 26 00 D2 BB B6 FE C8 FD CB C4 CE E5 C1 F9 C6 DF B0 CB BE C5 CA AE 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39"
// 去掉十六进制的空格
let hex = data.replace(/\s+/g, "")
// 转换的十六进制数组
let array = HexUtils.hexToArray(hex)
let params = {
    data: array, // 数据
    mode: "CRC16_TYPE_modbus" // 校验算法,参考下面说明
}
let result = CRCUtils.getCRC16(params)
// result:{"crc":35917,"low":77,"high":140,"hex":"8C4D"}

mode(crc校验算法)取之类型有:

  • CRC16_TYPE_ccittFalse

  • CRC16_TYPE_arc

  • CRC16_TYPE_augCcitt

  • CRC16_TYPE_buypass

  • CRC16_TYPE_cdma2000

  • CRC16_TYPE_dds110

  • CRC16_TYPE_dectR

  • CRC16_TYPE_dectX

  • CRC16_TYPE_dnp

  • CRC16_TYPE_en13757

  • CRC16_TYPE_genibus

  • CRC16_TYPE_maxim

  • CRC16_TYPE_mcrf4xx

  • CRC16_TYPE_riello

  • CRC16_TYPE_t10dif

  • CRC16_TYPE_teledisk

  • CRC16_TYPE_tms37157

  • CRC16_TYPE_usb

  • CRC16_TYPE_a

  • CRC16_TYPE_kermit

  • CRC16_TYPE_modbus

  • CRC16_TYPE_x25

  • CRC16_TYPE_xmodem

  • CRC32 CRC32在浏览器上有值溢出问题,暂时不支持浏览器


let data = "5A A5 01 00 26 00 D2 BB B6 FE C8 FD CB C4 CE E5 C1 F9 C6 DF B0 CB BE C5 CA AE 31 32 33 34 35 36 37 38 39 31 32 33 34 35 36 37 38 39"
// 去掉十六进制的空格
let hex = data.replace(/\s+/g, "")
// 转换的十六进制数组
let array = HexUtils.hexToArray(hex)
let params = {
    data: array, // 数据
    mode: "CRC32_TYPE_defaultCrc" // 校验算法,参考下面说明
}
let result = CRCUtils.getCRC32(params)

mode(crc校验算法)取之类型有:

  • CRC32_TYPE_defaultCrc
  • CRC32_TYPE_bzip2
  • CRC32_TYPE_c
  • CRC32_TYPE_d
  • CRC32_TYPE_mpeg2
  • CRC32_TYPE_posix
  • CRC32_TYPE_sata
  • CRC32_TYPE_q
  • CRC32_TYPE_jamcrc
  • CRC32_TYPE_xfer

modbus


import {
    HexUtils, ModbusUtils
} from "@/uni_modules/wrs-uts-modbuscrchex"
  • 读数据指令

// 设备地址
let address = 0x25;
// 寄存器起始地址
let start = 20;
// 寄存器个数
let count = 3;
 // crc校验类型,参考CRC16接口的mode字段
let crcMode = "CRC16_TYPE_modbus"
// CRC校验是否低位在前
let crcLowFront = false
let byteArray = ModbusUtils.getModbusReadData(address, start, count, crcMode, crcLowFront);
let hex = HexUtils.arrayToHex(byteArray);
  • 写数据指令

// 设备地址
let address = 0x25;
// 寄存器起始地址
let start = 20;
// 数据
let data = [];
data.push(0x02);
data.push(0x0A);
// crc校验类型
let crcMode = "CRC16_TYPE_modbus"
// CRC校验是否低位在前
let crcLowFront = false
let byteArray = ModbusUtils.getModbusWriteData(address, start, data, crcMode, crcLowFront);
let hex = HexUtils.arrayToHex(byteArray);

制转转换


import {
    DecimalUtils
} from "@/uni_modules/wrs-uts-modbuscrchex"
  • 二进制转十进制

let bitStr = "11101"
let result = DecimalUtils.bitToDec(bitStr)
// bitToDec bit:11101 value:29
  • 十进制转二进制

let result = 29
let bitStr = DecimalUtils.decToBit(result)
// decToBit dec:29 value:11101
  • 十六进制转十进制

let  hexStr = "00FF"
let result = DecimalUtils.hexToDec(hexStr)  
 // hexToDec hex:00FF value:255
  • 十进制转十六进制

let result = 255
let hexStr = DecimalUtils.decToHex(result)

整型工具类


import {
    IntUtils
} from "@/uni_modules/wrs-uts-modbuscrchex"
  • 高低位转整型

let low = 226;
// 高位
let high = 102;
// 26338
let value = IntUtils.highLowToInt(high,
    low)
  • 整型转高低位

let value = 26338;
// 26338
let obj = IntUtils.intToHighLow(value)
// 低位
let low = obj.low;
// 高位
let high = obj.high;
  • 大端序-字节数组转整型

var byteArray = [0x01, 0x02, 0x03, 0x04]
var intValue = IntUtils.bigEndianToInt(byteArray)
  • 大端序-整型转字节数组

var intValue = 2461;
var byteArray = IntUtils.bigEndianToByteArray(intValue)
  • 小端序-字节数组转整型

var byteArray = [0x01, 0x02, 0x03, 0x04]
var intValue = IntUtils.littleEndianToInt(byteArray)
  • 小端序-整型转字节数组

var intValue = 2461;
var byteArray = IntUtils.littleEndianToByteArray(intValue)

文件工具类


import {
    FileUtils, HexUtils
} from "@/uni_modules/wrs-uts-modbuscrchex"
  • 获取文件字节数据

// 绝对路径
let path = plus.io.convertLocalFileSystemURL("_www/static/logo.png")
FileUtils.getFileData(path, (array)=>{
    let hex = HexUtils.arrayToHex(array);
    let msg = "getFileData:" + hex;
    this.showMsg(msg)
})

沾包粘包

粘包问题是指当发送两条消息时,比如发送了 ABC 和 DEF,但另一端接收到2条数据,第1条是 ABCD,第2条是EF,像这种一次性读取了两条数据的情况就叫做粘包(正常情况应该是一条一条读取的)。

当发送的消息是 ABC 时,另一端却接收到的是 AB 和 C 两条信息,像这种情况就叫做半包

针对这种问题的解决方案有:

  1. 封装协议请求 数据封装为两部分:数据头+数据正文,在数据头中存储数据正文的大小,当读取的数据小于数据头中的大小时,继续读取数据,直到读取的数据长度等于数据头中的长度时才停止。

  2. 用特殊字符作为每条指令的头尾 数据封装为两部分:帧头+数据正文(如果包含帧头/帧尾的数据需要转义)+帧尾,接收端收到数据先缓存起来,再按照特殊字符拆分每条指令

SLIP协议

SLIP提供了两个特殊字符,END(0xC0)和 ESC(0xDB),SLIP报文的头尾都有一个END字符

转义部分:

若报文中某个字符为END,那么就连续传输两个字节0xDB和0xDC来取代; 若报文中某个字符为ESC,那么就连续传输两个字节0xDB和0xDD来取代;

接口:


import {
    SLIPUtils, HexUtils
} from "@/uni_modules/wrs-uts-modbuscrchex"
  • 封装发送数据

let array = [0x00, 0xFF, 0xEE]
let hexArray = SLIPUtils.getSLIP(array)
// send hexArray,实际发送的是hexArray
// 如果是蓝牙有mtu限制的话,请将hexArray按照mtu大小拆分成n段发送,上一段发送成功后再发送下一段
  • 接收数据

let array = [0xC0, 0xAA, 0xC0, 0xC0, 0x11]
// 接收到数据,往数据缓存里面添加即可,如果缓存到有符合格式的数据时,会自动通过slip.setCallback回调识别到的单条指令
slip.addReceiveData(array)
  • 设置接收数据解析完完整数据时的回调

slip.setCallback((oneOrderArray)=>{
    // oneOrderArray时发送端发送的一条完整数据
    let hex = HexUtils.arrayToHex(oneOrderArray);
    this.showMsg('接收到数据为 十六进制数组:' + oneOrderArray + " 十六进制字符串:" + hex)
})

如果觉得可以就点个👍吧,欢迎粉丝收藏,土豪打赏,您的关注就是我们创作的动力!

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问