版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第8章网络通信引言本章学习目标通过本章的学习,来了解一定的网络通信知识深刻理解并掌握网络的层次划分及OSI七层网络模型2熟悉掌握网络通信中的几种协议及协议特性等能够将所学到的知识与编程实例进行有机结合8.1网络基础知识8.2WiFi通信8.3UDP协议8.4TCP协议8.5MQTT协议CONTENTS8.1.1网络基础知识概述4网络的定义是将若干终端设备和中间设备通过某种传输介质连接起来,实现信息交换和资源共享的系统。根据覆盖范围和连接方式的不同,网络可以分为局域网(LAN)、城域网(MAN)和广域网(WAN)等不同类型。它的基本组成要素包括数据传输介质、通信设备(如路由器、交换机)、协议和网络服务等。网络的作用主要包括数据通信、资源共享、信息传递、应用服务等,因此它广泛应用于办公、教育、娱乐等各个领域。已经成为了现代社会生活及发展不可缺少的一环。而计算机网络协议同我们的语言一样,下图展示了两台不同计算机群之间利用TPC/IP进行通信。8.1.2网络层次划分5国际标准化组织(ISO)提出了著名的OSI/RM(OpenSystemInterconnection/ReferenceModel)模型。它将计算机网络体系结构的通信协议划分为七层,自下而上依次为:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。其中第四层完成数据传送服务,上面三层面向用户。除了标准的OSI七层模型以外,常见的网络层次划分还有TCP/IP四层协议以及TCP/IP五层协议,它们之间的对应关系如下图所示:8.1.3OSI七层网络模型6TCP/IP协议毫无疑问是互联网的基础协议,没有它就根本不可能上网,任何与互联网有关的操作都离不开TCP/IP协议。不管是OSI七层模型还是TCP/IP的四层、五层模型,每一层中都要自己的专属协议,以用来完成自己相应的工作以及和上下层级之间进行沟通。OSI七层模型按网络的标准层次划分,如图所示。8.1.4IP地址7网络地址:IP地址由网络号和主机号组成,网络地址的主机号为全0,网络地址代表着整个网络。广播地址:通常称为直接广播地址,是为了区分受限广播地址。广播地址与网络地址的主机号正好相反,广播地址中,主机号为全1。当向某个网络的广播地址发送消息时,该网络内的所有主机都能收到该广播消息。组播地址:D类地址就是组播地址;A类地址以二进制0开头,第一字节为网络号,地址范围为~55;B类地址以二进制10开头,前两字节为网络号,地址范围为~55;C类地址以二进制110开头,前三个字节作为网络号,地址范围为~55;D类地址以二进制1110开头,地址范围是~55,D类地址作为组播地址;E类地址以1111开头,地址范围是~55,E类地址为保留地址,供以后使用。8.1.4IP地址855:该IP地址指的是受限的广播地址。受限广播地址与一般广播地址的区别在于,受限广播地址只能用于本地网络,路由器不会转发以受限广播地址为目的地址的分组;一般广播地址既可在本地广播,也可跨网段广播。:常用于寻找自己的IP地址。回环地址:/8被用作回环地址,回环地址表示本机的地址,常用于对本机的测试,用的最多的是。A、B、C类私有地址:私有地址不会在全球使用,只具有本地意义。A类私有地址:/8,范围是:~55;B类私有地址:/12,范围是:~55;C类私有地址:/16,范围是:~55。8.1.5子网掩码9为了在网络分段情况下有效地利用IP地址,通过对主机号的高位部分取作为子网号,从通常的网络位界限中扩展或压缩子网掩码,用来创建某类地址的更多子网。但创建更多的子网时,在每个子网上的可用主机地址数目会比原先减少。子网掩码和IP地址一样,由32位二进制地址组成,使用点式十进制来表示。子网掩码由一系列的1和0组成,A类地址的子网掩码为,B类地址的子网掩码为,C类地址的子网掩码为。将32位子网掩码与IP地址进行二进制形式的按位与运算得到的就是网络地址,将子网掩码取反再和IP地址按位与运算得到的就是主机地址。若两个IP地址在子网掩码按位与运算所得结果相同,则说明它们共属于同一子网。8.1.6ARP/RARP10地址解析协议,即ARP(AddressResolutionProtocol),是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。地址解析协议是建立在网络中各个主机互相信任的基础上的,网络上的主机可以自主发送ARP应答消息,其他主机收到应答报文时不会检测该报文的真实性就会将其记入本机ARP缓存;由此攻击者就可以向某一主机发送伪ARP应答报文,使其发送的信息无法到达预期的主机或到达错误的主机,这就构成了一个ARP欺骗。ARP命令可用于查询本机ARP缓存中IP地址和MAC地址的对应关系、添加或删除静态对应关系等。8.1.7路由选择协议11常见的路由选择协议有:RIP协议、OSPF协议。RIP协议:底层是贝尔曼福特算法,它选择路由的度量标准(metric)是跳数,最大跳数是15跳,如果大于15跳,它就会丢弃数据包。OSPF协议:OpenShortestPathFirst开放式最短路径优先,底层是迪杰斯特拉算法,是链路状态路由选择协议,它选择路由的度量标准是带宽,延迟。8.1网络基础知识8.2WiFi通信8.3UDP协议8.4TCP协议8.5MQTT协议CONTENTS8.2.1WLAN与WiFi13WLAN(WirelessLocalAreaNetwork,无线局域网)是指利用射频(RadioFrequency,RF)技术,使用电磁波并利用无线信道作为传输介质的计算机网络。以此所构成的局域网络,在空中进行通信连接。WLAN技术的出现是为了弥补有线网络的不足,以达到网络延伸到目的,实现无网线、无距离限制的通常网络。目前常用的WLAN实现技术有蓝牙、zigbee、WiFi等。8.2.2IEEE802协议簇14IEEE802协议簇是指IEEE标准中关于局域网(LAN)和城域网(MAN)的一系列标准。IEEE802中定义的服务和协议限定在OSI七层网络模型的最低两层,即数据链路层和物理层。实际上,IEEE802又将OSI的数据链路层分成了两个子层,逻辑链路控制层(LLC)和媒介访问控制层(MAC)。如下图所示。一般情况下,LLC层及以上由软件实现,MAC子层和PHY主要由硬件实现。IEEE802协议簇由IEEE802标准委员会维护。其中最广泛应用的协议有以太网(802.3)和WLAN(802.11)。8.2.2IEEE802协议簇15相关概念AP(AccessPoint):即为无线接入点。是一个无线网络的创建者,是网络的中心节点。一般家庭或办公室使用的无线路由器就一个AP。STA(Station):任何一个接入无线AP的设备都可以称为一个站点。也就是日常接入路由器的设备。SSID(ServiceSetIdentifier):每个无线AP都应该有一个标示用于用户识别,SSID就是这个用于用户识别的的名字,也就是我们经常说到的WiFi名。BSSID:每一个网络设备都有其用于识别的物理地址,即MAC地址,其一般情况下出厂会有一个默认值,可更改,也有其固定的命名格式,也是设备识别的标识符。而BSSID是针对设备而规定的,对于STA的设备来说,AP接入点的MAC地址就是BSSID。ESSID:与SSID相同,只是当有多种无线路由器都为同一种名称,那么便相当于将SSID扩大了,因此这几种无线路由器共同的这个名字就叫ESSID。8.2.2IEEE802协议簇162.应用模式STA在WLAN(无线局域网)中一般为客户端,可以是装有无线网卡的计算机,也可以是有WiFi模块的智能手机,可以是移动的,也可以是固定的。在无线环境中STA接入的过程包括:认证STA有没有权限和AP(接入点)建立链路;STA能不能接入WLAN;以及STA接入WLAN网络之后,认证STA能不能访问网络的权限。在STA和AP建立链路的过程中,当STA通过信标(Beacon)帧或探测响应(Proberesponse)帧扫描到可接入的SSID(服务集标识符)后,会根据已接收到的Beacon帧或Proberesponse帧的信号强度指示(RSSI)来选择合适的SSID进行接入。8.2.2IEEE802协议簇173.分层结构802.11协议定义了WLAN物理层以及MAC层的协议标准。其结构图如图所示:8.1网络基础知识8.2WiFi通信8.3UDP协议8.4TCP协议8.5MQTT协议CONTENTS8.3.1UDP协议特性19UDP用户数据报协议,是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。UDP通讯时不需要接收方确认,属于不可靠的传输,可能会出现丢包现象,实际应用中要求程序员编程验证。无连接性:UDP协议在传输数据之前不需要建立连接,也不需要维护连接状态,可以看作是无阻碍传输,因此传输速度快。不可靠性:UDP协议不保证数据传输的可靠性,因为它不提供重传机制、异常处理等功能,如果数据在传输过程中出现丢失或错误,UDP协议也不会进行任何处理。全双工通信:通信允许数据在两个方向上同时传输。支持广播和多播:UDP协议支持广播和多播,可以将数据同时发送给多个主机。8.3.2UDP协议的报文格式20学习协议其中一个重要的环节就是认识协议报文格式,也就是一个协议具体是怎么组织数据的。UDP协议的报文格式如图所示:UDP报文主体分为两个部分:UDP报头(占8个字节的数据)+UDP数据/UDP载荷。荷载:比较容易理解,里面存储的是应用层的数据报。UDP报头:源端口,目的端口,报文长度,校验和,组成,每个部分占两个字节,可以描述的数据范围是[0,65535]。8.3.3UDP协议编程实例21在使用UDP协议进行编程时,会基于一个重要的网络编程接口Socket,也被称为“套接字”,是网络编程中用于实现不同主机上进程间通信的一种技术。它提供了一种将网络通信抽象为文件操作的接口,使得程序员可以通过简单的函数调用来实现复杂的网络通信功能。基于socket技术的UDP通信流程框图如下所示:8.3.3UDP协议编程实例22本次示例指在Hi3861模块内部建立UDP的客户端,通过去连接电脑端的UDP服务器端来进行通信。其主要实验代码如下:voidTask1(void*argument)//定义了名为Task1的函数,用于接收void类型的参数{intsocket_fd=0;//定义整型变量,用来存储socket描述符intresult;//存储函数调用的结果//设置服务器的地址信息structsockaddr_insend_addr;socklen_taddr_length=sizeof(send_addr);charrecvBuf[512];//连接WifiWiFi_connectHotspots("AI_DEV","HQYJ12345678");//创建socketif((socket_fd=socket(AF_INET,SOCK_DGRAM,0))==-1){console_log_info("createsocketfailed!");return;}//初始化预连接的服务端地址8.3.3UDP协议编程实例23send_addr.sin_family=AF_INET;//设置地址族为IPv4send_addr.sin_port=htons(6789);//远端服务器的端口号send_addr.sin_addr.s_addr=inet_addr("26");//远端服务器的IP地址addr_length=sizeof(send_addr);//发送数据到服务远端result=sendto(socket_fd,"hellofarsight\r\n",strlen("hellofarsight\r\n"),0,(structsockaddr*)&send_addr,addr_length);if(result){console_log_info("result:%d,sendData:%s",result,"hellofarsight");}while(1){memset(recvBuf,0,sizeof(recvBuf));//接收服务端返回的字符串result=recvfrom(socket_fd,recvBuf,sizeof(recvBuf),0,(structsockaddr*)&send_addr,&addr_length);if(result>0){console_log_info("[%s:%d]recvData:%s",inet_ntoa(send_addr.sin_addr),ntohs(send_addr.sin_port),recvBuf);//发送数据到服务远端8.3.3UDP协议编程实例24result=sendto(socket_fd,recvBuf,sizeof(recvBuf),0,(structsockaddr*)&send_addr,addr_length);if(result){console_log_info("result:%d,sendData:%s",result,recvBuf);}}sleep(1);}//关闭socketclosesocket(socket_fd);}总结来说,这段代码的功能是通过UDP协议与指定的服务器进行通信,发送"hellofarsight\r\n"字符串,实现接收服务器能够返回数据并回复的功能。8.1网络基础知识8.2WiFi通信8.3UDP协议8.4TCP协议8.5MQTT协议CONTENTS8.4.1TCP报文字段26TCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的,所以只能用于端到端的通讯。TCP提供的是一种可靠的数据流服务,采用"带重传的肯定确认"技术来实现传输的可靠性。TCP还采用一种称为"滑动窗口"的方式进行流量控制,所谓窗口实际表示接收能力,用以限制发送方的发送速度。TCP报文是TCP层传输的数据单元,也称报文端。TCP报文中的每个字段内容如下图所示:8.4.2三次握手27为了保证客户端和服务器端的可靠连接,TCP建立连接时必须要进行三次会话,也叫TCP三次握手,进行三次握手的目的是为了确认双方的接收能力和发送能力是否正常。所谓三次握手,是指建立一个TCP连接时需要客户端和服务器端总共发送三个报文以确认连接的建立。在socket编程中,这一过程由客户端执行connect函数来直接执行。TCP的三次握手如图所示。第1握手:客户端向服务器发送SYN报文(即报文的标识位SYN=1,seq=J。其进入SYN已发送状态),等待服务器确认。第2握手:服务器接收到客户端的SYN报文后,服务器向客户端发送SYN+ACK报文,并进入SYN_RECV状态,等待客户端确认。服务器发送SYN+ACK报文后,进入SYN_RECV状态,等待客户端确认。第3握手:客户端接收到服务器的SYN+ACK报文,客户端进入ESTABLISHED状态,并向服务器发送ACK报文。服务器接收到客户端的ACK报文后进入ESTABLISHED状态。8.4.2三次握手288.4.3四次挥手29当客户端和服务器不再进行通信时,都会以四次挥手的方式结束连接。TCP的四次挥手如图所示。第1次挥手:客户端向服务器发送断开TCP连接请求的FIN+ACK报文。其中,FIN=11,seq=M,M是客户端随机生成的。客端进入FIN_WAIT_1状态。第2次挥手:当服务器接收到客户端发来的断开TCP连接的请求后,服务器向客户端发送ACK报文,表示已经收到断开TCP请求。第3次挥手:服务器在回复完客户端的TCP断开请求后,不会马上将TCP的连接断开。服务器会先确认TCP断开前,所有传输到客户端的数据是否已经传输完毕。服务器确认数据传输完毕后才进行断开,并向客户端发送FIN+ACK报文。第4次挥手:客户端接收到服务器发来的TCP断开连接报文后,向服务器发送ACK报文,表示收到断开TCP连接报文。其中,ACK报文的ACK=1,ack=N+1,seq=M+1,N为第3次挥手时服务器发送的FIN+ACK报文的seq,M为第1次挥手时客户端发送的FIN+ACK报文的seq。8.4.3四次挥手308.4.4TCP协议的编程实例31本次示例是在Hi3861开发板中创建TCP客户端,在PC电脑端创建TCP服务端,然后可以在两端之间进行传输数据。主要代码如下:voidTask1(void*argument)//定义了一个名为Task1的函数,用于接收参数{intsocket_fd=0;//声明一个整型变量,用于存储socket描述符。charbuff[256];//声明一个字符数组buff,用于接收数据intre=0;//声明一个整型变量re,用于存储函数返回值//连接WifiWiFi_connectHotspots("FS_Hi3861","fs123456");socket_fd=socket(AF_INET,SOCK_STREAM,0);//创建一个TCP套接字structsockaddr_inaddr;//设置服务器的地址信息addr.sin_family=AF_INET;addr.sin_port=htons(5555);addr.sin_addr.s_addr=inet_addr("14");//填写服务器的IP地址re=connect(socket_fd,(structsockaddr*)&addr,sizeof(addr));//连接服务器8.4.4TCP协议的编程实例32if(re==-1){console_log_info("Failedtoconnecttotheserver");return;}console_log_info("Connectiontoserversuccessful");//发送连接成功的消息到服务器send(socket_fd,"Connectiontoserversuccessful.",strlen("Connectiontoserversuccessful."),0);while(1)//进入一个无限循环,以持续接收和发送数据{memset(buff,0,sizeof(buff));re=recv(socket_fd,buff,sizeof(buff),0);//接收客户端发送过来的消息if(re<=0)//如果接收失败或服务器关闭连接,则退出循环break;else{console_log_info("Receivedatareceivedbytheserver:%s",buff);send(socket_fd,buff,sizeof(buff),0);//将接收到的数据发送回服务器}}close(socket_fd);//断开与服务器的连接}8.1网络基础知识8.2WiFi通信8.3UDP协议8.4TCP协议8.5MQTT协议CONTENTS8.5.1MQTT协议通信模型34MQTT(MessageQueuingTelemetryTransport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上,MQTT协议提供一对多的消息发布,可以降低应用程序的耦合性,用户只需要编写极少量的应用代码就能完成一对多的消息发布与订阅,在协议中主要有3种身份:发布者(Publisher)、代理(服务器)(Broker)以及订阅者(Subscriber)。通信模型如图所示。8.5.2MQTT协议相关信息35MQTT协议传输信息:MQTT传输的消息分为Topic(主题)和Payload(负载)两部分:Topic可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容;Payload可以理解为消息的内容,是指订阅者具体要使用的内容。MQTT协议服务质量:MQTT的服务质量(Qos)提供3个等级:Qos=0:最多发送一次消息,在消息发送出去后,接收者不会发送回应,发送者也不会重发消息,消息可能送达一次也可能根本没送达,这个服务质量常用于不重要的消息传递中。QoS=1:最少发送一次消息,QoSl的PUBLISH报文的可变报头中包含一个报文标识符,需要PUBACK报文确认。即需要接收者返回PUBACK应答报文。QoS=2:最高等级的服务质量,消息丢失和重复都是不可接受的。MQTT协议的方法:MQTT协议中定义了一些方法,用来表示对确定资源所进行操作。这个资源可以代表预先存在的数据或动态生成数据,这取决于服务器的实现。通常来说,资源指服务器上的文件或输出。8.5.3MQTT协议数据格式36MQTT控制报文由三部分组成,固定报头、可变报头及有效载荷。MQTT所有收、发的数据都是按照这个格式进行的,它的数据格式图如下图所示。8.5.3MQTT协议数据格式37固定报头:固定报头(Fixedheader)是MQTT协议开头,占用2个字节,由消息类型、标志和剩余长度三部分组成。1)消息类型定义了消息的种类和用途,通过使用不同的MQTT消息类型,可以实现消息的发布、订阅、确认、取消等功能,以满足不同场景的通信需求。消息类型共16个,如下表所示:8.5.3MQTT协议数据格式382)标志(Flags)用于在MQTT协议中标识消息的不同属性和操作。DUP、QoS和RETAIN都属于较为重要的标志。重发标志DUP:当该标志被设置为0时,表示客户端或服务端第一次请求发送这个PUBLISH报文。标志被设置为1,表示这可能是一个早前报文请求的重发。客户端或服务端请求重发一个PUBLISH报文时,必须将DUP标志设置为1。对于QoS0的消息,DUP标志必须设置为0;服务质量等级QoS:是MQTT的避免信息丢失及对数据保护的一个措施;保留标志RETAIN:发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它,如果设有那么推送至当前订阅者后释放。3)剩余长度(RemainingLength)表示当前报文剩余部分的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码。更大的值按下面的方式处理。低7位有效位用于编码数据,最高有效位用于指示是否有更多的字节。因此每个字节可以编码128个数值和一个延续位(continuationbit)。剩余长度字段最大4个字节。8.5.3MQTT协议数据格式39可变报头:可变报头的数据依据固定报头中的报文类型而不同,一般是包含和报文类型相关的数据;例如客户端连接服务器报文,包含了协议名,协议级别(用来表示mqtt的版本信息)、连接标志、保持连接等有效载荷(Payload):发布或接收的数据。有效载荷可以是任何类型的数据,例如文本、二进制流或JSON格式的数据。发布者将有效载荷发布到特定主题上,订阅者可以订阅该主题并接收有效载荷。有效载荷是MQTT协议传输数据的核心,也是其实现低延迟、高效率的重要因素之一。8.5.4MQTT协议编程实例40MQTT是机器对机器(M2M)/物联网(IoT)连接协议。它被设计为一个极其轻量级的发布/订阅消息传输协议。对于需要较小代码占用空间和/或网络带宽非常宝贵的远程连接非常有用,是专为受限设备和低带宽、高延迟或不可靠的网络而设计。这些原则也使该协议成为新兴的“机器到机器”(M2M)或物联网(IoT)世界的连接设备,以及带宽和电池功率非常高的移动应用的理想选择。本次示例则通过连接PC端的MQTT服务器,然后进行订阅主题和发布主题。其主要代码如下:osThreadId_tmqtt_send_task_id;//mqtt订阅数据任务osThreadId_tmqtt_recv_task_id;//mqtt发布数据任务int8_tmqtt_sub_payload_callback(unsignedchar*topic,unsignedchar*payload){console_log_info("[info]topic:[%s]recv<==%s",topic,payload);}//定义了回调函数,用于处理订阅数据时接收到的主题和负载voidmqtt_recv_task(void*argument)//定义了函数mqtt_recv_task,执行订阅数据任务8.5.4MQTT协议编程实例41{while(1)//进入循环,订阅MQTT主题,并每200毫秒执行一次{MQTTClient_sub();usleep(200*1000);}}voidmqtt_send_task(void*argument)//定义函数mqtt_send_task,执行发布数据任务{//连接Wifiif(WiFi_connectHotspots("AI_DEV","HQYJ12345678")!=WIFI_SUCCESS){console_log_info("[error]WiFi_connectHotspots");}begin://用于在连接失败后重新尝试连接MQTT服务器8.5.4MQTT协议编程实例42if(MQTTClient_connectServer(SERVER_IP_ADDR,SERVER_IP_PORT)!=0){console_log_info("[error]MQTTClient_connectServer");sleep(2);gotobegin;}//若连接服务器失败,则等待两秒钟后再次尝试连接if(MQTTClient_init("mqtt_client_123","username","password")!=0){console_log_info("[error]MQTTClient_init");sleep(2);gotobegin;}//如果初始化失败,则等待两秒钟后重新初始化并连接服务器if(MQTTClient_subscribe(MQTT_TOPIC_SUB)!=0){console_log_info("[error]MQTTClient_subscribe");sleep(2);osThreadTerminate(mqtt_recv_task_id);gotobegin;}//若订阅主题失败,则等待两秒钟后终止订阅数据并重新连接服务器//如果订阅主题成功,则创建一个新的线程mqtt_recv_task,并设置线程属性8.5.4MQTT协议编程实例43else{osThreadAttr_toptions;="mqtt_recv_task";options.attr_bits=0;options.cb_mem=NULL;options.cb_size=0;options.stack_mem=NULL;options.stack_size=1024*5;options.priority=osPriorityNormal;mqtt_recv_task_id=osThreadNew((osThreadFunc_t)mqtt_recv_task,NULL,&options);if(mqtt_recv_task_id!=NULL){console_log_info("ID=%d,Createmqtt_recv_task_idisOK!",mqtt_recv_task_id);}}8.5.4MQTT协议编程实例44while(1){MQTTClient_pub(MQTT_TOPIC_PUB,"helloworld!!!",strlen("helloworld!!!"));sleep(1);}//进入循环,发布指定主题的数据"helloworld!!!",并每隔一秒钟执行一次发布操作}Thankyouforwatching.第9章物联网应用引言本章学习目标了解物联网技术在日常生活的实际应用理解开发板中各个电路部分在实验中所起到的作用47掌握各个实例的实验原理,提高实验设计思维熟练运用前面所学到的知识,与本章实例进行结合,以提高学习能力010203049.1智能家居9.2智能交通9.3智能医疗9.4智能安防CONTENTS9.1.1项目框架49本项目使用的是华为云平台作为中间服务器,在设备端(Hi3861):首先进行连接附近的WiFi热点,与华为云平台建立MQTT连接,并且使用JSON格式数据进行交互数据;在应用端(微信小程序):使用HTTP协议与华为云平台进行连接,调用相关API,调用成功之后,会返回JSON格式的数据。在设备端,在连接不上附近WiFi热点的时候,会在OLED显示屏上显示,连接WiFi热点失败的提示信息,此时我们可以使用微信小程序上的NFC烧写界面,将WiFi名称和密码进行烧写开发板上的NFC标签,然后再重新开发板进行重新连接新的WiFi热点。连接成功之后,可以按下开发板上的按键进行切换照明灯的工作模式,每次切换模式都会向华为云平台发送一次数据,在MQTT接收任务中,当接收到云平台接收到数据之后,会进行解析正确的JSON数据包,根据JSON数据包中的命令进行控制本系统中的相关变量。在应用端,首先进行获取项目的Token秘钥信息,获取到Token秘钥信息之后,再去使用“获取设备镜像API”,才能知道当前设备是否在线状态。当同时满足以上两种情况的时候,就可以进行下发指令控制设备端。此外,我们还需要再华为云平台中进行配置相关的基础数据和控制数据格式,配置完成之后,才可以进行通信使用。它的整体框架图如下所示:9.1.1项目框架50511.主控部分本项目使用的是WF-H861-RTA1模组作为主控,此模组是基于Hi3861V100芯片设计的,该芯片是一款高度集成的2.4GHz芯片,集成了IEEE802.11b/g/n基带和RF电路,包括功率放大器PA、低噪声放大器LNA、RFbalun、天线开关以及电源管理模块等。它支持20MHz标准带宽和5MHz/10MHz窄带宽,提供最大72.2Mbit/s物理层速率。并且集成了高性能32位微处理器,提供SPI、UART、I2C、I2S、PWM、GPIO以及多路ADC模拟输入等丰富的外设接口,同时支持SDIO2.0接口,时钟最高支持50MHz。主控部分原理图如下图所示:9.1.2硬件设计522.三色灯部分RGB灯部分所使用的是AW2013控制芯片进行驱动和共阳极的三色LED灯,此芯片支持淡入淡出效果和直接PWM控制模式和一次编程模式,使用的I2C端口与主控芯片进行通信,它可以驱动3个单独的LED灯或一组RGB灯。亮度可以使用PWM进行设置,输出电流可配置4级(0A、5mA、10mA、15mA)。原理图如下图所示:9.1.2硬件设计533.NFC部分NFC通信使用的是NT3H1101芯片,此芯片支持I2C通信,支持可配置的现场检测引脚,内部配备有EEPROM存储芯片,允许在RF和I2C之间快速传出数据,不收EEPROM内存的写入周期进行限制。原理图如图所示:9.1.2硬件设计544.OLED显示屏部分采用SSD1306芯片进行驱动0.96寸OLED显示屏,本显示屏使用黄+蓝屏幕进行显示。点阵数量为128*64。9.1.2硬件设计9.1.3程序设计55该项目的主程序代码如下,首先定义了三个线程ID,分别用于MQTT数据发布、接收和传感器数据采集。定义了smartLamp_Project_example函数,作为该项目的主要入口函数。设置MQTT客户端的订阅回调函数,当接收到消息时会调用这个回调。接着初始化全局变量,设置RGB灯的亮度值为100%,初始化各种外设,包括按键、三色LED灯、三合一传感器、OLED显示屏和NFC模块。externmsg_data_tsys_msg_data;osThreadId_tmqtt_send_task_id;//mqtt发布数据任务IDosThreadId_tmqtt_recv_task_id;//mqtt接收数据任务IDosThreadId_tsensor_collect_task_id;//传感器采集任务IDstaticvoidsmartLamp_Project_example(void){console_log_info("EntersmartLamp_Project_example()!");p_MQTTClient_sub_callback=&mqttClient_sub_callback;//全局变量的初始化sys_msg_data.led_light_value=100;//RGB灯的亮度值为100%的状态//外设的初始化KEY_Init();//按键初始化9.1.3程序设计56AW2013_Init();//三色LED灯的初始化AW2013_Control_RGB(0,0,0);AP3216C_Init();//三合一传感器初始化SSD1306_Init();//OLED显示屏初始化SSD1306_CLS();//清屏nfc_Init();sleep(2);#if1//通过NFC芯片进行连接WiFiuint8_tndefLen=0;//ndef包的长度uint8_tndef_Header=0;//ndef消息开始标志位uint32_tresult_code=0;//函数的返回值//读整个数据的包头部分,读出整个数据的长度if(result_code=NT3HReadHeaderNfc(&ndefLen,&ndef_Header)!=true){console_log_error("NT3HReadHeaderNfcisfailed.result_code=%d",result_code);return;}ndefLen+=NDEF_HEADER_SIZE;//加上头部字节uint8_t*ndefBuff=(uint8_t*)malloc(ndefLen+1);9.1.3程序设计57if(ndefBuff==NULL){console_log_error("ndefBuffmallocisFalied!");return;}if(result_code=get_NDEFDataPackage(ndefBuff,ndefLen)!=HI_ERR_SUCCESS){console_log_error("get_NDEFDataPackageisfailed.result_code=%d",result_code);return;}console_log_info("startprintndefBuff.");for(size_ti=0;i<ndefLen;i++){printf("0x%x",ndefBuff[i]);}CONNECT_WIFI:9.1.3程序设计58if(NFC_configuresWiFiNetwork(ndefBuff)!=WIFI_SUCCESS){console_log_error("nfcconnectwifiisfailed!");oled_consle_log("wifino.");sleep(1);SSD1306_CLS();//清屏gotoCONNECT_WIFI;}else{console_log_info("nfcconnectwifiisSUCCESS");oled_consle_log("wifiyes.");sleep(1);}#endif#if0CONNECT_WIFI://手动输入WiFi信息,连接WiFi9.1.3程序设计59if(WiFi_connectHotspots("AI_DEV","HQYJ12345678")!=WIFI_SUCCESS){console_log_error("connectWiFiHotspots");oled_consle_log("wifino.");sleep(1);SSD1306_CLS();//清屏gotoCONNECT_WIFI;}else{console_log_info("connectWiFiHotspots");oled_consle_log("wifiyes.");sleep(1);}#endifCONNECT_MQTT_SERVER://连接MQTT服务器9.1.3程序设计60if(MQTTClient_connectServer(SERVER_IP_ADDR,SERVER_IP_PORT)!=0){console_log_error("mqttClient_connectServer");oled_consle_log("mqttserno.");sleep(1);SSD1306_CLS();//清屏gotoCONNECT_MQTT_SERVER;}else{console_log_info("mqttClient_connectServer");oled_consle_log("mqttseryes.");sleep(1);}CONNECT_MQTT_CLIENT://初始化MQTT客户端9.1.3程序设计61if(MQTTClient_init(MQTT_CLIENT_ID,MQTT_USER_NAME,MQTT_PASS_WORD)!=0){console_log_error("mqttClient_init");oled_consle_log("mqttclino.");sleep(1);SSD1306_CLS();//清屏gotoCONNECT_MQTT_CLIENT;}else{console_log_info("mqttClient_init");oled_consle_log("mqttcliyes.");sleep(1);}CONNECT_MQTT_SUB://订阅主题9.1.3程序设计62if(MQTTClient_subscribe(MQTT_TOPIC_SUB_COMMANDS)!=0){console_log_error("mqttClient_subscribe");oled_consle_log("mqttsubno.");sleep(1);SSD1306_CLS();//清屏gotoCONNECT_MQTT_SUB;}else{console_log_info("mqttClient_subscribe");oled_consle_log("mqttsubyes.");sleep(1);}SSD1306_CLS();//清屏9.1.3程序设计63定义线程属性,并创建三个线程,分别用于MQTT数据发送、接收和传感器数据采集。最后启动整个项目的运行。osThreadAttr_toptions;="mqtt_send_task";options.attr_bits=0;options.cb_mem=NULL;options.cb_size=0;options.stack_mem=NULL;options.stack_size=1024*5;options.priority=osPriorityNormal;mqtt_send_task_id=osThreadNew((osThreadFunc_t)mqtt_send_task,NULL,&options);if(mqtt_send_task_id!=NULL){console_log_info("ID=%d,Createmqtt_send_task_idisOK!",mqtt_send_task_id);}9.1.3程序设计64="mqtt_recv_task";options.stack_size=1024*5;mqtt_recv_task_id=osThreadNew((osThreadFunc_t)mqtt_recv_task,NULL,&options);if(mqtt_recv_task_id!=NULL){console_log_info("ID=%d,Createmqtt_recv_task_idisOK!",mqtt_recv_task_id);}="sensor_collect_task";options.stack_size=1024*5;sensor_collect_task_id=osThreadNew((osThreadFunc_t)sensor_collect_task,NULL,&options);if(sensor_collect_task_id!=NULL){console_log_info("ID=%d,Createsensor_collect_task_idisOK!",sensor_collect_task_id);}}9.1.4实验结果65在烧写程序前,需要到华为云平台进行设备信息的配置,以便开发板与华为云平台进行连接。云平台配置成功后,将程序编译烧写进开发板,按下开发板的复位按钮,当成功连接WiFi后,会在OLED显示屏界面中会显示当前设备连接附近WiFi热点的提示信息和连接华为云平台服务器的信息,直到在界面中显示如下图所示,说明连接华为云成功。连接成功之后,我们需要打开微信小程序,在小程序中界面中,我们可以点击开关按钮,进行下发指令让设备中RGB灯进行点亮和熄灭操作,还可以进行调整当前RGB灯的颜色值,并且可以调整当前RGB灯的亮度值。010203049.1智能家居9.2智能交通9.3智能医疗9.4智能安防CONTENTS9.2.1项目框架67本项目实现的主要内容:实时监测超声波测距传感器返回的数据;将检测到的数据显示在OLED显示屏上;与障碍物距离小于50cm的时候,进行报警提示。项目整体框架图如下所示。9.2.2硬件设计68本项目模块的整体硬件电路如图所示,硬件部分包含了依然采用了基于Hi3861V100芯片设计的WF-H861-RTA1模组作为主控、AP3216C为核心的传感器模块、蜂鸣器模块以及与SSD1306芯片驱动的0.96寸OLED显示屏等作为主要模块,且全都直接使用I2C总线进行控制。9.2.3程序设计69本项目主要实现了一个智能倒车雷达系统的核心功能,包括串口通信、数据处理、用户界面显示等。通过解析外部设备发送的距离信息,系统可以实时显示距离,并根据距离的远近控制RGB灯和蜂鸣器,提醒驾驶员注意安全距离。首先使用uart_init函数来初始化串口并设置串口2的波特率、数据位、停止位和校验位。随后配置GPIO引脚作为串口的发送和接收引脚。voiduart_init(void){uint32_tret=0;//初始化串口hi_io_set_func(HI_IO_NAME_GPIO_11,HI_IO_FUNC_GPIO_11_UART2_TXD);hi_io_set_func(HI_IO_NAME_GPIO_12,HI_IO_FUNC_GPIO_12_UART2_RXD);hi_uart_attributeuart_param={.baud_rate=115200,.data_bits=8,.stop_bits=1,.parity=0,};ret=hi_uart_init(HI_UART_IDX_2,&uart_param,NULL);if(ret!=HI_ERR_SUCCESS){console_log_error("hiuartinitisfaild.");}}9.2.3程序设计70使用show_page函数:显示智能距离测量的页面,根据传入的距离值val,控制RGB灯闪烁和蜂鸣器音响。并使用parse_json_data函数解析接收到的JSON格式的数据包。voidshow_page(uint16_tval){SSD1306_ShowStr(0,0,"SmartDistance",16);if(val<=50)//5cm{rgb_val^=0xFF;AW2013_Control_Red(rgb_val);//红灯闪烁sys_msg_data.pcf8574_io.bit.p1^=0x01;//蜂鸣器滴滴响PCF8574_Write(sys_msg_data.pcf8574_io.all);}else9.2.3程序设计71{rgb_val=0;AW2013_Control_Red(rgb_val);//红灯灭sys_msg_data.pcf8574_io.bit.p1=1;//蜂鸣器关PCF8574_Write(sys_msg_data.pcf8574_io.all);}//显示数字uint8_tx=val/1000;//显示数字的千位SSD1306_DrawBMP(bmp_number_1.left,bmp_number_1.top,16,32,bmp_16X32_number[x]);x=val/100%10;//显示数字的百位SSD1306_DrawBMP(bmp_number_2.left,bmp_number_2.top,16,32,bmp_16X32_number[x]);x=val/10%10;//显示数字的十位SSD1306_DrawBMP(bmp_number_3.left,bmp_number_3.top,16,32,bmp_16X32_number[x]);x=val%10;//显示数字的个位SSD1306_DrawBMP(bmp_number_4.left,bmp_number_4.top,8,16,bmp_8X16_number[x]);//显示小数点SSD1306_DrawBMP(bmp_dian.left,bmp_dian.top,16,16,bmp_16X16_dian);//显示cmSSD1306_DrawBMP(bmp_danwei.left,bmp_danwei.top,32,32,bmp_32X32_cm);}9.2.3程序设计72voidparse_json_data(void){if(strlen((char*)recvBuff)<=3)return;
cJSON*json_root=cJSON_Parse((constchar*)recvBuff);if(json_root){console_log_success("json_root");cJSON*json_status=cJSON_GetObjectItem(json_root,"status");if(json_status){console_log_success("json_status");cJSON*json_distance=cJSON_GetObjectItem(json_status,"distance");if(json_distance){sys_msg_data.distance=json_distance->valueint;show_page(sys_msg_data.distance);//显示温度页面}json_distance=NULL;}json_status=NULL;cJSON_Delete(json_root);}json_root=NULL;}9.2.3程序设计73voiduart_recv_task(void){hi_u8uart_buff[20]={0};hi_u8last_len=0;uart_init();//串口2初始化while(1){//阻塞接收hi_u32len=hi_uart_read(HI_UART_IDX_2,uart_buff,sizeof(uart_buff));if(len>0){//printf("uart_buff:%s\n",uart_buff);memcpy((char*)pbuff,(char*)uart_buff,len);pbuff+=len;if(len<last_len){pbuff=recvBuff;//回到recvBuff的头位置//printf("buff:%s\n",recvBuff);parse_json_data();memset((char*)recvBuff,0,sizeof(recvBuff));}last_len=len;memset((char*)uart_buff,0,sizeof(uart_buff));}}}9.2.3程序设计74使用主函数,初始化IO扩展芯片、RGB灯和OLED显示屏。创建线程,用于处理串口接收任务。staticvoidReversingRadar_main(void){console_log_info("EnterReversingRadar_main()!");//外设的初始化PCF8574_Init();//初始化IO扩展芯片sys_msg_data.pcf8574_io.bit.p1=1;//关闭蜂鸣器PCF8574_Write(sys_msg_data.pcf8574_io.all);AW2013_Init();//AW2013初始化AW2013_Control_RGB(0,0,0);SSD1306_Init();//OLED显示屏初始化SSD1306_CLS();//清屏SSD1306_ShowStr(0,0,"SmartDistance",16);usleep(200*1000);//创建线程osThreadAttr_toptions;="uart_recv_task";options.attr_bits=0;options.cb_mem=NULL;options.cb_size=0;options.stack_mem=NULL;9.2.3程序设计75options.stack_size=1024*5;options.priority=osPriorityNormal1;uart_recv_task_id=osThreadNew((osThreadFunc_t)uart_recv_task,NULL,&options);if(uart_recv_task_id!=NULL){console_log_info("ID=%d,Createuart_recv_task_idisOK!",uart_recv_task_id);}}SYS_RUN(ReversingRadar_main);9.2.4实验结果76设备端烧写程序成功之后,按下“复位”按键之后,可以看到OLED显示屏上显示检测到的距离,并且当有障碍物遮挡的时候,蜂鸣器和红灯亮起,如下图所示:010203049.1智能家居9.2智能交通9.3智能医疗9.4智能安防CONTENTS9.3.1项目框架78本项目实现将要实现的内容有:实时监测空气中当前的温湿度值;将监测到的信息显示在OLED显示屏上;并根据当前的温湿度值改变表情。项目框架图如下图所示。9.3.2硬件设计79模块整体的硬件设计如图所示,电路中包括了基于Hi3861V100芯片设计的WF-H861-RTA1模组作为主控电路、SSD1306芯片驱动的0.96寸OLED显示屏电路以及SHT20温湿度传感器电路。该传感器配有一个全新设计的CMOSens®芯片、一个经过改进的电容式湿度传感元件和一个标准的能隙温度传感元件,其性能已经大大提升甚至超出了前一代传器(SHT1x和SHT7x)的可靠性水平。且使用I2C总线进行通讯。9.3.3程序设计80本项目主要是实现一个简单的温湿度监控系统,因此本项目代码实现的功能便是读取传感器数据并OLED屏幕上交替显示温度和湿度信息,同时根据温湿度的不同范围显示不同的图标。项目的主体代码如下所示。整个程序的流程是:初始化传感器和OLED屏幕,并创建一个任务来周期性地读取温湿度值,最终在OLED屏幕上交替显示这些值。voidshow_temp_page(floatval){SSD1306_CLS();//显示标题中间居中显示SSD1306_ShowStr(temp_title.left,temp_title.top,"Temperature",16);intx=(val*100)/1000;SSD1306_DrawBMP(number_1.left,number_1.top,16,32,bmp_16X32_number[x]);//显示数字的十位x=((int)(val*100))/100%10;SSD1306_DrawBMP(number_2.left,number_2.top,16,32,bmp_16X32_number[x]);//显示数字的个位SSD1306_DrawBMP(dian.left,dian.top,16,16,bmp_16X16_dian);//显示小数点SSD1306_DrawBMP(danwei.left,danwei.top,16,16,bmp_16X16_sheShiDu);//显示℃符号x=((int)(val*100))/10%10;SSD1306_DrawBMP(number_3.left,number_3.top,8,16,bmp_8X16_number[x]);//数字小数位//适宜温度0~30℃9.3.3程序设计81if(val<0)SSD1306_DrawBMP(image.left,image.top,48,48,bmp_48X48_5_ku_qi);elseif(val>=0&&val<6)SSD1306_DrawBMP(image.left,image.top,48,48,bmp_48X48_5_ku_qi);elseif(val>=6&&val<12)SSD1306_DrawBMP(image.left,image.top,48,48,bmp_48X48_4_nan_guo);elseif(val>=12&&val<18)SSD1306_DrawBMP(image.left,image.top,48,48,bmp_48X48_2_wei_xiao);elseif(val>=18&&val<24)SSD1306_DrawB
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- (2026版)护理带教计划
- 三级安全教育(班组级)考试试卷
- 混凝土模具工岗前规章制度考核试卷含答案
- 拖拉机铸造加工生产线操作调整工冲突解决测试考核试卷含答案
- 球团焙烧工安全演练竞赛考核试卷含答案
- 矿用润滑油车司机保密评优考核试卷含答案
- 铸管制芯工岗前履职考核试卷含答案
- 发电厂发电机检修工岗中评审考核试卷含答案
- 职业指导师沟通技巧能力考核试卷含答案
- 墨制作工操作技能能力考核试卷含答案
- 2026国企招聘考试(文秘)历年参考题库含答案详解
- 2026数学新教材 数学广角:搭配问题 课件 人教版(新教材)三年级数学上册
- 山东名校考试联盟2026-2027学年高三上学期10月阶段性检测 化学原卷
- 房建工程施工测量流程与规范标准
- 2026理赔专业技术职务任职资格考试(理赔员·社保理赔)历年参考题库含答案详解
- 市场营销:理论与中国实践(第4版数字教材版)课件 第11章 营销传播
- 食堂后厨岗位流程标准化SOP
- 第12课 家乡新变化(教学课件)小学二年级上册 统编版《道德与法治》新教材
- 2025年全国HIV抗体诊断试剂临床质量评估报告范文
- 2021-2022学年天津市河东区高二上学期期中质量检测语文试题(解析版)
- 阅读护理文献分享
评论
0/150
提交评论