You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart/Flutter中Modbus返回的Uint16List如何正确转字符串与整数

Dart中Modbus Uint16List转字符串与整数的正确方案

问题根源

你当前得到乱码的核心原因是直接将Uint16的每个元素作为独立Unicode码点传入String.fromCharCodes转换,但Modbus设备返回的字符串通常是将每个16位寄存器拆为2个8位字节存储(编码多为ASCII/UTF-8),整数也可能是由多个16位寄存器拼接而成,需要先处理字节序再做转换。

Uint16List转字符串的正确实现

首先需要将Uint16List按字节序拆为Uint8List,过滤掉字符串末尾的空字节后再用对应编码解码:

import 'dart:typed_data';
import 'dart:convert';

// 工具方法:Uint16List转有效字节数组,默认适配Modbus通用大端序
Uint8List uint16ToValidBytes(Uint16List uint16list, {Endian endian = Endian.big}) {
  final byteData = ByteData.sublistView(uint16list);
  final uint8list = Uint8List(uint16list.length * 2);
  for (int i = 0; i < uint16list.length; i++) {
    uint8list[i*2] = byteData.getUint8(i*2, endian);
    uint8list[i*2 + 1] = byteData.getUint8(i*2 + 1, endian);
  }
  // 过滤字符串末尾的0值终止字节
  return Uint8List.fromList(uint8list.takeWhile((byte) => byte != 0).toList());
}

// 调用示例:转换设备名称
var deviceNameRegisters = await client.readHoldingRegisters(0x90, 32);
var deviceNameBytes = uint16ToValidBytes(deviceNameRegisters);
// 根据设备实际编码选择utf8或ascii解码,allowMalformed避免编码不匹配抛出异常
var deviceStr = utf8.decode(deviceNameBytes, allowMalformed: true);

如果解码结果仍不符合预期,可在调用工具方法时传入endian: Endian.little切换为小端序测试,不同厂商设备的字节序可能存在差异。

Uint16List转整数的正确实现

根据整数的长度选择拼接方式,以常见的16位、32位无符号整数为例:

// 工具方法:多寄存器拼接为整数,默认大端序
int uint16ToInt(Uint16List uint16list, {Endian endian = Endian.big}) {
  final byteData = ByteData.sublistView(uint16list);
  switch(uint16list.length) {
    case 1:
      return byteData.getUint16(0, endian);
    case 2:
      return byteData.getUint32(0, endian);
    case 4:
      return byteData.getUint64(0, endian);
    default:
      throw ArgumentError('不支持的寄存器长度:${uint16list.length}');
  }
}

// 调用示例:转换OS版本
var versionRegisters = await client.readHoldingRegisters(0x82, 2);
// 若版本号为32位整数,直接调用即可
var osVersion = uint16ToInt(versionRegisters);
// 若版本号为分段格式(如主版本.次版本),可直接取对应寄存器值
var majorVersion = versionRegisters[0];
var minorVersion = versionRegisters[1];

你示例中返回的[264, 0]如果是大端32位整数结果为172916736,如果是小端32位整数结果为264,如果是分段版本号就是主版本264、次版本0,可结合设备说明文档选择对应处理方式。

内容的提问来源于stack exchange,提问作者Олег Якунин

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:39:04