Flutter UDP Modbus客户端插件modbus_client_udp的使用

Flutter UDP Modbus客户端插件modbus_client_udp的使用

引入

本示例基于 modbus_client 项目开发,提供了Modbus客户端发送请求到远程设备的功能。 包含TCP、UDP和Serial三种协议。

特性

  • 自动连接模式:通过设置 ModbusConnectionMode 来自动连接和断开客户端。
  • 单位ID:客户端和请求可以指定目标单位ID,适用于多个设备共享一个串口的情况。
  • 响应超时:请求中可以设置等待响应的超时时间。
  • 服务器发现(仅支持TCP/UDP):从起始IP地址发现Modbus服务器。
  • 连接超时(仅支持TCP/UDP):设置连接超时时间。
  • 延迟后连接(仅支持TCP/UDP):在连接服务器后应用延迟。
  • 元素类型:提供多种元素类型,如 ModbusNumRegisterModbusBitElement 等。
  • 文件记录:支持 File Records 功能码0x14和0x15的不同类型的数值记录。
  • 组元素:为了优化请求,可以创建 Group of elements
  • 自定义请求实现:可以通过重写 Request 类来实现自定义请求。
  • 日志:Modbus客户端库启用了日志功能,可以通过根日志器或 ModbusAppLogger 实例启用日志。

使用方法

使用 modbus client 是非常简单的的。 您定义元素,创建读或写请求,并使用客户端发送请求。

示例代码

import 'package:modbus_client/modbus_client.dart';
import 'package:modbus_client_udp/modbus_client_udp.dart';

void main() async {
  // 创建一个 modbus 整数16位寄存器元素
  var batteryTemperature = ModbusInt16Register(
      name: "BatteryTemperature",
      type: ModbusElementType.inputRegister,
      address: 22,
      uom: "°C",
      multiplier: 0.1,
      onUpdate: (self) => print(self));

  // 发现 Modbus 服务器
  var serverIp = await ModbusClientUdp.discover("192.168.0.0");
  if (serverIp == null) {
    ModbusAppLogger.shout("No modbus server found!");
    return;
  }

  // 创建 modbus 客户端。
  var modbusClient = ModbusClientUdp(serverIp, unitId: 1);

  // 发送读请求从元素
  await modbusClient.send(batteryTemperature.getReadRequest());

  // 结束这里
  modbusClient.disconnect();
}

读请求

import 'package:modbus_client/modbus_client.dart';
import 'package:modbus_client_udp/modbus_client_udp.dart';

void main() async {
  // 创建一个 modbus 整数16位寄存器元素
  var batteryStatus = ModbusEnumRegister(
      name: "BatteryStatus",
      address: 11,
      type: ModbusElementType.holdingRegister,
      enumValues: BatteryStatus.values,
      onUpdate: (self) => print(self));

  // 发现 Modbus 服务器
  var serverIp = await ModbusClientUdp.discover("192.168.0.0");
  if (serverIp == null) {
    ModbusAppLogger.shout("No modbus server found!");
    return;
  }

  // 创建 modbus 客户端。
  var modbusClient = ModbusClientUdp(serverIp, unitId: 1);

  var req = batteryStatus.getWriteRequest(BatteryStatus.running);
  var res = await modbusClient.send(req);
  print(res.name);

  modbusClient.disconnect();
}

写请求

import 'package:modbus_client/modbus_client.dart';
import 'package:modbus_client_udp/modbus_client_udp.dart';

enum BatteryStatus implements ModbusIntEnum {
  offline(0),
  standby(1),
  running(22),
  fault(3),
  sleepMode(4);

  const BatteryStatus(this.intValue);

  @override
  final int intValue;

  @override
  String toString() {
    return name;
  }
}

void main() async {
  var batteryStatus = ModbusEnumRegister(
      name: "BatteryStatus",
      address: 11,
      type: ModbusElementType.holdingRegister,
      enumValues: BatteryStatus.values);

  // 发现 Modbus 服务器
  var serverIp = await ModbusClientUdp.discover("127.0.0.1");
  if (serverIp == null) {
    ModbusAppLogger.shout("No modbus server found!");
    return;
  }

  // 创建 modbus 客户端。
  var modbusClient = ModbusClientUdp("127.0.0.1", unitId: 1);

  await modbusClient.send(batteryStatus.getReadRequest());
  modbusClient.disconnect();
}

元素组

import 'package:modbus_client/modbus_client.dart';
import 'package:modbus_client_udp/modbus_client_udp.dart';

enum BatteryStatus implements ModbusIntEnum {
  offline(0),
  standby(1),
  running(22),
  fault(3),
  sleepMode(4);

