Commit 5f1835ef authored by JiangYixing's avatar JiangYixing

Upload New File

parent 35686105
Pipeline #120 failed with stages
# New Vaccum Thing功能实现及思路说明
> 之前写过一个读取真空值的Thing,拿到二楼控制室去用了一段时间了,但是后来那个接口要接别的东西,读取真空值要换到另一个设备上去,代码就要重写。
> 而且之前那个写的也比较粗暴,这次重写就把思路理顺一点。
## ComConfig
需要用到串口,不管是RS232还是RS485,基本的配置都是需要的,主要包括:串口名、波特率、数据位、停止位、奇偶校验、握手协议。
## Vacuum
Vacuum Thing所需要实现的基本功能过程是:首先打开串口,然后循环的发送查询指令,然后接收来自真空计的回复,并且更新当前的数值。
因为Thing的TryInit函数最好不要做很多比较复杂的事情,做越简单的事情越好,复杂的事情可以放到Start函数里面做。
所以考虑在TryInit函数中,只将串口的配置读取进来,创建一个ComConfig的对象。然后在Start函数里面完成打开串口,创建循环发送查询指令的线程。
因为初始化并打开串口的部分几乎都是一样的步骤,所以我觉得将这部分抽取出来,单独写成一个函数InitSerialPort更好,然后直接在Start里面调用InitSerialPort
因为串口接收数据是靠的DataReceived事件,所以在初始化串口的时候还要加上处理DataReceived事件的方法。
```C#
public void InitSerialPort()
{
port = new SerialPort(comconfig.com)
{
BaudRate = comconfig.baudrate,
Parity = comconfig.parity,
StopBits = comconfig.stopbits,
DataBits = comconfig.databits,
Handshake = comconfig.handshake,
//不加这个有些带串口的板子用不了,但是有时候加了下面这一句又可能导致一些神秘的问题。
RtsEnable = true
};
port.DataReceived += new SerialDataReceivedEventHandler(DataReceived);
port.Open();
}
```
按照协议文件中写的。查询的指令就只有这一条,所以实现查询指令就很容易。
```
public void Query()
{
byte[] QueryCmd = new byte[] { 0x07, 0x04, 0x00, 0x00, 0x00, 0x02 };
byte[] QueryCmdAddCRC = SoftCRC16.CRC16(QueryCmd);
port.Write(QueryCmdAddCRC, 0, QueryCmdAddCRC.Length);
}
```
<div align = center>
![](images/2021-05-08-15-59-32.png)
</div>
实现循环发送查询指令的时候,考虑到如果串口突然被拔掉或者出了什么问题,那么在调用Query方法的时候肯定会抛出异常,不处理的话程序就没法继续运行下去了,,所以就选择捕获这个一场然后继续运行。但是这样就引入另一个问题,假如拔了串口,程序可以继续跑,但是真空值不会更新,就没办法知道是不是出了问题。所以加了一个叫做PortRunningNormal的标志,并且在其他地方也更新这个PortRunningNormal的值。
```c#
public void RollPollingQuery()
{
while (true)
{
try
{
Thread.Sleep(2000);
Query();
PortRunningNormal = true;
}
catch (Exception e)//如果报错了
{
PortRunningNormal = false;
continue;
}
}
}
```
接收数据通过DataReceived方法来实现,主要部分在if (SoftCRC16.CheckCRC16(RecData))的地方,按照协议内容把数值和负指数值提取出来,然后算出真实的真空值。
由于巨神这个要和xxh的influxdb配合起来看真空值的整个波形,所以要求当真空值数据发生变化时,产生一个事件,事件的payload里面只包含最新的真空值
```
public void DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int n = port.BytesToRead;
byte[] RecData = new byte[n];
port.Read(RecData, 0, n);
double newvalue;
if (SoftCRC16.CheckCRC16(RecData))
{
PresureValue = (uint)(RecData[3] * 256 + RecData[4]);
NegetiveExpValue = (uint)(RecData[5] * 256 + RecData[6]);
newvalue = (PresureValue / 10) * Math.Pow(10, -NegetiveExpValue);
if (newvalue != RealPressureValue)
{
VacuumChangedPayload payload = new VacuumChangedPayload();
payload.NewValue = newvalue;
//产生一个事件,表示真空值发生了改变
MyHub.EventHub.Publish(Path, "VacuumChanged", payload);
}
RealPressureValue = newvalue;
}
}
```
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment