我正在尝试使用 C# 在控制台应用程序或 Windows 窗体应用程序中解析来自 OSI LaserScan AutoSense 615 LiDaR 的输入。
根据制造商,LiDaR 的输出是字节 11111110,然后是 30 字节的强度数据(值介于 00000000 和 11111111 之间)和 30 字节的距离数据(值介于 00000000 和 11111101 之间),然后是字节 11111111,然后是 30字节的强度数据和三十字节的距离数据。
LiDaR 的输出通过专有的 10 针端口到 9 针 RS-422 母端口,然后通过 9 针 RS-422 公端口、SeaLevel 制造的 RS-422 到 USB 适配器和USB 2.0 端口。我已经安装了驱动程序“SeaCOM for Windows v3.7.4”。在 Windows 设备管理器中,我将波特率设置为 14400。波特率 9600 会产生类似的结果。我还尝试了 Prolific USB 到串行 COMM 端口,它将 RS-232 转换为 USB,并产生了类似的结果。
我创建了以下 Windows 窗体应用程序,根据下面的代码隐藏,该应用程序在长度等于两个信息突发长度或 2 * 61 的字节数组中显示前束标头字节 (11111110) 的位置字节。这个位置大部分时间都是个位数。这是正确的起始字节吗?我发现当我将字节数组转换为 BitArray 时,字节的位是从右到左读取的。从索引较小的位置开始读取字节并转到较大的索引仍然很好吗?
如果我找到了 11111110 的位置,我会评估字节 11111111 是否在那个位置加上 61。有时会找到字节 11111111,但大多数时候不是。是否有与我缺少的 RS-422 协议相关的停止位?我的布线是否无法收集所有位?我是否应该从 11111110 开始,收集 60 多个字节,然后开始寻找 11111111?
namespace Serial_Communication
{
public partial class formSerialCommunication : System.Windows.Forms.Form
{
// Constructor formSerialCommunication initializes form components.
public formSerialCommunication()
{
InitializeComponent();
}
// On loading formSerialCommunication, add available port names
// to comboBoxAvailablePorts.
void formSerialCommunication_Load(object sender, System.EventArgs e)
{
comboBoxAvailablePorts.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
}
// Define a buttonOpenPort.Click event handler.
private void buttonOpenPort_Click(object sender, System.EventArgs e)
{
try
{
// If buttonOpenPort has been clicked, but either a COM port is not selected
// or the user has not entered a baud rate, add a message to textBoxReceivedData.
if (comboBoxAvailablePorts.Text == "" || textBoxBaudRate.Text == "")
{
textBoxReceivedData.Text = "Please select port and enter baud rate.";
}
else
{
// Transfer the name of the selected COM port
// to serialPortAssociatedWithFormSerialCommunication.
serialPortAssociatedWithFormSerialCommunication.PortName =
comboBoxAvailablePorts.Text;
// Transfer the user's baud rate
// to serialPortAssociatedWithFormSerialCommunication.
serialPortAssociatedWithFormSerialCommunication.BaudRate =
System.Convert.ToInt32(textBoxBaudRate.Text);
// Try to open the serial port.
serialPortAssociatedWithFormSerialCommunication.Open();
// Cause a transition of progressBarConnectionStatus
// from gray / empty to green / full.
progressBarConnectionStatus.Value = 100;
// Disable buttonOpenPort.
buttonOpenPort.Enabled = false;
// Enable buttonClosePort.
buttonClosePort.Enabled = true;
// Enable buttonReceiveData.
buttonReceiveData.Enabled = true;
}
}
catch(System.UnauthorizedAccessException)
{
textBoxReceivedData.Text =
"An UnauthorizedAccessException has been caught." +
"The exception is thrown when the operating system denies access" +
"because of an input / output error or a specific type of security error.";
}
} // buttonOpenPort_Click
// Define a buttonClosePort.Click event handler.
private void buttonClosePort_Click(object sender, System.EventArgs e)
{
// Close serial port.
serialPortAssociatedWithFormSerialCommunication.Close();
// Set progress bar at gray / empty.
progressBarConnectionStatus.Value = 0;
// Enable buttonOpenPort.
buttonOpenPort.Enabled = true;
// Disable buttonClosePort.
buttonClosePort.Enabled = false;
// Disable buttonReceiveData.
buttonReceiveData.Enabled = false;
// Clear text from textBoxPositionOfLeadingBeamHeaderByteInTwoBurstInput.
textBoxPositionOfLeadingBeamHeaderByteInTwoBurstInput.Text = "";
// Clear text from textBoxReceivedData.
textBoxReceivedData.Text = "";
}
// Create a buttonReceiveData.Click event handler.
private void buttonReceiveData_Click(object sender, System.EventArgs e)
{
// Refresh textBoxPositionOfLeadingBeamHeaderByteInTwoBurstInput.
textBoxPositionOfLeadingBeamHeaderByteInTwoBurstInput.Text = "";
// Refresh textBoxReceivedData.
textBoxReceivedData.Text = "";
try
{
// Define the number of bytes transmitted in one information burst
// from an OSI LaserScan AutoSense 615 LiDaR.
int bytesInInformationBurst = 61;
// Define the number of bits transmitted in one information burst
// from an OSI LaserScan AutoSense 615 LiDaR.
int bitsInInformationBurst = 8 * bytesInInformationBurst;
// Declare a buffer for bytes from the serial port.
byte[] bufferAsByteArray = new byte[2 * bytesInInformationBurst];
// Define an offset at which to write bytes in bufferAsByteArray.
int offset = 0;
// Read into bufferAsByteArray starting at position offset
// bytesTransmittedInASecond bytes.
serialPortAssociatedWithFormSerialCommunication.Read(
bufferAsByteArray,
offset,
2 * bytesInInformationBurst);
// Considering each byte in bufferAsByteArray...
for (int i = 0; i < bytesInInformationBurst; ++i)
{
// If the present byte is 1111110...
if (bufferAsByteArray[i] == 0xFE)
{
// Display the position of the present byte in bufferAsByteArray.
textBoxPositionOfLeadingBeamHeaderByteInTwoBurstInput.Text =
System.Convert.ToString(i);
if (bufferAsByteArray[i + 61] == 0xFF)
{
textBoxPositionOfLeadingBeamHeaderByteInTwoBurstInput.Text +=
";" + System.Convert.ToString(i + 61);
}
break;
}
}
} // try
catch(System.TimeoutException)
{
textBoxReceivedData.Text =
"A TimeoutException has been caught." +
"The exception is thrown when the time allotted for a process or operation" +
"has expired.";
} // catch(TimeoutException)
}
}
}