C#实现托利多电子秤数据采集与控制

在现代工业自动化和计量领域中,电子秤数据的自动采集和处理变得越来越重要。本文将介绍如何使用C#开发一个托利多电子秤的驱动类库,实现重量数据的实时读取和设备控制功能。

一、项目概述

托利多是一款高性能的电子天平,支持多种通信方式。我们需要开发一个通用的类库,能够通过串口或TCP/IP连接与设备通信,并实现以下功能:

  • 重量数据的实时读取和解析

  • 设备状态监控(稳定状态、超限状态等)

  • 设备操作(清零、去皮、清除皮重等)

  • 多设备配置管理

二、核心数据模型设计

首先定义了两个核心数据模型:

/// <summary>
/// 重量数据模型
/// </summary>
public class WeightData
{
    public string NetWeight { get; set; } = "0";
    public string TareWeight { get; set; } = "0";
    public string GrossWeight { get; set; } = "0";
    public string PresetTareWeight { get; set; } = "0";
    public bool Stable { get; set; }
    public bool OverstepRange { get; set; }
    public string Date { get; set; } = string.Empty;
    public string Time { get; set; } = string.Empty;
    public string DateTime { get; set; } = string.Empty;
    public string Unit { get; set; } = "kg";
}

/// <summary>
/// 配置实体
/// </summary>
public class BalanceConfig
{
    public string CommunicationMode { get; set; } = string.Empty;
    public string OutputType { get; set; } = string.Empty;
    public string SerialPort { get; set; } = string.Empty;
    public int BaudRate { get; set; } = 9600;
    public string IpAddress { get; set; } = string.Empty;
    public int Port { get; set; } = 1500;
}

三、设备连接与通信实现

3.1 设备配置管理

类库支持单设备和多设备配置,方便在不同场景下使用:

public void ConfigureDevice(BalanceConfig configuration)
{
    _deviceConfigurations = new List<BalanceConfig> { configuration };
    // 应用配置参数...
}

public void ConfigureMultipleDevices(List<BalanceConfig> configurations)
{
    if (configurations != null && configurations.Count > 0)
    {
        _deviceConfigurations = configurations;
        // 应用主设备配置...
    }
}

3.2 连接初始化

根据配置的连接类型初始化不同的通信方式:

public bool InitializeConnection(int deviceCount = 1)
{
    try
    {
        Disconnect();
        _isConnected = true;
        _cancellationTokenSource = new CancellationTokenSource();

        switch (ConnectionType)
        {
            case "SerialPort":
                SetupSerialConnection();
                break;
            case "TCP/IP":
                SetupNetworkConnection();
                break;
            default:
                throw new Exception("未指定通讯方式");
        }

        return true;
    }
    catch (Exception ex)
    {
        _errorMessage = "连接失败: " + ex.Message;
        Disconnect();
        return false;
    }
}

四、数据解析核心算法

4.1 实时数据解析

对于实时模式接收的数据,需要按照IND231的通信协议进行解析:

private void ParseDataPacket(byte[] packet)
{
    try
    {
        // 解析状态字A
        byte statusA = packet[1];
        int decimalPlaces = statusA & 0x07;
        (double decimalMultiplier, string formatString) = GetDecimalFormat(decimalPlaces);

        // 解析状态字B
        byte statusB = packet[2];
        bool isNetWeight = (statusB & 0x01) == 0x01;
        bool isPositive = (statusB & 0x02) == 0;
        bool isOutOfRange = (statusB & 0x04) == 0x04;
        bool isStable = (statusB & 0x08) == 0;

        // 解析净重和皮重数据
        byte[] netWeightBytes = new byte[6];
        Array.Copy(packet, 4, netWeightBytes, 0, 6);
        string netWeightStr = Encoding.ASCII.GetString(netWeightBytes);
        
        // 数据处理和转换...
    }
    catch (Exception ex)
    {
        _errorMessage = "解析数据包时出错: " + ex.Message;
    }
}

4.2 打印模式数据处理

对于打印模式,数据格式不同,需要特殊处理:

private void ParsePrintData(string data)
{
    var dataLines = data.Split('@');
    
    foreach (string line in dataLines)
    {
        if (string.IsNullOrEmpty(line)) continue;
        
        var datas = line.Split(' ');
        switch (datas[0].Trim())
        {
            case "Date":
            case "日期":
                _currentWeightData.Date = datas[datas.Length - 1];
                break;
            case "Time":
            case "时间":
                _currentWeightData.Time = datas[datas.Length - 1];
                break;
            // 其他数据处理...
        }
    }
}

五、设备操作功能

类库提供了完整的设备操作功能:

// 执行清零操作
public void PerformZero(int scaleNumber = 1)
{
    lock (_syncLock)
    {
        string command = DataOutputMode == "sics" ? "ZI" : "Z";
        SendCommandToDevice(command);
    }
}

// 执行去皮操作
public void PerformTare(int scaleNumber = 1)
{
    lock (_syncLock)
    {
        string command = DataOutputMode == "sics" ? "TI" : "T";
        SendCommandToDevice(command);
        _currentWeightData.PresetTareWeight = "0";
    }
}

// 发送命令到设备
private void SendCommandToDevice(string command)
{
    switch (ConnectionType)
    {
        case "SerialPort":
            _serialPort.WriteLine(command);
            break;
        case "TCP/IP":
            if (_tcpClient?.Connected == true)
            {
                string fullCommand = command + "\x0D\x0A";
                byte[] buffer = Encoding.UTF8.GetBytes(fullCommand);
                NetworkStream stream = _tcpClient.GetStream();
                stream.Write(buffer, 0, buffer.Length);
            }
            break;
    }
}

六、使用示例

6.1 初始化并连接设备

// 创建设备配置
var config = new BalanceConfig
{
    CommunicationMode = "SerialPort",
    OutputType = "continu",
    SerialPort = "COM1",
    BaudRate = 9600
};

// 初始化设备
var balance = new ToledoIND231Balance();
balance.ConfigureDevice(config);
bool connected = balance.InitializeConnection();

if (connected)
{
    Console.WriteLine("设备连接成功");
    
    // 订阅数据接收事件
    balance.DataReceivedEvent += (sender, e) =>
    {
        WeightData data = balance.GetCurrentWeight();
        Console.WriteLine($"净重: {data.NetWeight}{data.Unit}, 状态: {(data.Stable ? "稳定" : "不稳定")}");
    };
}

6.2 执行设备操作

// 执行清零操作
balance.PerformZero();

// 执行去皮操作
balance.PerformTare();

// 设置预置皮重
balance.SetPredefinedTare("10.5");

七、总结

本文介绍的托利多IND231电子秤驱动类库具有以下特点:

  1. 多连接方式支持:同时支持串口和TCP/IP连接

  2. 多输出模式适配:适配实时模式和打印模式两种数据输出方式

  3. 完整设备操作:提供清零、去皮、清除皮重等操作功能

  4. 多设备管理:支持多个设备的配置和管理

  5. 异常处理:完善的异常处理机制,保证系统稳定性

这个类库可以轻松集成到各种工业自动化和计量系统中,实现电子秤数据的自动化采集和处理,提高生产效率和数据准确性。

注意:实际使用时需要根据具体的设备配置和通信协议进行调整,确保参数设置与设备实际配置一致。

更多推荐