您的位置:首页 > 大数据 > 物联网

物联网可编程逻辑控制器(三)

2016-12-03 20:47 169 查看
在上一期的文章里,我们介绍了很多针对MiCO系统移植eCLR运行内核的相关基础,在eCLR内核移植完成后,我们就可以使用MULTIPROG对MiCOKit-Nucleo开发板进行编程,如下图所示移植好eCLR的MiCOKit-Nucleo开发板运行MULTIPROG示例工程的实际效果(感谢MiCO团队提供的天线,加上去过后,WIFI信号真心好太多了,MULTIPROG连接开发板各种不卡,各种流畅,前面没有加天线还小小痛苦了一阵子):

 


图:3.1
 

大家可能会有疑惑,就这样结束了吗,从此MULTIPROG就可以对MiCOKit-Nucleo开发板上的各种外设,对系统级的API能够随意调用吗?回答是当然没有这么简单的事情,eCLR移植到客户的硬件平台上并且运行起来后,MULTIPROG中只可以使用最最基础的算法来对设备进行编程,而且这些算法都与外设是没有任何关系的,默认自带的算法如下图3.2图3.3总结:

 


图3.2
 


 
图3.3
 

所以仅仅是这些通用基础算法当然是满足不了我们对于开发产品的要求,至少我们要的就是如何访问设备上的I2C,SPI与UART等等外设来获得传感器信息以及如何控制OLED,RGBLED与Motor吧?关于这些迫在眉睫的问题,当然eCLR内核是有办法扩展自定义指令集的,下图展示了eCLR内核的架构图:

 


图3.4
 

前面我们介绍到了MiCOKit-Nucleo上的eCLR内核就是基于MiCO系统上的一个应用程序而已,在第二章节我们一起看到了很多移植相关接口,这里就是指的上图中的System
Interface与Communication Interface,只有这两部分运行起来了,MULTIPROG编程软件才能对MiCOKit-Nucleo开发板做一些基础的逻辑编程工作,注意这里说的是只是基础的逻辑编程而已。所以我们要实现一个完整的平台,就肯定需要对外设进行编程,在eCLR内核中有:
Firmware FBs与I/O Interface这两种方式:

1. 对于I/O Interface主要用于扩展硬件的输入输出,例如:开关信号,继电器,模拟量传感器等等,但是我们需要通过带有IEC地址的变量进行访问,这个就比较麻烦了,如果不熟悉IEC61131-3标准的话,使用I/O
Interface对于外设扩展就是一个灾难,当然使用I/O Interface也有好处就是使用起来特别方便,只需要通过变量就可以访问外设了,而不需要每次都连接一个模块才能输入输出。例如在下面图片中我们是直接通过Motor_Start这个变量来获得开关输入,通过Motor这个变量来控制电机起停,读写这两个变量就可以达到我们的目的了,注意这两个变量之所以拥有输入输出的能力是由于用户已经给这两个变量一些特殊地址。



图3.5

 

2. 对于Firmware FBs方式扩展就非常灵活了,我们可以定义一个带输入输出的模块,并且用C/C++实现内部的逻辑,既然有了C/C++的支持,我们可以干任何我们想干的事情,调用任意API去实现我们所需要的功能。使用Firmware
FBs最大的优势就是比较直观,因为我们自己实现的Firmware FBs最终都在FBD代码工作单中这样表示:


 
图3.6
左边是输入,右边是输出,输入输出可以直接与不同模块的同类型端口相连,也可以直接连接到变量上,例如CTUD这个模块的QU是一个输出,连接到了CU_output_temp这个变量上,变量类型可以把鼠标悬停在这个变量上,系统会在弹出的信息框中有显示,对于CU_output_temp这个变量来说,它是BOOL类型与我们在C/C++里面的BOOL含义是一样的。

 

 

所以我们综合前面分析,我决定使用Firmware FBs机制来实现基于MiCOKit-Nucleo开发板外设的Demo。首先我们还是来确定下我们的需求,我们期望实现上面提到的带输入输出的模块来对MiCOKit-Nucleo开发板外设的访问,首先我们看看哪些外设可能是我们的目标,我们尽量会选择哪些比较容易拿出来展示的外设:

1. OLED. 这个用于显示一些文本信息,当然也是非常直观了。

2. RGBLED. 三色的LED灯,这个也不错。

3. HTS221. 温湿度传感器,可以拿来测测看。

4. UVIS25. 紫外线指数传感器,感觉用不着。但是做成模块放在室外墙上挂着给屋内系统提示一点”今天出门是否需要防晒霜”的信息可能也不错,留着吧。

5. LSM9DS1. 九轴运动位置传感器。这个搞无人机的需要,反正我们随便玩玩,还是做下。

6. LPS25HB. 气压传感器。又是跟无人机相关的,留着。

7. 光传感器. 模拟传感器,ADC直接采样。这个比较有用了,室内室外都可能需要。

8. DC Motor. 直流小电机,只有开关两个信号,比较简单,演示起来也比较带劲,打开电机,在桌面上震得还挺厉害的。

9. STMEMS数字麦克风.
暂时就不玩了,这个还要加PDM的库才能转换为PCM数据,其实个人理解麦克风数据采集并不需要直接放在MULTIPROG来编程,而是把麦克风的应用做出来再由MULTIPROG进行管理,例如可以实现一个语音识别的Firmware
FBs,这部分就比较复杂了,RAM&Flash空间都不太够,暂时就不加入Demo演示了。

 

这些外设应该就是MiCOKit-Nucleo开发板上全部的传感器了,只想说实在太丰富了,MiCO团队做的这个传感器板很用心。

 

所以有了目标下面我们就要来看如何利用eCLR的Firmware FBs机制来扩展算法玩转这些传感器了。在eCLR里实现自定义的Firmware
FBs(后面简称固件库)也是非常简单的一件事,按照流程做,肯定就可以实现,当然细节我们没有办法全部介绍到,而且这部分内容是需要购买eCLR的SDK才可以实现,不过我们是来看看观摩下总该可以的:

1. 使用Visual Studio 2015添加一个C#语言实现的动态链接库dll工程,引用eclrlib,pcoslib系统库,保留System库,代码中添加好引用,并且做好对应的系统设定(这里不详细说明了,反正就是工程里面有一些特定的工具配置,这并不是我们的重点)。

 


图3.7
2. 第二步才是我们的重点,我们需要实现一个MiCO_OLED_ShowString算法模块,那么久需要这样定义一个类的名称,并且定义这个模块的输入输出(使用IEC61131语法与C#定义相互匹配,因为涉及到非常细节的开发内容,这里我们并不详细介绍了),构造与析构函数都需要添加,另外添加功能块需要的__Init与__Process函数,功能块定义就完工了,。


 
图3.8
 

3. 把这个工程使用VS2015重新编译下,就会生成给MULTIPROG使用的MiCOlib库(注意这个库我们后面需要在MULTIPROG中导入才能够使用我们扩展的算法模块)

 


与C++源代码模板

 


我们需要把MiCOlib相关的C++代码模板放在IAR中与eCLR核心编译在一起,并且在MiCO_OLED_ShowString::__Process()函数中实现其算法,因为MiCO_OLED_ShowString模块每执行一次MiCO_OLED_ShowString::__Process()也会执行一次。所以我们就来编写实现MiCO_OLED_ShowString的算法吧:

 

大家可以看到在这里我们是直接调用的MiCO API来实现这个算法模块的,我们需要将前面定义的接口传进的数据经过处理后最终传递到MiCO API函数里。这里我们对于MiCO_OLED_ShowString模块的执行是通过一个Execute上升沿信号来进行触发执行,所以只有当Execute输入从FALSE变为TRUE的时候OLED_ShowString函数才会被调用。

 

在实现了MiCOlib库的C++代码后,不要忘记在eCLR初始化过程中执行MiCOlib库的初始化,可以使用下面代码进行初始化:

MiCOlib::init();

MiCOlib::loadLibrary();

 

到这里,控制器内核的代码就结束了,剩下时间就是在MULTIPROG中来测试这个模块了。

 

4. 在MULTIPROG中新建一个工程与MiCOKit-Nucleo开发板连接,并且保证可以下载一个简单的工程,然后插入一个固件库选择前面由VS2015生成的MiCOlib固件库,如下图所示:


 
图3.11
 
这样我们就可以在右边的“编辑向导”中找到MiCOlib中的算法模块,当然在下图里面我已经在MiCOlib中添加了这些传感器的模块定义,这里我们只关注下MiCO_OLED_ShowString模块:

 


图3.12
 

把MiCO_OLED_ShowString模块拖到中间的代码编辑区后,系统会提示定义一个实例名称,我们直接点击确定即可,后面看到的就如下图所示,这个模块仅仅需要输入,所以大家看到的模块只有左边有可连接的参数:


 
图3.13
我们双击蓝色的点定义与这个模块输入类型一样的变量以及常量,编译,并且下载,我们就可以来简单测试测试,切换到调试模式后显示如下图,其中ShowStringExecute为变量,其他几个输入为常量,与我们C/C++编程非常类似,在调试模式下通过双击ShowStringExecute,就可以通过覆盖功能随时改变ShowStringExecute的值为TRUE,前面我们提到过,在C/C++代码实现里面我们是通过一个上升沿来触发该模块的执行,所以当ShowStringExecute的值从FALSE变为TRUE后,OLED_ShowString()这个函数会被执行一次,而不会每个执行周期都会执行,结果如下图:


 
图3.14
 

而此时MiCOKit-Nucleo开发板上则显示了我们通过MULTIPROG编程输入给MiCO_OLED_ShowString_1这个模块的Content连接的常量’Hello
IoT World’。看到这里,是不是觉得很新颖,感觉是不是很方便:


 
图3.15
 

篇幅有限,我们不能一个一个模块全部都介绍,其实所有这些传感器访问模块或者任意你期望的功能都可以通过这种方式作为一个模块来给用户调用,只要你可以使用C/C++代码在IAR中基于MiCO系统来实现,就可以这样做。最后再分享一张将这些功能块都添加到一个工程中并且通过MULTIPROG软件实时捕获温度值并通过逻辑分析仪将曲线实时显示的截图(唔,办公室温度有点偏高,稍稍热了点J):


 
图3.16
 

后记:在实际测试过程中,偶尔发现这些连接在I2C总线上的模块读写速度过慢,会导致PLC一直等待I2C操作从而导致用时过大,而PLC的任务都是周期性执行的,例如1s任务周期如果其执行耗时超过1s,就会出现系统报警而停止当前PLC执行。后续需要进一步测试I2C传感器的API执行时间并且通过异步执行的方式实现传感器数据的读取,以免MULTIPROG中会报警。

 

本章节到这里就结束了,下一个章节也就是我们的最后一个章节了,主要是把Fogcloud2.0在开发板上尝试运行起来并与eCLR内核进行结合,耗费的时间会长点,目前还不确定Fogcloud2.0会占用多少RAM与FLASH空间,在MiCOKit-Nucleo开发板上能挤就挤吧,实在挤不出来就把Bootloader移除,可以省出32KB的FLASH,试试看。

如果大家喜欢我的文章,可以扫描下面二维码关注我的个人公众号<<IoT物联世界>>来获得第一时间的更新以及我的最新动态哦:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: