RS485 C# SerialPort 封装 个人总结记录
今天开发完了气象仪的工作内容,总结思路如下:
1.使用了串口读取的方式进行数据读取工作 SerialPort 这个函数,他需要提前输入几个参值 如图所示:
public RS485_FTY6(string comName, int baudRate, Parity parity, int dataBits, StopBits stopBits) {
_comName = comName;
_baudRate = baudRate;
_parity = parity;
_dataBits = dataBits;
_stopBits = stopBits;
SerialPort serialPort = new SerialPort();
//FTY6_command fTY6_Command = new FTY6_command();
//_Command = fTY6_Command;
_serialPort = serialPort;
}
2.数据进行输入 使用
_serialPort.Write
但是写入后,要进行读取设备返回值的操作,需要订阅事件+委托的方式。其中注意此方法一定要 sleep等待一下,不然读不到值!
因为事件没有及时响应从而导致 没有进行相关订阅委托
_serialPort.DataReceived += new SerialDataReceivedEventHandler(FTY6_Get_Message);
Thread.Sleep(100);
其中特别注意 以下场景:需要多次发送相关指令,多次调用返回数据。 注意此处会多次调用 订阅事件+委托, 一定要取消相关订阅关联!!
_serialPort.DataReceived -= new SerialDataReceivedEventHandler(FTY6_Get_Message);
记录一下串口读取数据的方式
byte[] dataTemp = new byte[_serialPort.BytesToRead];
//读取串口数据
_serialPort.Read(dataTemp, 0, dataTemp.Length);
当初以为是数据堵塞的问题,才使用队列+异步的方式,后面发现是订阅没有取消关联,是坑 记录一下,下面贴下 队列异步的方式
其实后面想想不必需要此方式来制约。
private async Task FTY6_QueueAsync(Queue messageQueue) {
bool forTrue=true;
int i = 0;
while (messageQueue.Count>0) { //此处循环+队列 进行相关数据停止
if (forTrue) {
Console.WriteLine($"运行状态{i}");
forTrue = false;
forTrue = await FTY6_GoAsync(messageQueue, i);
Console.WriteLine($"当前队列存在值为{messageQueue.Count}");
i++;
}
}
}
private async Task<bool> FTY6_GoAsync(Queue messageQueue,int number) {
_getValueName = messageQueue.Dequeue().ToString();
var commandList = FTY6_CommandList.allCommand;
Console.WriteLine(_getValueName);
_serialPort.Write((byte[])commandList[number], 0, 8);
_serialPort.DataReceived += new SerialDataReceivedEventHandler(FTY6_Get_Message);
Thread.Sleep(100);
_serialPort.DataReceived -= new SerialDataReceivedEventHandler(FTY6_Get_Message);
return true;
}
private void FTY6_GetALLValue() {
var messageQueue =new Queue(); //创建队列
foreach (var item in FTY6_CommandList.allgetValueName) {
messageQueue.Enqueue(item);//队列增加值
}
FTY6_QueueAsync(messageQueue);
}
}
此时公司项目,具体代码就不贴出来,只是属于个人记录与经验分享