Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
C
Cfet2NewVacuum
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
JiangYixing
Cfet2NewVacuum
Commits
5f1835ef
Commit
5f1835ef
authored
May 13, 2021
by
JiangYixing
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Upload New File
parent
35686105
Pipeline
#120
failed with stages
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
98 additions
and
0 deletions
+98
-0
NewVacuumThingReadme.md
NewVacuumThingReadme.md
+98
-0
No files found.
NewVacuumThingReadme.md
0 → 100644
View file @
5f1835ef
# 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
>

</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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment