CfetPlc的理解

ArduSensorPlatform

基本模型:

Host:我觉得可以想象为一个可以插很多个传感器(Sensor)的主机。 然后Sensor就想象成插在Host上面的一个个传感器,每个Sensor可能包含一个或者多个通道,然后每个通道都对应有一个float数值,其他类型也可以和float相互转换。

代码思路:

ArduSensorPlatform下主要有两个类:

  • Host
  • SensorBase

SensorBase

SensorBase是所有你实现的Sensor的基类,实现的Sensor都要继承SensorBase类。
SensorBase类主要定义了Sensor类都需要实现的接口,也就是需要实现的几个功能函数:

  1. GetChannelNum :返回Sensor的通道数
  2. Update:这是整个Sensor最重要的函数,Update函数需要实现Sensor的数据更新,Update需要读入所有通道的最新数据,然后存储到变量里,以及写入所有需要写的通道。或者由update函数完成一些逻辑功能。(这里不太容易解释得非常清楚,可以看完后面的例子之后再回看这部分)
  3. Read:Read函数并不会去读取最新的数值,这个是在update函数时完成的,update函数读取最新的数值之后会保存到一个变量中,Read函数就直接返回这个变量的值
  4. Write:Write函数有两种模式:一种是同步,一种是异步。同步模式时,会将要写的数值先保存到一个变量中,等到update函数执行时,就将这个变量的值写到对应的通道中。异步模式时,会在数值保存到变量中之后,紧接着调用update函数,立刻实现数据的更新。默认为同步模式
  5. SensorBase还包含一个指向自己Host的指针。这个可以用来实现一些逻辑,比如当Host上的另一个传感器的某个通道的值满足某些条件时,改变另外一些通道的值。这个在后面例子Scripter中有体现。

Host

一个Host包含多个Sensor,每个Sensor又有多个通道。Host就按照Sensor加入的顺序,给每个通道依次编号。比如Sensor1有2个通道,Sensor2有3个通道。那Host就依次给标记为1、2、3、4、5号通道。1、2对应Sensor1的2个,3、4、5对应Sensor2的3个通道。Host标记的通道号就叫AbsoluteChannelNum 所以 findAbsoluteChanelNp(int sensorNo, int channelNo)函数就是找到某个Sensor的某个通道对应的AbsoluteChannelNum。

然后这里需要注意:ChannelSamples[i]表示从通道i读入的数据存储的地方。OutputChannelSamples[i]表示的是需要写到通道i的数据的暂存的地方。 所以同样的,

  • Read:并不会读取最新的值,而是直接返回ChannelSamples数组中存储的数据。
  • Write:同步模式下,只将需要写的某通道的值写到OutputChannelSamples数组中暂存。

最后就是Host的Update,同样的Update函数是很重要的函数,Host的Update要实现所有Sensor所有Channel的数据的更新,包括读取新的数值以及写入所有需要写的通道。 要完成所有的Sensor所有Channel更新,需要逐个调用每个Sensor的update,就完成了Sensor数据的更新,然后再更新ChannelSamples数组和OutputChannelSamples数组,把从Sensor更新的数据更新到这两个数组里面来。

具体例子

Dioport

顾名思义,就是数字IO口的Sensor。 总共一个通道,有8个1bit的io sample[1]就是读入的数值,write就是要写出的数值。 outputMask是指定哪个引脚可用,哪个不可用。 (这个地方可能理解错了,不是指定哪个引脚可用哪个不可用,可用不可用是通过PinList里面的值来指定的,>0表示该引脚可用。OutputMask用来指定的是该引脚是输入还是输出,从代码的这个地方可以看出来

Scripter

Scripter Sensor的概念类似一种“软件Sensor”,就是说它没有硬件与之对应。 但是Scripter给我们展示了可以通过这种 软件Sensor 来实现一些逻辑,实现对其他Sensor其他通道的控制。 这里的update函数中:读取了Host的第1个Sensor的第一个通道值,然后把这个值取反又写了回去,这样在每次Scripter的update函数被执行的时候,Host的第一个Sensor的第一个通道的值都会取反一次

int Scripter::Update()
{
    auto value = (uint8_t)MyHost->Read(0, 0);
    value = ~value;
    MyHost->Write(0, 0, (float)value);
    return 0;
}

本文章使用limfx的vscode插件快速发布