从 Mettler Toledo Rice Lake 秤获取连续秤重量

Get scale weight over serial from Mettler Toledo Rice Lake scale

在梅特勒-托利多 Rice Lake 秤通过串行命令请求时尝试接收重量。首先,如果我使用腻子发送命令,它工作正常;它 returns 打印头上当前显示的正确重量,这实际上是我想通过这些功能完成的所有工作。

尽管我尝试了很多变体,但目前这是我的代码:

加载表单时,它将修复与端口关联的变量,以遵循软件中其他地方设置的设置。这似乎可以正常工作,并且在软件的许多其他部分也是如此。

设置: 12:COM1 13: 9600 16: none 17:8 18: 一个 19: 打印

private void Get_Weight_Load(object sender, EventArgs e)
        {
            string path11 = File.ReadAllText(Application.StartupPath + @"\ConfigurationPathFile.txt") + @"\GeneralSettings.txt";
            path11 = path11.Replace("\r", "").Replace("\n", "");
            string[] settings = File.ReadAllText(path11).Split(',');

            LoadResources();
            #region Scale
            ScalePort.PortName = settings[12];
            ScalePort.BaudRate = Int32.Parse(settings[13]);
            ScalePort.Handshake = Handshake.RequestToSend; // This is one thing I have been changing in order to try and fix the problem.
            switch (settings[16])
            {
                case "None":
                    ScalePort.Parity = System.IO.Ports.Parity.None;
                    break;
                case "Odd":
                    ScalePort.Parity = System.IO.Ports.Parity.Odd;
                    break;
                case "Even":
                    ScalePort.Parity = System.IO.Ports.Parity.Even;
                    break;
                case "Mark":
                    ScalePort.Parity = System.IO.Ports.Parity.Mark;
                    break;
                case "Space":
                    ScalePort.Parity = System.IO.Ports.Parity.Space;
                    break;
            }
            ScalePort.DataBits = Int32.Parse(settings[17]);
            switch (settings[18])
            {
                case "None":
                    ScalePort.StopBits = System.IO.Ports.StopBits.None;
                    break;
                case "One":
                    ScalePort.StopBits = System.IO.Ports.StopBits.One;
                    break;
                case "Two":
                    ScalePort.StopBits = System.IO.Ports.StopBits.Two;
                    break;
                case "OnePointFive":
                    ScalePort.StopBits = System.IO.Ports.StopBits.OnePointFive;
                    break;
            }
            try
            {
                ScalePort.Open();
                ScalePort.WriteLine(settings[19]);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Contact your system admin if you are seeing this message" + System.Environment.NewLine + ex.ToString());
            }
            #endregion
        }

表单关闭时:

private void Get_Weight_FormClosed(object sender, FormClosedEventArgs 
{
     if (ScalePort.IsOpen)
        { ScalePort.Close(); }
}

和 ScalePort 数据接收事件处理程序:

 private void ScalePort_DataReceived(object sender, SerialDataReceivedEventArgs e)
 {
      Thread.Sleep(30);
      SerialPort sp = (SerialPort)sender;
      string indata = sp.ReadExisting();
      textBox1.AppendText(indata + System.Environment.NewLine);
      //MessageBox.Show(indata);
 }

运行时,我在 textbox1 中收到的是我发送的命令,在本例中是 kprint。

所以要弄清楚我的问题是什么;我做错了什么导致我无法接收重量,或者我是否发送了错误的命令?如果是,我该如何正确执行?

这是打印头的图片:

我得到了内联串口reader,这是我在左边的腻子上生成我的软件的日志。我的软件上的每个测试都是单独的尝试,每次尝试之间打开和关闭端口。

我根据下面建议的 mode cmd 命令调整了我的设置,然后我再次使用了 mode 命令我只有一件事我似乎无法改变,那就是超时关闭,设置为无限 -1 开启阅读和赖特。这样做后结果没有变化。这是软件左侧之后 Putty 右侧之后的两个图像:

根据 documentation, there are two choices for the termination character: CRLF (default) or CR, so you'll need to set the SerialPort.NewLine value as appropriate. It's also important that the other SerialPort 属性设置为与您正在使用的串行端口设备上相同的值。 get/set 值的过程可以在文档中找到。

下面的代码已经使用我拥有的串行端口设备(不是秤)进行了测试。但是,它对您的秤的用处可能会有所不同,具体取决于与为秤设置的属性相匹配的串行端口属性。我还根据秤文档中的信息设置了一些串行端口 属性 值。

尝试以下操作:

添加以下using语句:

using System.IO.Ports;
using System.Diagnostics;

枚举:

public enum TerminationCharacterType
{
    CRLF,
    CR
};

public enum PortBaudRate : int
{
    Baud300 = 300,
    Baud600 = 600,
    Baud1200 = 1200,
    Baud2400 = 2400,
    Baud4800 = 4800,
    Baud9600 = 9600,
    Baud19200 = 19200,
    Baud38400 = 38400
};

注意:你说你用过PuTTY,而且似乎有效。安装 PuTTY 后,我注意到设置了以下值:

  • 波特率: 9600
  • 数据位: 8
  • 停止位: 1
  • 奇偶校验:None
  • 流量控制:XON/XOFF

在下面的代码中,我使用了以下设置:

  • ScalePort.Handshake = Handshake.XOnXOff;
  • ScalePort.DtrEnable = true;

如果设置不起作用,您可以尝试:

  • ScalePort.Handshake = Handshake.None;
  • ScalePort.DtrEnable = false;

连接:

public System.IO.Ports.SerialPort ScalePort { get; private set; } = null;
private string _dataReceived = string.Empty;
private TerminationCharacterType _termin = TerminationCharacterType.CRLF;

public string Connect(string comPort, TerminationCharacterType termin = TerminationCharacterType.CRLF, PortBaudRate baudRate = PortBaudRate.Baud9600)
{
    //create new instance
    ScalePort = new SerialPort(comPort);

    //set properties
    ScalePort.BaudRate = (int)baudRate;
    ScalePort.Handshake = Handshake.XOnXOff; //Handshake.None or Handshake.XOnXOff 
    ScalePort.DtrEnable = true; //enable Data Terminal Ready - set true for Handshake.RequestToSend, Handshake.RequestToSendXOnXOff, or Handshake.XOnXOff
    ScalePort.RtsEnable = false; //enable Request to send - set true for Handshake.RequestToSend or Handshake.RequestToSendXOnXOff

    //if Parity.None is used, then use DataBits = 8
    //if Parity.Even or Parity.Odd is used, then use DataBits = 7
    ScalePort.Parity = Parity.None; //Even,None,Odd supported; default: Parity.None
    ScalePort.DataBits = 8; //default: 8

    //set value
    _termin = termin;

    if (termin == TerminationCharacterType.CR)
        ScalePort.NewLine = "\r"; //CR: \r
    else
        ScalePort.NewLine = "\r\n"; // CRLF: \r\n; this is the default

    ScalePort.StopBits = StopBits.One; //1 or 2 supported; default: 1
    ScalePort.ReadTimeout = 200; //num ms before a time-out occurs
    ScalePort.ReadBufferSize = 4096; //default is 4096; max value is 2147483647
    ScalePort.ReceivedBytesThreshold = 1; //default is 1; num bytes before DataReceived event occurs
    ScalePort.WriteBufferSize = 2048; //default is 2048
    ScalePort.WriteTimeout = 50; //num ms before a time-out occurs

    //subscribe to events
    ScalePort.DataReceived += ScalePort_DataReceived;
    ScalePort.ErrorReceived += ScalePort_ErrorReceived;

    //open port
    ScalePort.Open();
}

private void ScalePort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;

    if (e.EventType != SerialData.Chars)
        return;

    //read data
    //string data = sp.ReadExisting();

    //System.Threading.Thread.Sleep(25);
    string data = sp.ReadLine();

    Debug.WriteLine("data: " + data);
}

private void ScalePort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
{
    Debug.WriteLine("Error - " + e.ToString());
}

注意SerialPort.ReadLine may also work. If you use it, this post可能有用。

发送数据:

public void SerialCmdSend(string data, bool sendAsString = true)
{
    if (ScalePort.IsOpen && !String.IsNullOrEmpty(data))
    {
        //ToDo: see if the following works, if not comment it out
        //For testing, try to prepend STX (hex: 02; Ctrl-B)
        data = "\x02" + data.Trim();

        if (_termin == TerminationCharacterType.CRLF)
            data = data.Trim() + "\r\n"; //append CRLF
        else if (_termin == TerminationCharacterType.CR)
            data = data.Trim() + "\r"; //append CR

        if (sendAsString)
        {
            //ScalePort.WriteLine(data);
            ScalePort.Write(data);
        }
        else
        {
            // Send the binary data out the port
            byte[] hexstring = Encoding.ASCII.GetBytes(data);

            foreach (byte hexval in hexstring)
            {
                byte[] _hexval = new byte[] { hexval }; // need to convert byte to byte[] to write
                ScalePort.Write(_hexval, 0, 1);
                //System.Threading.Thread.Sleep(1);
            }
        }
    }
}

由于我没有您使用的秤,以下内容未经测试:

写入显示重量:

//write current displayed weight with units identifier
//SerialCmdSend("P", false);
SerialCmdSend("P", true);

列出所有参数值:

//list all parameter values
SerialCmdSend("DUMPALL");

传送净重:

//transmit net weight in displayed units
SerialCmdSend("XN");

根据 documentation,“以较慢的波特率连续传输可能需要 EOL,以确保在传输另一个字符串之前接收缓冲区为空。 ".

您可能还想查看 STREAM 设置选项,其中“...选择用于连续传输的串行端口”。

更新:

这里有一些可能有用的附加信息:

打开 PowerShell 并运行以下内容:

  • Get-WmiObject -Class Win32_SerialPort
  • Get-WmiObject -Class Win32_SerialPortConfiguration
  • Get-WmiObject -Class Win32_PnPEntity -filter "Name LIKE '%(com%)%'"
  • mode

资源: