gpt4 book ai didi

c# - 从串口只读取 8 个字符

转载 作者:行者123 更新时间:2023-11-30 12:58:56 25 4
gpt4 key购买 nike

我正在尝试通过制作 RFID 读取器来自学 C Sharp。

我已经创建了一些代码来从串口读取(通过蓝牙 RS232 的 rfid 阅读器)

我希望有人能帮助我解决的问题是:

我的 RFID 阅读器会非常快速地连续传输卡代码,这意味着当我刷卡时,它会用卡代码的不同部分多次触发我的事件处理程序,所以目前我无法一次收到完整的卡代码导致无法处理该卡。

我目前的代码是:

    private SerialPort serialPort = new SerialPort("COM14", 9600, Parity.None, 8, StopBits.One); // set com port

String code; // this stores the code from the RFID reader / serial port
Int32 id; // this is the ID of the person that the RFID code belongs to
String data;

bool addtag;

public Int32 ID // set the ID so it can be passed to other forms
{
get { return id; }
}

public rfidreader()
{
serialPort.DtrEnable = true; // enable data to flow from the SerialPort
OpenSerialPort(); // Call the OpenSerialPort section below

serialPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); // when data is recieved from the RFID reader fire the event handaler
}

public void PauseRFIDReader()
{
addtag = false;
OpenSerialPort();
}

public void CloseSerialPort()
{
serialPort.Close();
addtag = true;
}

private void OpenSerialPort() // called from above
{
try
{
serialPort.Open(); // open the serialport
}
catch // if serail port unavalable show message box, if Retry is pressed run this section again, if cancel carry on without serial port
{
DialogResult result = MessageBox.Show("Failed to connect to the RFID reader" + "\n" + "Check the reader is powered on and click Retry" + "\n\n" + "Press Cancel to use the program without RFID reader", "Error", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);
if (result == DialogResult.Retry)
{
OpenSerialPort(); // if retry is pressed run the sectiona gain
}
else
{
}
}
}

private void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) // data recieved from RFID reader
{
if (addtag == false)
{
data = serialPort.ReadExisting(); // read what came from the RFID reader

if (data.Length >= 9) // check if the string if bigger than 9 characters
{
code = data.Substring(0, 9); // if string is bigget than 9 characters trim the ending characters until it is only 9 long
}
else
{
code = data; // if less that 9 characters use however many it gets
}
MessageBox.Show(code.ToString());
Start(); // start to process the person

}
else
{
}
}

谁能告诉我如何限制事件处理程序在接收到 8 个字符之前触发并且每秒只触发一次?

在此先感谢一位非常困惑的 Ryan

最佳答案

你似乎有两个不同的问题:

  1. 如何一次读八个字符。
  2. 如何限制每秒处理一个卡代码。

这两者可以(并且应该)一起解决。您可以解决 DataReceived 中的第一个问题事件处理程序,但具体细节将取决于第二个。

不幸的是,你的问题说你一次想要八个字符,但你的代码说九个。所以我无法确保细节是正确的。我只是添加一个常量,让你决定。 :)

我推荐这样的东西来处理输入:

private const _maxCharacters = 8;
private code = "";
private BlockingCollection<string> codes = new BlockingCollection<string>();

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (addtag == false)
{
data = serialPort.ReadExisting(); // read what came from the RFID reader

while (data.Length > 0)
{
string fragment =
data.Substring(0, Math.Min(maxCharacters - code.Length, data.Length));

code += fragment;
data = data.Substring(fragment.Length);

if (code.Length == maxCharacters)
{
codes.Add(code);
code = "";
}
}
}
else
{
}
}

注意上面并没有实际处理代码。相反,为了实现每秒一个代码的设计目标,您需要使用上述以外的代码(将延迟引入串行 I/O 本身只会导致问题)。

所以,在不同的线程中:

private static readonly TimeSpan minInterval = TimeSpan.FromSeconds(1);

private void CodeConsumer()
{
TimeSpan lastCode = TimeSpan.MinValue;
Stopwatch sw = Stopwatch.StartNew();

foreach (string code in codes.GetConsumingEnumerable())
{
TimeSpan interval = sw.Elapsed - lastCode;

if (interval < minInterval)
{
Thread.Sleep(minInterval - interval);
}

ProcessOneCode(code);
}
}

别忘了调用codes.CompleteAdding()当你完成从串口读取后,CodeConsumer()线程可以退出。

关于c# - 从串口只读取 8 个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27952452/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com