从 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
资源:
- 420 Plus HMI Digital Weight Indicator Installation Manual
- System.IO.Ports Namespace
- SerialPort Class
- SerialPort.NewLine
- SerialPort.ReadExisting
- SerialPort.ReadLine
- DTREnable
- Handshake
- Handshake Enum
- How to update a RichTextBox from BackgroundWorker using BeginInvoke
- Serial port communication issue in WPF using VSPE
- I need SerialPort event on NewLine received
- C# Async Serial Port Read
- Communicating With Serial Port In C#
- PowerShell - Get-WmiObject
- PowerShell - LIKE operator
在梅特勒-托利多 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
资源:
- 420 Plus HMI Digital Weight Indicator Installation Manual
- System.IO.Ports Namespace
- SerialPort Class
- SerialPort.NewLine
- SerialPort.ReadExisting
- SerialPort.ReadLine
- DTREnable
- Handshake
- Handshake Enum
- How to update a RichTextBox from BackgroundWorker using BeginInvoke
- Serial port communication issue in WPF using VSPE
- I need SerialPort event on NewLine received
- C# Async Serial Port Read
- Communicating With Serial Port In C#
- PowerShell - Get-WmiObject
- PowerShell - LIKE operator