【AllJoyn专题】基于AllJoyn和Yeelink的传感器数据上传与指令下行的研究-程序员宅基地

技术标签: 操作系统  c/c++  嵌入式  

接触高通物联网框架AllJoyn不太久,但确是被深深地吸引了。在我看来,促进我深入学习的原因有三点:一、AllJoyn开源,对开源的软硬件总会有种莫名的喜爱,虽然或许不会都深入下去;二、顺应潮流,物联网虽远未普及,但已是大势所趋,高通公司在领域布局,致力于打造舒适高效的智能家居场景,推出AllJoyn软件框架,适应了发展趋势;三、文档丰富,开源软件的使用,特别是框架,若没有文档相助,相信没有多少开发人员愿意尝试,AllJoyn在这方面做得不错,日后还需做得更好。当然啦,也有些额外原因,包含高通的大力推广,个人对C++的喜爱等等。

 

近期,依据之前所学,利用AllJoyn和国内受人欢迎的Yeelink物联网平台完毕了一个简单的Web of Things的小系统。我们知道随着因特网的蓬勃发展和物联网在全球的兴起,一个新的执行模式也在悄然诞生,即Web of Things,简称为WoT。它可被理解为是IoT的一部分,集中实现以Web方式来控制和管理物联网中的资源,包含各种网关及网关上的传感器,其主旨是提倡通过REST Web API的形式直接对智能终端与网关上的资源进行开放,用户能够通过訪问互联网的方式来訪问终端的数据资源,这就是典型的互联网模式。而Yeelink平台恰好能提供这种功能需求,所以我选择了它作为应用层;而在网络层能够细分为两种,一种是公网传输,即借助眼下成熟的互联网,二种是局域网传输,AllJoyn与生俱来的局域传输能力就在这里得到了体现;最以下为感知层,即Arduino终端作为网关接各种感知设备。结构示意图如图0所看到的:


眼下系统实现的两大功能例如以下:

1、上传温度传感器採集的温度值至Yeelink平台,在平台上以易读方式显示;

2、通过点击平台上的虚拟开关向感知层的Arduino终端发出命令,控制LED灯的亮灭;


1 工具和开发环境

AllJoyn

关于AllJoyn的介绍,我相信维基百科和官方文档会比我说得具体得多,可參考后文的链接。依照我眼下的理解就是用它能够实现邻近设备间的互联互通,无论是什么设备,仅仅要支持alljoyn,通过wifi、蓝牙都可高速连接,实现信息共享和及时通信。它的优点之中的一个就在于支持多编程语言和多平台,很方便开发人员的使用


Yeelink

Yeelink是一个国内开放的的物联网平台,每一个注冊用户都可免费加入设备及传感器,利用平台提供的Restful接口,实现对各个传感器的代码訪问,从而能够实现传感器数据上传和控制终端等多种功能。有这样一个免费平台,相信对开发人员来说是一大福音!

 

软件环境

我眼下服务端是在windows 7系统下做此实验,如若在linux环境下执行,需改动部分平台相关代码。集成开发环境是Visual Studio 2012,非常强大的IDE,在x86平台下用scons命令生成的samples目录下相同都是VS项目文件。client的实现则是用开源硬件流行的IDE——arduino-1.5.6-r2,它支持arduino due开发板,用它可进行文件的编辑与烧写。

 

硬件环境

除了x86 PC,大点的就仅仅是arduino due开发板了。日前智能硬件的盛行也促进了开源硬件领域的发展,用arduino等相关成熟硬件可高速做系统原型,大量节约成本,在适当情况下是个非常好的技术解决方式。令开发人员欣慰的是,开源硬件社区非常流行,所以有非常好的问题解决资源。

有arduino板,但无传感器可不行。为方便起见,我眼下所展示的就仅仅是温度传感器DS18B20一种。因为详细的传感器数据获取与alljoyn并无关联,所以就以温感为例阐述基于alljoyn的传输数据,其他传感器数据就与之类似了。另外,为了配合控制指令下传,配备了一个发光二极管,当然这是arduino due板上已有的,在13号引脚上。


---------------------------------------------------------------------------------------------------- --------------

友情建议:建议刚開始学习的人学习x86平台下的alljoyn时,先可直接在VS下进行编辑生成,毕竟有比較好的代码提示功能,熟练后再可用notepad等工具。如若刚学就在notepad上写代码,会非常让人无奈,由于一大堆函数和參数你都不知道,不easy发现错误。

---------------------------------------------------------------------------------------------------- --------------


2 结构框架

本系统共同拥有两个Arduino Due开发板作client,因为是瘦client,所以须要标准client提供Daemon才可连接,这一点在官方文档中讲得非常明确,不再赘述;Windows 7 PC端作为服务端,公布服务供瘦client连接,或许有朋友注意到了这与官方样例ledctrl和AJ_LedService不太一样,客户与服务的角色颠倒了,瘦client不再作为服务而是客户了;另外一方面,PC服务端通过互联网与Yeelink平台进行交互,实现数据上传与接收指令,接收到的指令又通过AllJoyn总线控制瘦client,从而实现了Yeelink平台下基于AllJoyn的传输数据与控制功能。其结构框图如图1所看到的:



3 各子系统具体解释


3.1 Yeelink平台

要想利用Yeelink资源,就须在官网注冊一个唯一帐号,在用户中心进行设备和传感器加入。例如以下图所看到的,我加入了arduino设备


接下来在“我的设备”项,加入温度传感器和控制开关,系统会为每个设备生成唯一的URL,通过URL就能够訪问特定传感器了。详细操作文档可參考这里:http://www.yeelink.net/develop/api


3.2 PC服务端

在讲到接下来的服务和客户实现时,我会就核心代码作具体解析,而不会写上完整代码,望读者理解

服务端主流程例如以下图所看到的:


上图是主线程的流程,因为在PC上是多线程执行,所在在监听对象、总线对象上都有额外的线程执行,它们是异步的,也就意味着当事件发生时,能够迅速得到响应,比方当服务端收到温感瘦client传来看温度时,总线对象就调用其方法处理函数向Yeelink平台上传。以下就重点细节来谈谈怎样设计服务端


首先创建总线对象,然后给总线对象加入接口。接口中有一个sendTemp方法,带一个字符串输入參数,有一个ledSwitch信号,带一个uint8_t型參数。最后激活接口和启动总线


接下来创建监听和总线对象,分别给总线注冊监听和总线对象实例,最后总线实例開始连接本地router


在监听类中,我们又一次实现了几个虚函数,包含

bool AcceptSessionJoiner(SessionPortsessionPort, const char* joiner, const SessionOpts& opts)

void SessionJoined(SessionPort sessionPort,SessionId id, const char* joiner)

void NameOwnerChanged(const char* name,const char* previousOwner, const char* newOwner)

前两个是服务端特有的,当有客户接入时,会自己主动被调用;最后一个服务和客户都可调用,当有服务或客户进入或退出时,总线上会发生名称改变,从而它被调用,有时不止一次。这三个虚函数的实现基本是常规写法,就不在此解说了

 

在总线对象实例的构造中,我是这样做的:

首先给总线加入已经设置的接口,为sendTemp方法加入方法处理函数,同一时候给私有成员ledSwitchMember设置值


在方法处理函数中,获取传过来的温度值,字符串形式,就往yeelink平台上传:


我须要强调的是,在makeString方法中,若要正确拼装成http post请求,有几条属性不能少,于是定义了四个全局数组:

char yeelink_server[] = "api.yeelink.net";
char temp_path[] = "/v1.0/device/9966/sensor/19877/datapoints";
char switch_path[] = "/v1.0/device/9966/sensor/22595/datapoints";
char apikey[] = "d3d565a5923afdd82105e0e5a";

相应着post请求中的下面项:

POST /v1.0/device/9966/sensor/19877/datapoints HTTP/1.1

Host: api.yeelink.net

U-ApiKey: d3d565a5923afdd82105e0e5a

host和path共同组成了传感器的URL,具体说明可參见yeelink文档


至于在初使化windows socket函数中,也需用到yeelink_server,填入相关结构的域,例如以下所看到的:

这部分是与平台相关的,若移植到linux平台,须要改动


在总线对象类中,另一个成员函数emitLedSwitchSignal用于主线程发射信号给led瘦client

将发来的參数封装成message參数,和信号一起发送出去,注意sessionid为ledclientid


我们回到主线程main中,Connect之后就開始公布服务了,三步曲:Request,CreateSession,Advertise


最后进入循环,轮询我在yeelink中加入的控制开关状态:

在这里我採取的是被动轮询开关状态的方式,事实上不是最佳的,最好是开关状态一改变,就像硬件中断似的,立马通知CPU,而在此之前CPU全然能够去做其他事。但这须要yeelink平台的主动发送,貌似不太好办,所以就隔断时间轮询状态了。时间间隔也要选好,大了,LED灯变化有延迟;小了,请求太频繁又被yeelink拒绝。那么怎样轮询呢?事实上与上传温度差点儿相同,还是组装(只是如今是GET请求)、初使化socket,只是在接收中我是这么做的:

相关注意点已在凝视中说明。之所以待状态改变后才发射信号,也是为了性能着想,没有必要在状态未改变时也发射。最后返回的值是一个uint8_t型,取值为0或1,0表示熄灭LED灯,1表示点亮LED灯。仅仅要开关状态改变,就把此信息发送给LED瘦client


3.3 温感瘦client

写client代码之前,首先建立目录,起名需和.ino文件的主名保持一致,这是arduino环境默认的习惯。我将着重讲述温感数据的发送过程,至于获取温度值,读者可參考arduino中文社区的这个帖子:http://www.arduino.cn/thread-1345-1-1.html,同一时候下载四个源文件:

DallasTemperature.cpp,DallasTemperature.h,OneWire.cpp,OneWire.h,这属于获取温度的库,所有和ino文件放在一起

另外创建另外一个cpp文件,为alljoyn相关的核心文件,传输温度值。以下着重讲述这个文件

首先要重视下面几个数据结构的书写:

服务名、路径、port、接口名务必和服务端保持一致,接口中必需要有sendTemp方法,携带一个字符串參数,其他的和Dummy作用一样,作填充;SEND_TEMP表示为AJ_PRX_MESSAGE_ID型


在AJ_Main中,首先做例如以下工作:

成功连上服务后,StartClient才会返回


接下来才是核心动作,获取温度、方法调用、睡眠,再循环:

因为我不关心后面的解消息过程,所以重点就是前几句,方法调用例如以下:

首先marshal方法,然后marshal參数,即温度值,最后deliver。这样,就会导致服务端的方法回调函数被调用


3.4 LED瘦client

这一端与温感有些地方类似,只是文件就仅仅有2个,一个ino,一个以alljoyn为主的cpp

主要改动在于在sampleInterface中,加入ledSwitch信号"!ledSwitch instr>y",再提前定义#define LED_SWITCH  AJ_PRX_MESSAGE_ID(0, 0, 2)

開始阶段当然就与温感类似了,StartClient成功后,就開始解消息,由于服务端的信号要过来了:

当信号过来后,检验消息ID,发现是LED_SWITCH,就解參数,获取开关状态。假设为1,则点亮LED;为0则熄灭之。另外在这个client就不用睡眠了,由于是被动接收服务端的信号


4 演示验证

待服务、两个client代码实现后,服务端生成exe文件,连接好硬件,client分别烧入两个arduino due开发板。粗略图例如以下图:


那个红色板上面就有DS18B20温度传感器,三个引脚号接入到了当中一个arduino板的引脚上。两个板子都与主机PC通过路由器同处一个局域网内部。还得强调一点,若要使PC服务端能与板子通信,必须启动瘦clientSDK bin下的SampleDaemon.exe程序,由于服务端并没有绑定的Daemon,它就是来提供Daemon给瘦client使用的,其源代码能够\alljoyn-14.02.00-src\alljoyn_core\samples\SampleDaemon找到

以下首先看温度传感器的验证

连接好硬件上电,打开yeelink平台的温度传感器的显示页面,方便随时刷新;点击arduino IDE,按shift+ctrl+M打开串口终端,有例如以下显示:


如若没有SampleDaemon,是不会有最后一句输出的;接下来在命令行运行服务端程序:



正如上图所看到的,服务端一启动,就发现了客户接入,接入成功之后開始会话。因为我的开关初使状态是开着的,程序默觉得关,所以状态改变就发射了一次信号;同一时候收到了温感一端发来的温度值;串口终端的打印也表明传送温度成功,字符'f'的输出是我的输出函数的小问题,暂无论它。几秒钟之后,成了这样:


咦?为什么温度上升了呢?呵呵,那是由于我把手指放在DS18B20上了!它当然温度升高啦。此时我们再来看yeelink上温感的反应:


不负所望,在14年9月13日 12:26:34分显示了最初的温度值26.6,前面的为之前的数据了。这也就实现了在线监控温度的功能了


在另外一client,打开串口窗体:



服务端收到了另外一客户的接入,NameOwnerChanged被调用了好几次,倘若我接下来在用鼠标点击yeelink的控制开关,即下图所看到的:


服务和瘦client的反应是:



由结果可知,我是开了一次开关,又关了一次开关,导致client先后接到1,0,过程中观察LED灯的反应就是一亮一灭,同一时候温度值也可在下图中收到:


上面应该是传输错误才出现了a字符

到此为止,整个预先设想功能基本实现了


5 值得改进

1、能够添入很多其它传感器,从而让功能更加丰富

2、能够让第三个瘦client充当服务,比方用arduino板,移动手机等等,假设处理能力满足条件的话。由于作为多个客户的服务端,数据处理能力应该要强些,假设仅仅是单线程,像arduino板,是否能处理值得验证

3、能够给温度传感器设定阈值,一旦温度超过给定值就採取报警,鸣响蜂鸣器之类的设备


6 參考链接

AllJoyn官方1:https://allseenalliance.org/         

AllJoyn官方2:https://www.alljoyn.org/

Yeelink官网:http://www.yeelink.net/

Arduino Due介绍:http://www.arduino.cc/en/Main/ArduinoBoardDue

Arduino 中文社区:http://www.arduino.cn/


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_33857679/article/details/85695708

智能推荐

攻防世界_难度8_happy_puzzle_攻防世界困难模式攻略图文-程序员宅基地

文章浏览阅读645次。这个肯定是末尾的IDAT了,因为IDAT必须要满了才会开始一下个IDAT,这个明显就是末尾的IDAT了。,对应下面的create_head()代码。,对应下面的create_tail()代码。不要考虑爆破,我已经试了一下,太多情况了。题目来源:UNCTF。_攻防世界困难模式攻略图文

达梦数据库的导出(备份)、导入_达梦数据库导入导出-程序员宅基地

文章浏览阅读2.9k次,点赞3次,收藏10次。偶尔会用到,记录、分享。1. 数据库导出1.1 切换到dmdba用户su - dmdba1.2 进入达梦数据库安装路径的bin目录,执行导库操作  导出语句:./dexp cwy_init/[email protected]:5236 file=cwy_init.dmp log=cwy_init_exp.log 注释:   cwy_init/init_123..._达梦数据库导入导出

js引入kindeditor富文本编辑器的使用_kindeditor.js-程序员宅基地

文章浏览阅读1.9k次。1. 在官网上下载KindEditor文件,可以删掉不需要要到的jsp,asp,asp.net和php文件夹。接着把文件夹放到项目文件目录下。2. 修改html文件,在页面引入js文件:<script type="text/javascript" src="./kindeditor/kindeditor-all.js"></script><script type="text/javascript" src="./kindeditor/lang/zh-CN.js"_kindeditor.js

STM32学习过程记录11——基于STM32G431CBU6硬件SPI+DMA的高效WS2812B控制方法-程序员宅基地

文章浏览阅读2.3k次,点赞6次,收藏14次。SPI的详情简介不必赘述。假设我们通过SPI发送0xAA,我们的数据线就会变为10101010,通过修改不同的内容,即可修改SPI中0和1的持续时间。比如0xF0即为前半周期为高电平,后半周期为低电平的状态。在SPI的通信模式中,CPHA配置会影响该实验,下图展示了不同采样位置的SPI时序图[1]。CPOL = 0,CPHA = 1:CLK空闲状态 = 低电平,数据在下降沿采样,并在上升沿移出CPOL = 0,CPHA = 0:CLK空闲状态 = 低电平,数据在上升沿采样,并在下降沿移出。_stm32g431cbu6

计算机网络-数据链路层_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输-程序员宅基地

文章浏览阅读1.2k次,点赞2次,收藏8次。数据链路层习题自测问题1.数据链路(即逻辑链路)与链路(即物理链路)有何区别?“电路接通了”与”数据链路接通了”的区别何在?2.数据链路层中的链路控制包括哪些功能?试讨论数据链路层做成可靠的链路层有哪些优点和缺点。3.网络适配器的作用是什么?网络适配器工作在哪一层?4.数据链路层的三个基本问题(帧定界、透明传输和差错检测)为什么都必须加以解决?5.如果在数据链路层不进行帧定界,会发生什么问题?6.PPP协议的主要特点是什么?为什么PPP不使用帧的编号?PPP适用于什么情况?为什么PPP协议不_接收方收到链路层数据后,使用crc检验后,余数为0,说明链路层的传输时可靠传输

软件测试工程师移民加拿大_无证移民,未受过软件工程师的教育(第1部分)-程序员宅基地

文章浏览阅读587次。软件测试工程师移民加拿大 无证移民,未受过软件工程师的教育(第1部分) (Undocumented Immigrant With No Education to Software Engineer(Part 1))Before I start, I want you to please bear with me on the way I write, I have very little gen...

随便推点

Thinkpad X250 secure boot failed 启动失败问题解决_安装完系统提示secureboot failure-程序员宅基地

文章浏览阅读304次。Thinkpad X250笔记本电脑,装的是FreeBSD,进入BIOS修改虚拟化配置(其后可能是误设置了安全开机),保存退出后系统无法启动,显示:secure boot failed ,把自己惊出一身冷汗,因为这台笔记本刚好还没开始做备份.....根据错误提示,到bios里面去找相关配置,在Security里面找到了Secure Boot选项,发现果然被设置为Enabled,将其修改为Disabled ,再开机,终于正常启动了。_安装完系统提示secureboot failure

C++如何做字符串分割(5种方法)_c++ 字符串分割-程序员宅基地

文章浏览阅读10w+次,点赞93次,收藏352次。1、用strtok函数进行字符串分割原型: char *strtok(char *str, const char *delim);功能:分解字符串为一组字符串。参数说明:str为要分解的字符串,delim为分隔符字符串。返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。其它:strtok函数线程不安全,可以使用strtok_r替代。示例://借助strtok实现split#include <string.h>#include <stdio.h&_c++ 字符串分割

2013第四届蓝桥杯 C/C++本科A组 真题答案解析_2013年第四届c a组蓝桥杯省赛真题解答-程序员宅基地

文章浏览阅读2.3k次。1 .高斯日记 大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?高斯出生于:1777年4月30日。在高斯发现的一个重要定理的日记_2013年第四届c a组蓝桥杯省赛真题解答

基于供需算法优化的核极限学习机(KELM)分类算法-程序员宅基地

文章浏览阅读851次,点赞17次,收藏22次。摘要:本文利用供需算法对核极限学习机(KELM)进行优化,并用于分类。

metasploitable2渗透测试_metasploitable2怎么进入-程序员宅基地

文章浏览阅读1.1k次。一、系统弱密码登录1、在kali上执行命令行telnet 192.168.26.1292、Login和password都输入msfadmin3、登录成功,进入系统4、测试如下:二、MySQL弱密码登录:1、在kali上执行mysql –h 192.168.26.129 –u root2、登录成功,进入MySQL系统3、测试效果:三、PostgreSQL弱密码登录1、在Kali上执行psql -h 192.168.26.129 –U post..._metasploitable2怎么进入

Python学习之路:从入门到精通的指南_python人工智能开发从入门到精通pdf-程序员宅基地

文章浏览阅读257次。本文将为初学者提供Python学习的详细指南,从Python的历史、基础语法和数据类型到面向对象编程、模块和库的使用。通过本文,您将能够掌握Python编程的核心概念,为今后的编程学习和实践打下坚实基础。_python人工智能开发从入门到精通pdf

推荐文章

热门文章

相关标签