  const BatteryStatus(this.intValue);

  @override
  final int intValue;

  @override
  String toString() {
    return name;
  }
}

void main() async {
  // 创建 modbus 元素组
  var batteryRegs = ModbusElementsGroup([
    ModbusEnumRegister(
        name: "BatteryStatus",
        type: ModbusElementType.holdingRegister,
        address: 37000,
        enumValues: BatteryStatus.values),
    ModbusInt32Register(
        name: "BatteryChargingPower",
        type: ModbusElementType.holdingRegister,
        address: 37001,
        uom: "W",
        description: "> 0: charging - < 0: discharging"),
    ModbusUint16Register(
        name: "BatteryCharge",
        type: ModbusElementType.holdingRegister,
        address: 37004,
        uom: "%",
        multiplier: 0.1),
    ModbusUint16Register(
        name: "BatteryTemperature",
        type: ModbusElementType.holdingRegister,
        address: 37022,
        uom: "°C",
        multiplier: 0.1),
  ]);

  // 创建 modbus 客户端。
  var modbusClient = ModbusClientUdp("127.0.0.1", unitId: 1);

  // 发送读请求从组
  await modbusClient.send(batteryRegs.getReadRequest());
  print(batteryRegs[0]);
  print(batteryRegs[1]);
  print(batteryRegs[2]);
  print(batteryRegs[3]);

  // 结束这里
  modbusClient.disconnect();
}

文件记录


更多关于Flutter UDP Modbus客户端插件modbus_client_udp的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter UDP Modbus客户端插件modbus_client_udp的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个使用Flutter和modbus_client_udp插件来实现UDP Modbus客户端的示例代码。这个示例将展示如何连接到Modbus服务器,读取和写入寄存器。

首先,确保你已经在pubspec.yaml文件中添加了modbus_client_udp依赖:

dependencies:
  flutter:
    sdk: flutter
  modbus_client_udp: ^最新版本号  # 请替换为实际发布的最新版本号

然后运行flutter pub get来安装依赖。

接下来,在你的Flutter应用中,你可以按照以下步骤实现UDP Modbus客户端:

  1. 导入必要的包
import 'package:flutter/material.dart';
import 'package:modbus_client_udp/modbus_client_udp.dart';
import 'dart:async';
import 'dart:typed_data';
  1. 创建Modbus客户端
class ModbusService {
  ModbusUdpClient? client;

  ModbusService() {
    // 初始化Modbus UDP客户端
    client = ModbusUdpClient('服务器IP地址', 服务器端口号);
  }

  Future<Uint8List?> readHoldingRegisters(int unitId, int startAddress, int quantity) async {
    try {
      await client?.connect();
      var response = await client?.readHoldingRegisters(unitId, startAddress, quantity);
      return response;
    } catch (e) {
      print('Error reading registers: $e');
      return null;
    } finally {
      await client?.close();
    }
  }

  Future<void> writeSingleRegister(int unitId, int address, int value) async {
    try {
      await client?.connect();
      await client?.writeSingleRegister(unitId, address, value);
    } catch (e) {
      print('Error writing register: $e');
    } finally {
      await client?.close();
    }
  }
}
  1. 使用Modbus服务
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Modbus UDP Client',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final ModbusService modbusService = ModbusService();
  Uint8List? registerData;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Modbus UDP Client'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Read Holding Registers:',
            ),
            ElevatedButton(
              onPressed: () async {
                setState(() {
                  registerData = await modbusService.readHoldingRegisters(1, 0, 10);
                });
                if (registerData != null) {
                  print('Register Data: ${registerData!.map((e) => e.toRadixString(16)).join(', ')}');
                }
              },
              child: Text('Read Registers'),
            ),
            SizedBox(height: 20),
            Text(
              'Write Single Register:',
            ),
            ElevatedButton(
              onPressed: () async {
                await modbusService.writeSingleRegister(1, 0, 12345);
                print('Wrote 12345 to register 0');
              },
              child: Text('Write Register'),
            ),
          ],
        ),
      ),
    );
  }
}

解释

  1. ModbusService类:负责Modbus客户端的初始化和连接管理,包括读取和写入寄存器的方法。
  2. readHoldingRegisters方法:读取保持寄存器的值。
  3. writeSingleRegister方法:写入单个寄存器的值。
  4. MyApp和MyHomePage类:Flutter应用的UI部分,包含两个按钮,一个用于读取寄存器,另一个用于写入寄存器。

请根据你的实际需求修改服务器IP地址、端口号、单元ID、寄存器地址和数量等参数。这段代码提供了一个基本框架,你可以在此基础上进行扩展和修改。

回到顶部