网加思维做网站推广,求个网站2020急急急,wordpress自适应主体,泉州做网站seo基于树莓派的智能家居控制系统(华为云IOT) 文章目录 一、设计需求前言【1】 项目背景【2】需求总结【3】研究的内容【4】 国内外研究状况【5】本课题要解决的问题【6】开发工具的选择 二、硬件选型【1】 树莓派开发板【2】TFT卡-烧写系统使用【3】0.5米网线-远程登录【4】MQ2烟… 基于树莓派的智能家居控制系统(华为云IOT) 文章目录 一、设计需求前言【1】 项目背景【2】需求总结【3】研究的内容【4】 国内外研究状况【5】本课题要解决的问题【6】开发工具的选择 二、硬件选型【1】 树莓派开发板【2】TFT卡-烧写系统使用【3】0.5米网线-远程登录【4】MQ2烟雾传感器【5】DHT11温湿度传感器【6】洞洞板【7】母对母杜邦线(两排)【8】继电器2个【9】雨滴检测模块【10】火焰检测传感器【11】光敏电阻【12】蜂鸣器模块【13】 LED灯模块 三、部署华为云物联网平台3.1 物联网平台介绍3.2 开通物联网服务3.3 创建产品1创建产品2填写产品信息3产品创建成功4添加自定义模型 3.4 添加设备1注册设备2根据自己的设备填写3保存设备信息(4) 设备创建完成 3.5 MQTT协议主题订阅与发布1MQTT协议介绍2华为云平台MQTT协议使用限制3主题订阅格式4主题发布格式 3.6 MQTT三元组1MQTT服务器地址2生成MQTT三元组 3.7 模拟设备登录测试1填入登录信息2打开网页查看3MQTT登录测试参数总结 四、上位机开发4.1 Qt开发环境安装4.2 创建IAM账户4.3 获取影子数据4.4 修改设备属性4.5 设计上位机【1】新建Qt工程【2】打开现有的Qt工程【3】设计UI界面【4】配置参数读取与保存【5】通信交互代码【8】设置应用图标和应用名称【9】编译工程代码【10】更新时间日期【11】 运行效果【12】源码目录【13】可执行文件【14】软件使用介绍 五、树莓派4B环境搭建【1】硬件环境介绍【2】资料下载【3】准备需要的配件【4】准备烧写系统1安装镜像烧写工具2格式化SD卡3烧写系统 【5】启动系统1树莓派供电2启动树莓派以Type-C供电示例3查看开发板的IP地址4SSH方式登录开发板 【6】windows远程登录桌面1安装xdrp2打开windows远程桌面3连接树莓派远程桌面 【7】扩展树莓派SD卡可用空间1查看内存使用情况2扩展内存 【8】树莓派连接WIFI1配置需要连接的WIFI2通过WIFI的IP地址登录远程桌面 六、硬件开发树莓派点亮LED【1】树莓派4B的引脚【2】安装 WiringPi库【3】点亮LED灯(python)【4】点亮LED灯(C语言)【5】GPIO口常用的控制函数C语言 七、硬件开发智能家居控制系统【1】硬件连线【2】DHT11温湿度读取代码【3】核心代码 一、设计需求
前言
本次设计实现了一个基于树莓派的智能家居系统可以对家庭环境进行实时监测和控制提高居家安全性和舒适度。该系统采用了多种传感器和模块包括温湿度传感器、烟雾传感器、火焰传感器、光敏传感器、雨滴传感器、LED灯光控制模块、继电器控制模块等实现了对家庭环境的多项监测和控制功能。同时通过服务器实现了数据的存储和可视化方便管理员对环境数据进行分析和管理。该系统采用了HTTP和MQTT两种协议进行通信连接华为云IOT云平台支持有线和无线组合通信方式可以满足不同场景下的需求。
使用华为云IOT平台可以提高智能家居系统的可靠性、易用性和可扩展性同时还能够降低系统的成本和实现快速部署。华为云IOT平台采用了分布式架构和多层安全防护机制提供了丰富的开发工具和API支持多种协议和接口能够满足不同规模和需求的物联网应用。在智能家居系统中使用华为云IOT平台可以实现设备接入、数据采集、数据存储和可视化等功能同时还能够方便地与其他系统进行集成提高系统的整体性能和用户体验。
本文将介绍该系统的整体框架和各个模块的功能同时也将介绍系统的设计思路和实现过程。同时本文也将介绍如何搭建华为云物联网服务器以及如何设计、使用手机客户端或电脑端实时查看家庭环境监测数据。希望本文能够为读者提供有关智能家居系统设计的参考和启示同时也能够促进智能家居技术的发展和应用。
【1】 项目背景
智能家居是在物联网的影响之下的物联网化的体现它的概念最早出现于美国利用先进的计算机、嵌入式、网络通信、综合布线技术等技术将与家居生活有关的各种子系统有机的结合在一起。随着大数据云计算可穿戴设备人机交互物联网等技术的不断兴起和发展智能家居开始由概念逐步的进入到现实生活中。智能家居在美国日本新、加坡德国已经得到了广泛的运用并且获得了很快的发展。由于诸多原因中国的智能家居的发展相对缓慢但是随着国家的政策的扶持与规范引导、消费观念的形成、智能城市建设的逐步深入和完善、物联网技术 的发展与兴盛我国的智能家居前景非常广阔。根据《中国智能家居设备[4]行业发展环境与市场需求预测分析报告前瞻》预计国内的智能家居行列将以年均19.8%的速率增长。所以这就对人才的需求更加紧迫。
【2】需求总结
本次设计主要以树莓派为主要的硬件开发平台以Raspbian操作系统为软件开发平台。主板树莓派通过HTTP协议和MQTT协议分别与上位机和下位机通信搭建的服务器用来储存数据和日志记录。搭配有线和无线组合通信方式设计出一套完整的智能家居系统。 通过对智能家居系统的整体需求分析利用温湿度传感器、MQ-2烟雾气敏传感器、火焰传感器、光敏传感器以及雨滴模块传感器采集环境中的数据构成家庭环境监控系统通过传感器采集环境数据并实时上传至手机客户端或者电脑端可以实时查看家庭环境监测数据。最后根据功能需求设计出整个系统的框架。
该设计系统主要包括控制和终端两个部分**。主温湿度检测模块、烟雾检测模块、蜂鸣器报警模块、LED灯光控制模块、继电器控制模块、满足智能家居的日常需求**。同时为了便于用户实现对采集到的数据进行分析和操作系统需要加入数据存储部分。
1树莓派为硬件中心用于控制整个系统的运行。
2温度模块通过通过温湿度传感器和继电器配合实现对家庭空调和加湿器的控制。
3烟雾检测模块利用烟雾检测传感器同时提示用户加以检查确保安全打开窗户、打开喷淋水阀
4继电器控制模模块主要是为了用户根据实时情况完成对家中电器设备的操作。
5蜂鸣器模块用于当出现异常数据时报警使用。
6数据存储模块实现数据的传输将数据传输到服务端便于管理员分析管理。
7服务端实现数据可视化显示各个模块的信息。
8服务器采用华为云物联网服务器
最终实现的功能
整个项目分为3个部分 1. 树莓派硬件端智能家居硬件端 2. 华为云物联网服务器(web网页端) 3. Android手机APP手机端
运行流程
1树莓派硬件端通过WIFI连接到华为云物联网平台上传采集的传感器数据在web网页上可以看到设备上传的数据。
2手机APP通过华为云物联网平台的接口获取设备上传的数据在页面上实时显示出来。
3手机APP点击页面上的控制按钮可以向华为云服务器发送指令服务器再将指令转发给树莓派设备树莓派设备收到数据之后完成对硬件设备的控制。 项目功能演示视频 基于树莓派的智能家居控制系统(华为云IOT) 【3】研究的内容
随着5G时代的发展和工业4.0的持续推进家居行业将迎来智能化的转变。从长远来看中央坚持继续坚持“房住不炒、因城施策”的政策必将导致房地产公司内部竞争加剧所以打造 “量少质精”的项目工程和走精品装修的道路将是未来发展的必然趋势这也将对中国智能家居行业的发展产生积极的影响。
本次课题设计的目的是打造出一个符合现代绿色家庭生活理念的低成本、低功耗和扩展性强的智能家居系统。
本课题的研究具有以下几点意义
1使用Raspbian操作系统平台、树莓派开发板和多种传感器设备之间互联为嵌入式软硬件系统的综合开发提供一种新的思路。
2利用树莓派作为主要开发硬件以及使用低成本检测效果好的传感器模块达到降低智能家居系统使用成本的目的提高智能家居系统的实用性。
3结合Web网页端、移动端APP等多种平台的使用进一步扩大智能家居的适用范围
【4】 国内外研究状况
自1985年以来发达国家注意到智能家居行业充满广阔的商业价值和房地产市场的竞争价值已在智能家居系统的研发赛道上抢占先机。“智慧”制造在当今世界现占据重要地位西班牙街道上的房子大多采用经典的欧式风格当走近房屋内部会发现智能家居设计无处不在。当户外的阳光充足时窗帘会自动打开带有感应器的灯会自动熄灭从而降低能源的损耗。放置在屋顶上的传感器也可以随时收集温湿度数据根据不同温湿度情况控制草坪洒水喷头的开关智能家居为西班牙的艺术氛围增添了浓厚的一笔。
进入十四五的开局期全国各省市多次提出要发展智能家居行业随着人工智能与物联网技术日渐完善中国开始步入崭新的智慧生活时代。目前中国智能家居产业大致包括三部分依次是智能单品、智能装置设备和智能家居系统。智能家居系统主要起到采集、连接和管理等作用而智能单品系统则更多的是给中国传统家居产业赋能。
【5】本课题要解决的问题
传统的智能家居利用有线通信的方法传递信息需要破坏墙壁结构或凿壁布线在墙壁外布线后会有较密集的线头有碍美观而且施工期限也较长建造成本较高。当用户需要更新家居设备时则必须要进行破墙布线而且后期需要检修设备时但由于线路已埋入墙壁无法及时正确地检查出故障这将影响用户的居住体验。
【6】开发工具的选择
上位机的开发选择Qt框架编程语言采用CQt是一个1991年由Qt Company开发的跨平台C图形用户界面应用程序开发框架。它既可以开发GUI程序也可用于开发非GUI程序比如控制台工具和服务器。Qt是面向对象的框架使用特殊的代码生成扩展称为元对象编译器(Meta Object Compiler, moc)以及一些宏Qt很容易扩展并且允许真正地组件编程。Qt能轻松创建具有原生C性能的连接设备、用户界面UI和应用程序。它功能强大且结构紧凑拥有直观的工具和库。 STM32的编程语言选择C语言C语言执行效率高大学里主学的C语言C语言编译出来的可执行文件最接近于机器码汇编语言执行效率最高但是汇编的移植性比较差目前在一些操作系统内核里还有一些低配的单片机使用的较多平常的单片机编程还是以C语言为主。C语言的执行效率仅次于汇编语法理解简单、代码通用性强也支持跨平台在嵌入式底层、单片机编程里用的非常多当前的设计就是采用C语言开发。
开发工具选择Keilkeil是一家世界领先的嵌入式微控制器软件开发商在2015年keil被ARM公司收购。因为当前芯片选择的是STM32F103系列STMF103是属于ARM公司的芯片构架、Cortex-M3内核系列的芯片所以使用Kile来开发STM32是有先天优势的而keil在各大高校使用的也非常多很多教科书里都是以keil来教学开发51单片机、STM32单片机等等。目前作为MCU芯片开发的软件也不只是keil一家独大IAR在MCU微处理器开发领域里也使用的非常多IAR扩展性更强也支持STM32开发也支持其他芯片比如CC2530,51单片机的开发。从软件的使用上来讲IAR比keil更加简洁功能相对少一些。如果之前使用过keil而且使用频率较多已经习惯再使用IAR是有点不适应界面的。 二、硬件选型
【1】 树莓派开发板
链接https://detail.tmall.com/item.htm?abbucket15id624594173139ns1skuId4813073596177spma230r.1.14.16.186c28ee0dyAdW 【2】TFT卡-烧写系统使用
链接https://detail.tmall.com/item.htm?ali_refida3_430582_1006:1108679189:N:PKYQJYFonexjfYBRSvyKQPucrPvrsQRs:caaf3fc7646aae0a40c2887037e30c3aali_trackid1_caaf3fc7646aae0a40c2887037e30c3aid674652537643skuId5059575267140spma230r.1.14.11 【3】0.5米网线-远程登录
链接https://detail.tmall.com/item.htm?abbucket15id17940697346ns1spma230r.1.14.22.cc5c5549nGYTN8skuId3218929026606 【4】MQ2烟雾传感器
MQ2传感器对氨气、硫化物、苯系蒸汽的灵敏度高对烟雾和其它有害的监测也很理想。这种传感器可检测多种有害气体是一款适合多种应用的低成本传感器。
链接https://detail.tmall.com/item.htm?abbucket4id41265308241ns1spma230r.1.14.1.3e211b118SofPwskuId4100651795251 MQ-2型烟雾传感器属于二氧化锡半导体气敏材料属于表面离子式N型半导体。处于200~3000摄氏度时二氧化锡表面吸附空气中的氧形成氧的负离子吸附使半导体中的电子密度减少从面使其电阻值增加。当与烟雾接触时如果晶粒间界处的势垒收到烟雾的调至面变化就会引起表面导电率的变化。利用这一点就可以获得这种烟雾存在的信息烟雾浓度越大导电率越大输出电阻越低则输出的模拟信号就越大。
1引脚说明
VCC电源正极接口可外接3.3~5v供电电源 GND电源负极接口可外接电源负极或地线GND DO数字信号输出接口0和1可外接单片机的GPIO AO模拟信号输出接口可外接单片的ADC采样通道
2硬件连接
模块引脚GPIOVCC3.3V / 5VGNDGNDDONC(空)ADPA1
用杜邦线把模块的VCC和GND分别与单片机的3.3V(或5V)和GND连接 把DO与单片机的其中一个GPIO连接 把AD与单片机的其中一个ADC采样通道连接。
注传感器通电后需要先预热约60s后测量的数据才稳定。通电后传感器会出现正常的轻度发热现象因为内部有电热丝。
3烟雾检测
当可燃气体浓度小于指定的阈值时DO输出高电平大于指定的阈值时则输出低电平。
4阈值调节
模块中蓝色的电位器是用于调节阀值顺时针旋转阈值会越大逆时针越小。
5使用AO接口
与DO不同AO会输出模拟信号因此需要与单片机的ADC采样通道连接。单片机可以通过此模拟信号来获取可燃气体浓度大小。 【5】DHT11温湿度传感器
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术确保产品具有可靠性与卓越的长期稳定性成本低、相对湿度和温度测量、快响应、抗干扰能力强、信号传输距离长、数字信号输出、精确校准。传感器包括一个电容式感湿元件和一个NTC测温元件并与一个高性能8位单片机相连接。可用于暖通空调、除湿器、测试及检测设备、消费品、汽车、自动控制、数据记录器、气象站、家电、湿度调节器、医疗、其他相关湿度检测控制。
特点如下
1、可以检测周围环境的湿度
2、可以检测周围环境的温度
3、湿度测量范围:20%-95%0度-50度范围湿度测量误差:±5%4、温度测量范围:o度-50度温度测量误差:±2度
4、工作电压3.3V-5V
5、输出形式数字输出
https://detail.tmall.com/item.htm?id15598344236ali_refida3_430582_1006:1104520036:N:TAiHo9GD8eTurMzH21/csQ:bead289475b4a86864858785eb160a52ali_trackid1_bead289475b4a86864858785eb160a52spma230r.1.14.1skuId4835521242383 【6】洞洞板
链接https://detail.tmall.com/item.htm?abbucket9id525489414251ns1skuId3937268634921spma230r.1.14.34.16b221829wBwAI 【7】母对母杜邦线(两排)
作用 连接模块与单片机。
链接https://detail.tmall.com/item.htm?ali_refida3_430582_1006:1104520036:N:MsF9mE9KLTC2IibWJh%20K1A:adaa6d3d7abe6f1f07b87a36416ee4fbali_trackid1_adaa6d3d7abe6f1f07b87a36416ee4fbid14466195609skuId3936936817454spma230r.1.14.1 【8】继电器2个
链接https://detail.tmall.com/item.htm?id15909056050ali_refida3_430582_1006:1104520036:N:sGzbt9RI84M4qtD4oBlF3Q:4fce75890f7d69377369572984cac7b9ali_trackid1_4fce75890f7d69377369572984cac7b9spma230r.1.14.1skuId3931798090624 【9】雨滴检测模块
链接https://detail.tmall.com/item.htm?id41266204564ali_refida3_430582_1006:1109983619:N:GwY3Ypk8Xb7Xiq2PhqdDVTVt9Q0NFo%2BR:ecd5f9c9cdd3f853b91e6eebbac0c44fali_trackid1_ecd5f9c9cdd3f853b91e6eebbac0c44fspma230r.1.14.1 接上5V电源电源灯亮,感应板上没有水滴时DO输出为高电平,开关指示灯灭;
滴上一滴水DO输出为低电平,开关指示灯亮刷掉上面的水滴,又恢复到输出高电平状态。
AO模拟输出,可以连接单片机的AD口检测滴在上面的雨量大小。
DO TTL数字输出也可以连接单片机检测是否有雨。
【10】火焰检测传感器
链接https://detail.tmall.com/item.htm?abbucket15id21074472157ns1skuId3944467336586spma230r.1.14.16.24145f13h1YRjj 【11】光敏电阻
链接https://detail.tmall.com/item.htm?ali_refida3_430582_1006:1106005875:N:e27YWfG49A4pLholbz2SLw:5b5426346e88a6fe38173e25e6343841ali_trackid1_5b5426346e88a6fe38173e25e6343841id26828424469skuId4120397318424spma230r.1.14.11 【12】蜂鸣器模块
链接https://detail.tmall.com/item.htm?ali_refida3_430582_1006:1104520036:N:X/YIdD%20/nzZWyWHIKhozj3ahdFvQYGOd:09a834d50903c653d8893f1f618eb321ali_trackid1_09a834d50903c653d8893f1f618eb321id21124132861spma230r.1.14.1skuId4319138558993 【13】 LED灯模块
链接https://detail.tmall.com/item.htm?abbucket12id679438994128ns1skuId5042904238529spma230r.1.14.1.3f8ecdf6y7ha9e 三、部署华为云物联网平台
华为云官网: https://www.huaweicloud.com/
打开官网搜索物联网就能快速找到 设备接入IoTDA。 3.1 物联网平台介绍
华为云物联网平台IoT 设备接入云服务提供海量设备的接入和管理能力将物理设备联接到云支撑设备数据采集上云和云端下发命令给设备进行远程控制配合华为云其他产品帮助我们快速构筑物联网解决方案。
使用物联网平台构建一个完整的物联网解决方案主要包括3部分物联网平台、业务应用和设备。
物联网平台作为连接业务应用和设备的中间层屏蔽了各种复杂的设备接口实现设备的快速接入同时提供强大的开放能力支撑行业用户构建各种物联网解决方案。
设备可以通过固网、2G/3G/4G/5G、NB-IoT、Wifi等多种网络接入物联网平台并使用LWM2M/CoAP、MQTT、HTTPS协议将业务数据上报到平台平台也可以将控制命令下发给设备。
业务应用通过调用物联网平台提供的API实现设备数据采集、命令下发、设备管理等业务场景。 3.2 开通物联网服务
地址 https://www.huaweicloud.com/product/iothub.html 进来默认会提示开通标准版在2023的1月1号年之后没有基础版了。 开通之后点击总览查看接入信息。 我们当前设备准备采用MQTT协议接入华为云平台这里可以看到MQTT协议的地址和端口号等信息。 总结:
端口号 MQTT (1883)| MQTTS (8883)
接入地址 df8fe4bb66.st1.iotda-device.cn-north-4.myhuaweicloud.com根据域名地址得到IP地址信息:
Microsoft Windows [版本 10.0.19044.2604]
(c) Microsoft Corporation。保留所有权利。C:\Users\11266ping df8fe4bb66.st1.iotda-device.cn-north-4.myhuaweicloud.com正在 Ping df8fe4bb66.st1.iotda-device.cn-north-4.myhuaweicloud.com [117.78.5.125] 具有 32 字节的数据:
来自 117.78.5.125 的回复: 字节32 时间40ms TTL30
来自 117.78.5.125 的回复: 字节32 时间40ms TTL30
来自 117.78.5.125 的回复: 字节32 时间39ms TTL30
来自 117.78.5.125 的回复: 字节32 时间39ms TTL30117.78.5.125 的 Ping 统计信息:数据包: 已发送 4已接收 4丢失 0 (0% 丢失)
往返行程的估计时间(以毫秒为单位):最短 39ms最长 40ms平均 39msMQTT协议接入端口号有两个1883是非加密端口8883是证书加密端口单片机无法加载证书所以使用1883端口比较合适。 接下来的ESP8266就采用1883端口连接华为云物联网平台。
3.3 创建产品
1创建产品 2填写产品信息
根据自己产品名字填写下面的设备类型选择自定义类型。 3产品创建成功 4添加自定义模型
产品创建完成之后点击进入产品详情页面翻到最下面可以看到模型定义。 模型简单来说 就是存放设备上传到云平台的数据。比如环境温度、环境湿度、环境光照强度、土壤湿度、扇热风扇、灌溉抽水马达等等我们都可以单独创建一个模型保存。
当前设备需要与云平台交互的属性如下 接下来就按照下面的属性创建 华为云平台的模型。
DHT11_T 环境温度
DHT11_H 环境湿度
MQ2 烟雾浓度检测
water 雨滴检测
flame 火焰检测
light 光强检测
LED1 LED1控制
LED2 LED2控制
LED3 LED3控制先点击自定义模型。 再创建一个服务ID。 接着点击新增属性。 DHT11_T 环境温度 DHT11_H 环境湿度 MQ2 烟雾浓度 water 雨滴检测 flame 火焰检测 light 光强检测 LED灯控制
3盏LED灯。 全部添加完毕之后。 3.4 添加设备
产品是属于上层的抽象模型接下来在产品模型下添加实际的设备。添加的设备最终需要与真实的设备关联在一起完成数据交互。
1注册设备 2根据自己的设备填写 3保存设备信息
创建完毕之后点击保存并关闭得到创建的设备密匙信息。该信息在后续生成MQTT三元组的时候需要使用。 当前设备的信息如下
{device_id: 64000697352830580e48df07_dev1,secret: 12345678
}(4) 设备创建完成 3.5 MQTT协议主题订阅与发布
1MQTT协议介绍
当前的设备是采用MQTT协议与华为云平台进行通信。
MQTT是一个物联网传输协议它被设计用于轻量级的发布/订阅式消息传输旨在为低带宽和不稳定的网络环境中的物联网设备提供可靠的网络服务。MQTT是专门针对物联网开发的轻量级传输协议。MQTT协议针对低带宽网络低计算能力的设备做了特殊的优化使得其能适应各种物联网应用场景。目前MQTT拥有各种平台和设备上的客户端已经形成了初步的生态系统。
MQTT是一种消息队列协议使用发布/订阅消息模式提供一对多的消息发布解除应用程序耦合相对于其他协议开发更简单MQTT协议是工作在TCP/IP协议上由TCP/IP协议提供稳定的网络连接所以只要具备TCP协议栈的网络设备都可以使用MQTT协议。 本次设备采用的ESP8266就具备TCP协议栈能够建立TCP连接所以配合STM32代码里封装的MQTT协议就可以与华为云平台完成通信。
华为云的MQTT协议接入帮助文档在这里: https://support.huaweicloud.com/devg-iothub/iot_02_2200.html 业务流程 2华为云平台MQTT协议使用限制
描述限制支持的MQTT协议版本3.1.1与标准MQTT协议的区别支持Qos 0和Qos 1支持Topic自定义不支持QoS2不支持will、retain msgMQTTS支持的安全等级采用TCP通道基础 TLS协议最高TLSv1.3版本单帐号每秒最大MQTT连接请求数无限制单个设备每分钟支持的最大MQTT连接数1单个MQTT连接每秒的吞吐量即带宽包含直连设备和网关3KB/sMQTT单个发布消息最大长度超过此大小的发布请求将被直接拒绝1MBMQTT连接心跳时间建议值心跳时间限定为30至1200秒推荐设置为120秒产品是否支持自定义Topic支持消息发布与订阅设备只能对自己的Topic进行消息发布与订阅每个订阅请求的最大订阅数无限制
3主题订阅格式
帮助文档地址https://support.huaweicloud.com/devg-iothub/iot_02_2200.html 对于设备而言一般会订阅平台下发消息给设备 这个主题。
设备想接收平台下发的消息就需要订阅平台下发消息给设备 的主题订阅后平台下发消息给设备设备就会收到消息。
如果设备想要知道平台下发的消息需要订阅上面图片里标注的主题。
以当前设备为例最终订阅主题的格式如下:
$oc/devices/{device_id}/sys/messages/down最终的格式:
$oc/devices/64000697352830580e48df07_dev1/sys/messages/down4主题发布格式
对于设备来说主题发布表示向云平台上传数据将最新的传感器数据设备状态上传到云平台。
这个操作称为属性上报。
帮助文档地址https://support.huaweicloud.com/usermanual-iothub/iot_06_v5_3010.html 根据帮助文档的介绍 当前设备发布主题上报属性的格式总结如下
发布的主题格式:
$oc/devices/{device_id}/sys/properties/report最终的格式:
$oc/devices/64000697352830580e48df07_dev1/sys/properties/report
发布主题时需要上传数据这个数据格式是JSON格式。上传的JSON数据格式如下:{services: [{service_id: 填服务ID,properties: {填属性名称1: 填属性值,填属性名称2: 填属性值,..........}}]
}
根据JSON格式一次可以上传多个属性字段。 这个JSON格式里的服务ID属性字段名称属性值类型在前面创建产品的时候就已经介绍了不记得可以翻到前面去查看。根据这个格式组合一次上传的属性数据:
{services: [{service_id: stm32,properties:{DHT11_T:18,DHT11_H:80,MQ2:1,water:1,flame:1,light:0,LED1:0,LED2:0,LED3:0}}]}3.6 MQTT三元组
MQTT协议登录需要填用户ID设备ID设备密码等信息就像我们平时登录QQ微信一样要输入账号密码才能登录。MQTT协议登录的这3个参数一般称为MQTT三元组。
接下来介绍华为云平台的MQTT三元组参数如何得到。
1MQTT服务器地址
要登录MQTT服务器首先记得先知道服务器的地址是多少端口是多少。
帮助文档地址https://console.huaweicloud.com/iotdm/?regioncn-north-4#/dm-portal/home MQTT协议的端口支持1883和8883它们的区别是8883 是加密端口更加安全。但是单片机上使用比较困难所以当前的设备是采用1883端口进连接的。
根据上面的域名和端口号得到下面的IP地址和端口号信息 如果设备支持填写域名可以直接填域名不支持就直接填写IP地址。 IP地址就是域名解析得到的
华为云的MQTT服务器地址117.78.5.125
华为云的MQTT端口号18832生成MQTT三元组
华为云提供了一个在线工具用来生成MQTT鉴权三元组 https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
打开这个工具填入设备的信息也就是刚才创建完设备之后保存的信息点击生成就可以得到MQTT的登录信息了。
下面是打开的页面 填入设备的信息 上面两行就是设备创建完成之后保存得到的
直接得到三元组信息。 得到三元组之后设备端通过MQTT协议登录鉴权的时候填入参数即可。
DeviceId 64000697352830580e48df07_dev1
DeviceSecret 12345678
ClientId 64000697352830580e48df07_dev1_0_0_2023030206
Username 64000697352830580e48df07_dev1
Password a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf4493.7 模拟设备登录测试
经过上面的步骤介绍已经创建了产品设备数据模型得到MQTT登录信息。 接下来就用MQTT客户端软件模拟真实的设备来登录平台。测试与服务器通信是否正常。
1填入登录信息
打开MQTT客户端软件对号填入相关信息就是上面的文本介绍。然后点击登录订阅主题发布主题。 2打开网页查看
完成上面的操作之后打开华为云网页后台可以看到设备已经在线了。 点击详情页面可以看到上传的数据 如果想查看历史数据点击这里 到此云平台的部署已经完成设备已经可以正常上传数据了。
3MQTT登录测试参数总结
IP地址117.78.5.125
端口号1883
DeviceId 64000697352830580e48df07_dev1
DeviceSecret 12345678
ClientId 64000697352830580e48df07_dev1_0_0_2023030206
Username 64000697352830580e48df07_dev1
Password a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449
订阅主题$oc/devices/64000697352830580e48df07_dev1/sys/messages/down
发布主题$oc/devices/64000697352830580e48df07_dev1/sys/properties/report
发布的消息{services: [{service_id: stm32,properties:{DHT11_T:18,DHT11_H:80,MQ2:1,water:1,flame:1,light:0,LED1:0,LED2:0,LED3:0}}]}四、上位机开发
为了方便查看设备上传的数据对设备进行远程控制接下来利用Qt开发一款Android和windows系统的上位机。
使用华为云平台提供的API接口获取设备上传的数据也可以给设备下发指令控制设备。
为了方便查看设备上传的数据对设备进行远程控制接下来利用Qt开发一款Android和windows系统的上位机。
使用华为云平台提供的API接口获取设备上传的数据也可以给设备下发指令控制设备。
4.1 Qt开发环境安装
Qt的中文官网 https://www.qt.io/zh-cn/ QT5.12.6的下载地址https://download.qt.io/archive/qt/5.12/5.12.6
打开下载链接后选择下面的版本进行下载
qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details
软件安装时断网安装否则会提示输入账户。
安装的时候第一个复选框里勾选一个mingw 32编译器即可其他的不管默认就行直接点击下一步继续安装。 说明 我这里只是介绍PC端的环境搭建这个比较简单。 Android的开发环境比较麻烦可以去我的博客里看详细文章。
选择MinGW 32-bit 编译器 4.2 创建IAM账户
创建一个IAM账户因为接下来开发上位机需要使用云平台的API接口这些接口都需要token进行鉴权。简单来说就是身份的认证。 调用接口获取Token时就需要填写IAM账号信息。所以接下来演示一下过程。
地址: https://console.huaweicloud.com/iam/?regioncn-north-4#/iam/users
获取Token时除了AIM账号外还需要项目凭证:
22ef548bdacc41a9ade0b3c83bcc3b21鼠标放在左上角头像上在下拉菜单里选择统一身份认证。 点击左上角创建用户。 创建成功 4.3 获取影子数据
帮助文档https://support.huaweicloud.com/api-iothub/iot_06_v5_0079.html
设备影子介绍
设备影子是一个用于存储和检索设备当前状态信息的JSON文档。
每个设备有且只有一个设备影子由设备ID唯一标识
设备影子仅保存最近一次设备的上报数据和预期数据
无论该设备是否在线都可以通过该影子获取和设置设备的属性简单来说设备影子就是保存设备最新上传的一次数据。
我们设计的软件里如果想要获取设备的最新状态信息就采用设备影子接口。
如果对接口不熟悉可以先进行在线调试https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?productIoTDAapiShowDeviceShadow
在线调试接口可以请求影子接口了解请求与返回的数据格式。 设备影子接口返回的数据如下
{device_id: 64000697352830580e48df07_dev1,shadow: [{service_id: stm32,desired: {properties: null,event_time: null},reported: {properties: {DHT11_T: 18,DHT11_H: 85,MQ2: 1,water: 1,flame: 1,light: 0,LED1: 0,LED2: 0,LED3: 0},event_time: 20230302T063135Z},version: 4}]
}4.4 修改设备属性
地址: https://support.huaweicloud.com/api-iothub/iot_06_v5_0034.html
接口说明
设备的产品模型中定义了物联网平台可向设备下发的属性应用服务器可调用此接口向指定设备下发属性。平台负责将属性以同步方式发送给设备并将设备执行属性结果同步返回。修改设备属性的接口可以让服务器给设备下发指令如果需要控制设备。
在线调试地址
https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?productIoTDAapiUpdateProperties
修改设备属性是属于同步命令需要设备在线才可以进行调试先使用MQTT客户端登录服务器模拟设备上线。
然后进行调试测试数据远程下发给设备。
【1】利用MQTT客户端先登录设备 (这是同步命令必须在线才能调试) 【2】点击调试 {services:{LED:1}}【4】可以看到MQTT客户端软件上已经收到了服务器下发的消息 由于是同步命令服务器必须要收到设备的响应才能顺利完成一个流程设备响应了服务器才能确定数据下发成功。
MQTT设备端如何响应呢
设备响应格式说明https://support.huaweicloud.com/api-iothub/iot_06_v5_3008.html 下面进行实操
当服务器通过在线调试发送指令下来之后客户端将请求ID复制下来添加到发布主题的格式里再回复回去服务器收到了响应一次属性修改就完美完成了。 就是成功的状态 **下面是请求的总结 ** (响应服务器的修改设备属性请求)
上报主题的格式$oc/devices/{device_id}/sys/properties/set/response/request_id$oc/devices/64000697352830580e48df07_dev1/sys/properties/set/response/request_id响应的数据:
{result_code: 0,result_desc: success}4.5 设计上位机
前面2讲解了需要用的API接口接下来就使用Qt设计上位机设计界面完成整体上位机的逻辑设计。
【1】新建Qt工程 选择工程路径放在英文路径下。 创建完毕。 新建Android的模板 【2】打开现有的Qt工程
如果想打开已经设计好的工程可以在保存上位机源码的目录下找到工程文件xxx.pro双击打开工程详细操作看下面截图红框。 【3】设计UI界面
打开UI设计师界面 这是默认的界面 下面是设计好的界面 【4】配置参数读取与保存
/*
功能: 保存数据到文件
*/
void Widget::SaveDataToFile(QString text)
{/*保存数据到文件,方便下次加载*/QString file;fileQCoreApplication::applicationDirPath()/ConfigFile;QFile filesrc(file);filesrc.open(QIODevice::WriteOnly);QDataStream out(filesrc);out text; //序列化写字符串filesrc.flush();filesrc.close();
}/*
功能: 从文件读取数据
*/
QString Widget::ReadDataFile(void)
{//读取配置文件QString text,data;textQCoreApplication::applicationDirPath()/ConfigFile;//判断文件是否存在if(QFile::exists(text)){QFile filenew(text);filenew.open(QIODevice::ReadOnly);QDataStream in(filenew); // 从文件读取序列化数据in data; //提取写入的数据filenew.close();}return data; //返回值读取的值
}
【5】通信交互代码
//解析反馈结果
void Widget::replyFinished(QNetworkReply *reply)
{QString displayInfo;int statusCode reply-attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();//读取所有数据QByteArray replyData reply-readAll();qDebug()状态码:statusCode;qDebug()反馈的数据:QString(replyData);//更新tokenif(function_select3){displayInfotoken 更新失败.;//读取HTTP响应头的数据QListQNetworkReply::RawHeaderPair RawHeaderreply-rawHeaderPairs();qDebug()HTTP响应头数量:RawHeader.size();for(int i0;iRawHeader.size();i){QString firstRawHeader.at(i).first;QString secondRawHeader.at(i).second;if(firstX-Subject-Token){Tokensecond.toUtf8();displayInfotoken 更新成功.;//保存到文件SaveDataToFile(Token);break;}}QMessageBox::information(this,提示,displayInfo,QMessageBox::Ok,QMessageBox::Ok);return;}//判断状态码if(200 ! statusCode){//解析数据QJsonParseError json_error;QJsonDocument document QJsonDocument::fromJson(replyData, json_error);if(json_error.error QJsonParseError::NoError){//判断是否是对象,然后开始解析数据if(document.isObject()){QString error_str;QJsonObject obj document.object();QString error_code;//解析错误代码if(obj.contains(error_code)){error_codeobj.take(error_code).toString();error_str错误代码:;error_strerror_code;error_str\n;}if(obj.contains(error_msg)){error_str错误消息:;error_strobj.take(error_msg).toString();error_str\n;}//显示错误代码QMessageBox::information(this,提示,error_str,QMessageBox::Ok,QMessageBox::Ok);}}return;}//设置属性if(function_select12 || function_select13){//解析数据QJsonParseError json_error;QJsonDocument document QJsonDocument::fromJson(replyData, json_error);if(json_error.error QJsonParseError::NoError){//判断是否是对象,然后开始解析数据if(document.isObject()){QJsonObject obj document.object();if(obj.contains(response)){QJsonObject obj1obj.take(response).toObject();int val0;QString success;if(obj1.contains(result_code)){valobj1.take(result_code).toInt();}if(obj1.contains(result_desc)){successobj1.take(result_desc).toString();}if(val0 success success){//显示状态QMessageBox::information(this,提示,远程命令操作完成.,QMessageBox::Ok,QMessageBox::Ok);return;}else{//显示状态QMessageBox::information(this,提示,设备未正确回应.请检查设备网络.,QMessageBox::Ok,QMessageBox::Ok);return;}}}}}//查询设备属性if(function_select0){//解析数据QJsonParseError json_error;QJsonDocument document QJsonDocument::fromJson(replyData, json_error);if(json_error.error QJsonParseError::NoError){//判断是否是对象,然后开始解析数据if(document.isObject()){QJsonObject obj document.object();if(obj.contains(shadow)){QJsonArray arrayobj.take(shadow).toArray();for(int i0;iarray.size();i){QJsonObject obj2array.at(i).toObject();if(obj2.contains(reported)){QJsonObject obj3obj2.take(reported).toObject();if(obj3.contains(properties)){QJsonObject propertiesobj3.take(properties).toObject();qDebug()开始解析数据....;int DHT11_T;// 环境温度int DHT11_H;// 环境湿度int MQ2;// 烟雾浓度检测int water;// 雨滴检测int flame;// 火焰检测int light;// 光强检测int LED1;// LED1控制int LED2;// LED2控制int LED3;// LED3控制DHT11_Tproperties.take(DHT11_T).toInt();DHT11_Hproperties.take(DHT11_H).toInt();MQ2properties.take(MQ2).toInt();waterproperties.take(water).toInt();flameproperties.take(flame).toInt();lightproperties.take(light).toInt();LED1properties.take(LED1).toInt();LED2properties.take(LED2).toInt();LED3properties.take(LED3).toInt();//环境温度ui-DHT11_T-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);ui-DHT11_T-setText(QString(%1℃).arg(DHT11_T));//环境湿度ui-DHT11_H-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);ui-DHT11_H-setText(QString(%1%).arg(DHT11_H));//烟雾报警if(MQ20){ui-MQ2-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//样式表QString qssQString(QLabel{border-radius:0px;color:#FFFFFF;font: 18pt \Arial\;});ui-MQ2-setStyleSheet(qss);ui-MQ2-setText(QString(正常));}//正常else{ui-MQ2-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//样式表QString qssQString(QLabel{border-radius:0px;color:#FF0000;font: 18pt \Arial\;});ui-MQ2-setStyleSheet(qss);ui-MQ2-setText(QString(烟雾警告));}//火焰检测报警if(flame0){ui-flame-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//样式表QString qssQString(QLabel{border-radius:0px;color:#FFFFFF;font: 18pt \Arial\;});ui-flame-setStyleSheet(qss);ui-flame-setText(QString(正常));}//正常else{ui-flame-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);//样式表QString qssQString(QLabel{border-radius:0px;color:#FF0000;font: 18pt \Arial\;});ui-flame-setStyleSheet(qss);ui-flame-setText(QString(火警警告));}//雨滴检测报警if(water0){ui-water-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);ui-water-setText(QString(天晴));}//正常else{ui-water-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);ui-water-setText(QString(下雨));}//光强检测报警if(light0){ui-light-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);ui-light-setText(QString(强));}//正常else{ui-light-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);ui-light-setText(QString(弱));}//设置灯光开关的状态ui-LED1-setChecked(LED1);ui-LED2-setChecked(LED2);ui-LED3-setChecked(LED3);}}}}}}return;}
}【8】设置应用图标和应用名称 【9】编译工程代码
编译windows版本 编译Android版本 点击绿色小三角形之后会弹出选择手机设备列表。需要提前将Android手机通过USB连接电脑的USB口并且打开Android手机的USB调试选项接下来选择设备就可以编译安装到Android手机上。
【10】更新时间日期
//label_time
QDateTime current_date_time QDateTime::currentDateTime();QString current_date current_date_time.toString(yyyy/MM/dd hh:mm:ss);
ui-label_time-setAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
ui-label_time-setText(current_date);【11】 运行效果
下面是windows电脑的运行效果 下面是Android手机的运行效果 【12】源码目录
安装好Qt环境之后双击打开即可。 注意 Qt工程需要放在英文路径下打开。
【13】可执行文件
如果不想编译源码在资料目录下打开windows上位机可执行文件双击下面截图红框的程序即可。 也可以直接安装Android的安装包在Android手机上操作。
【14】软件使用介绍
第一次打开软件需要点击更新Token按钮如果在Android手机上每次启动都需要点击一次暂时没有保存配置文件。 五、树莓派4B环境搭建
【1】硬件环境介绍
当前购买的树莓派开发板是4B型号2GB内存就买了一个主板不带其他任何配件。 树莓派是什么Raspberry Pi(中文名为“树莓派”,简写为RPi或者RasPi/RPi)是为学生计算机编程教育而设计只有信用卡大小的卡片式电脑其系统基于Linux。 【2】资料下载
第一步先将树莓派4B需要使用的资料下载下来。
链接https://pan.baidu.com/s/1vYamLV9CPDbUF2wQMcbtPA?pwd9ubq 提取码9ubq –来自百度网盘超级会员V8的分享 【3】准备需要的配件
1准备一张至少32G的TFT卡用来烧写系统。
2准备一个读卡器方便插入TFT卡好方便插入到电脑上拷贝系统
3树莓派主板一个
4一根网线方便插路由器上与树莓派连接
5一根type-C的电源线。用自己Android手机的数据线就行拿手机充电器供电。 【4】准备烧写系统
1安装镜像烧写工具 2格式化SD卡
将TFT卡通过读卡器插入到电脑上将TFT卡格式化。 3烧写系统
**接下来准备烧写的系统是这一个系统**将系统解压出来。 然后打开刚才安装好的镜像烧写工具在软件中选择需要安装的 img镜像文件“Device”下选择SD的盘符然后选择“Write”然后就开始安装系统了根据你的SD速度安装过程有快有慢。
注意从网盘下载下来的镜像如果没有解压就先解压释放出img文件。 下面是烧写的流程 点击YES开始烧写。 烧写过程中 安装结束后会弹出完成对话框说明安装就完成了如果不成功需要关闭防火墙一类的软件重新插入SD进行安装。 需要注意的是安装完windows系统下看到SD只有74MB了这是正常现象因为linux下的磁盘分区win下是看不到的。 烧录成功后windows系统可能会因为无法识别分区而提示格式化分区此时**千万不要格式化不要格式化不要格式化**点击取消然后弹出内存卡插入到树莓派上。 至此树莓派烧写成功。
【5】启动系统
1树莓派供电
由于我买的树莓派开发板不带电源线就采用Android手机的充电线供电。 使用Type-C供电时要求电源头的参数要求电压是5V电流是3A。
我的充电器是小米的120W有线快充刚好满足要求。 2启动树莓派以Type-C供电示例
烧写完后把MicroSD卡直接插入树莓派的MicroSD卡插槽如果有显示器就连接显示器有DHMI线机也可以连接外接的显示器有鼠标、键盘都可以插上去就可以进入树莓派系统了。
但是我这块板子就一个主板什么都没有。就拿网线将树莓派的网口与路由器连接。 上电之后开发板的指示灯会闪烁说明已经启动。
3查看开发板的IP地址
现在板子没屏幕想要连接板子只能通过SSH远程登录的方式当前烧写的这个系统默认开机就启动了SSH所以只要知道开发板的IP地址就可以远程登录进去。
**如何知道树莓派板子的IP地址**方法很多最简单是直接登录路由器的后台界面查看连接进入的设备。
我使用的小米路由器登录后台看到了树莓派的IP地址。 4SSH方式登录开发板
当前烧写系统的登录账号和密码如下
账号pi 密码yahboom打开SSH远程登录工具PuTTY_0.67.0.0.exe。 输入IP地址和端口号点击open。 然后输入账号和密码。 输入用户名 pi按下回车然后再输入密码 yahboom。 注意Linux下为了保护隐私输入密码是不可见的你只需要正常输入按下回车键确定 即可。
正常情况下就登录成功了。 接下来看看联网情况。 ping一下百度测试互联网是否畅通因为接下来要在线安装软件包。
ping www.baidu.com可以看到网络没有问题。
提示 按下 Ctrl C 可以终止命令行。 这算是Linux基础。
【6】windows远程登录桌面
为了方便图形化方式开发可以使用windows系统通过远程桌面登录树莓派就可以看到界面了不过需要先安装工具。
1安装xdrp
在树莓派的命令行终端输入命令
sudo apt-get install xrdp按下回车之后会弹出确认窗口。输入 y之后按下回车继续安装。 安装完毕 2打开windows远程桌面
在windows电脑上打开运行命令的窗口输入mstsc来打开远程桌面。 打开远程桌面的窗口 3连接树莓派远程桌面
打开远程桌面后输入树莓派开发板的IP地址点击连接。 如果弹出窗口就选择是。 接下来就进入到树莓派开发板的远程桌面的登录窗口了。 接下来输入面账号和密码。
账号pi 密码yahboom输入后点击OK按钮登录。 正常情况下就顺利的进入树莓派的桌面了。接下来就可以进行远程桌面开发了。 【7】扩展树莓派SD卡可用空间
树莓派系统默认启动时树莓派默认没有把整个存储空间拓展到整张卡中如果需要使用整个SD卡这时候可以通过人为的把存储空间拓展到整张卡上。
1查看内存使用情况
打开命令行终端输入df -h 命令。 2扩展内存
1 打开树莓派命令行终端输入
piraspberrypi:~ $ sudo raspi-config2 在弹出的命令行里选择Advanced Options 3 选择第一个选项。 4 点击确定 5 点击右边的Finish按钮保存退出。
确定之后关闭界面系统会自动重启重启之后使用df命令查看是否扩展成功(我这里插的是32G的SD卡)。
可以看到我的系统已经扩展成功了目前可以内存空间是19G。 【8】树莓派连接WIFI
1配置需要连接的WIFI
点击右上角的数据连接图标打开WIFI列表点击想要的WIFI进行连接。 输入密码 连接成功后的效果 2通过WIFI的IP地址登录远程桌面
在路由器的后台可以看到目前树莓派连入了两个IP地址。接下来把网线拔掉使用WIFI无线也可以直接连接无线桌面这样就不用插网线了。 账号和密码
账号pi 密码yahboom六、硬件开发树莓派点亮LED
【1】树莓派4B的引脚 GPIO是标准引脚可以用来打开和关闭设备。例如一个LED、一个蜂鸣器。
I2C(Inter-Integrated Circuit)引脚连接并与支持该协议(I2C协议)的硬件模块对话。
SPI串行外设接口总线引脚可用于连接和对话SPI设备
UART 通用异步接收/发送器)是用于与其他设备通信的串行引脚。
GND是用来接地的引脚。
【2】安装 WiringPi库
这里使用了 WiringPi 库如果已经安装过可以跳过这一步。由于我当前使用的系统镜像已经默认安装了所以就不再安装。
安装方式如下
sudo apt-get update
#如果之前没有安装过 git执行下面的命令安装一下
sudo apt-get install git-core
#下载 wiringPi
git clone https://github.com/WiringPi/WiringPi
#编译 wiringPi
cd WiringPi
sudo ./build【3】点亮LED灯(python)
将LED灯接在GPIO18口上。 打开编辑器编写代码 打开编辑器后写好代码点击运行 就可以看到LED灯在闪烁了。 示例代码
#!/usr/bin/python
#-*-coding: utf-8 -*-
import RPi.GPIO as GPIO # 引入GPIO模块
from time import sleep # 引入time模块
GPIO.setmode(GPIO.BCM) # 使用BCM编号方式
GPIO.setup(18,GPIO.OUT) # 将GPIO18设置为输出模式
while True: # 无限循环GPIO.output(18,GPIO.HIGH) # 将GPIO18设置为高电平点亮LEDsleep(1) # 等待1秒钟GPIO.output(18,GPIO.LOW) # 将GPIO18设置为低电平熄灭LEDsleep(1) # 等待0.5秒钟
input() # 按下任意键退出
GPIO.cleanup() # 清理释放GPIO资源将GPIO复位【4】点亮LED灯(C语言)
使用C语言代码对树莓派的GPIO口操作时需要先初始化。下面是2种初始化函数对应不同的GPIO编码方式。
int wiringPiSetup (void) 返回:执行状态-1表示失败 当使用这个函数初始化树莓派引脚时程序使用的是wiringPi 引脚编号表。引脚的编号为 0~16int wiringPiSetupGpio (void) 返回执行状态-1表示失败 当使用这个函数初始化树莓派引脚时程序中使用的是BCM GPIO 引脚编号表。打开编辑器编写C语言代码 下面是C语言代码电路LED灯的代码
#include stdio.h
#include wiringPi.h
#include stdlib.h
#include string.h
/*树莓派控制继电器高低电平亮灯*/#define LED1 23int main()
{wiringPiSetupGpio(); pinMode(LED1,OUTPUT);while(1){digitalWrite(LED1,HIGH);sleep(1);digitalWrite(LED1,LOW);sleep(1);}return 0;
}写好代码后进行编译
piraspberrypi:~/word $ gcc led.c -lwiringPi运行代码
piraspberrypi:~/word $ ./a.out【5】GPIO口常用的控制函数C语言
1.void pinMode (int pin, int mode) ;
这个函数式设置pin脚的输入和输出模式以及PWM的输入和输出模式。在wiringPi中只有 pin 1 (BCM_GPIO 18)是支持PWM的输出的。2.void digitalWrite (int pin, int value) ;
这个函数式用来设置pin脚的高低电平的当我们写HIGH or LOW (1 or 0)的时候pin脚的mode必须为输出模式。3.void digitalWriteByte (int value) ;
这个函数可以将8位字节写给8个GPIO pin脚这是设置8个pin脚值的最快的方式。4.void pwmWrite (int pin, int value) ;
写入的值必须是0-1024。输出一个值到PWM寄存器控制PWM输出。pin只能是wiringPi 引脚编号下的1脚BCM下的18脚5.int digitalRead (int pin) ;
这个函数是读取GPIO的pin脚的电平高低然后返回读取的值。6.void pullUpDnControl (int pin, int pud) ;
这个函数是设置GPIO的pin脚是否接上拉电阻和下拉电阻的。函数的参数pud必须设置当设置为PUD_OFF时表示没有上拉电阻和下拉电阻当设置为PUD_DOWN 时为下拉电阻设置为PUD_UP是为上拉电阻。7. void analogWrite(int pin, int value)
pin:引脚
value输出的模拟量
模拟量输出 树莓派的引脚本身是不支持AD转换的也就是不能使用模拟量的API需要增加另外的模块8. int analogRead (int pin)
pin引脚
返回引脚上读取的模拟量
模拟量输入 树莓派的引脚本身是不支持AD转换的也就是不能使用模拟量的API需要增加另外的模块PWM的控制
1.pwmSetMode (int mode) ;
这个函数是设置PWM的占空比模式一般为50%占空比和占空比可调模式。树莓派默认是50%占空比模式我们可以通过PWM_MODE_BAL 和PWM_MODE_MS这两个参数来设置。2.pwmSetRange (unsigned int range) ;
这个函数是设置PWM寄存器写入的范围一般默认为1024.3.pwmSetClock (int divisor) ;
这个函数的设置PWM时钟的分频因子。时间控制函数
1.void delay (unsigned int howLong)
这个是毫秒级的延时函数。2.void delayMicroseconds (unsigned int howLong)
微秒级的延时函数3. unsigned int millis (void)
这个函数返回 一个 从你的程序执行 wiringPiSetup 初始化函数或者wiringPiSetupGpio 到 当前时间 经过的 毫秒数。
返回类型是unsigned int最大可记录 大约49天的毫秒时长。4. unsigned int micros (void)
这个函数返回 一个 从你的程序执行 wiringPiSetup 初始化函数或者wiringPiSetupGpio 到 当前时间 经过的 微秒数。
返回类型是unsigned int最大可记录 大约71分钟的时长。关于中断的函数
1.int waitForInterrupt (int pin, int timeOut) ;
这一个等待事件中断函数timeout参数是毫秒级别的参数当为-1时代表永远等待中断状态。如果发生错误返回值是-1,0表示超时1表示成功中断。调用这个函数之前我们需要对GPIO进行初始化。例如我们要设置GPIO 0为等待下降沿中断我们需要在运行程序之前先终端运行 gpio edge 0 falling2.int wiringPiISR (int pin, int edgeType, void (*function)(void)) ;
这个函数是利用一个函数作为参数来获取在特定的GPIO pin脚的中断。edge_Type参数可以设定为 INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH or INT_EDGE_SETUP.当中断发生的时候function将被调用调用function之前会先清除相应的标志位这就使得随后的中断不会被影响。七、硬件开发智能家居控制系统
【1】硬件连线
下面是传感器与树莓派之间的连线。
MQ2烟雾传感器GPIO4
DHT11温湿度传感器GPIO17
火焰检测传感器GPIO18
光敏电阻GPIO27
蜂鸣器GPIO22
LED灯1GPIO23
LED灯2GPIO24
LED灯3GPIO25
雨滴检测传感器GPIO5
继电器模块GPIO6【2】DHT11温湿度读取代码
下面采用C语言方式读取DHT11温湿度传感器的数
#include wiringPi.h
#include stdio.h
#include stdlib.htypedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;#define HIGH_TIME 32int pinNumber 17;
uint32 databuf;uint8 readSensorData(void)
{uint8 crc; uint8 i;pinMode(pinNumber, OUTPUT); // set mode to outputdigitalWrite(pinNumber, 0); // output a high level delay(25);digitalWrite(pinNumber, 1); // output a low level pinMode(pinNumber, INPUT); // set mode to inputpullUpDnControl(pinNumber, PUD_UP);delayMicroseconds(27);if (digitalRead(pinNumber) 0) //SENSOR ANS{while (!digitalRead(pinNumber)); //wait to highfor (i 0; i 32; i){while (digitalRead(pinNumber)); //data clock startwhile (!digitalRead(pinNumber)); //data startdelayMicroseconds(HIGH_TIME);databuf * 2;if (digitalRead(pinNumber) 1) //1{databuf;}}for (i 0; i 8; i){while (digitalRead(pinNumber)); //data clock startwhile (!digitalRead(pinNumber)); //data startdelayMicroseconds(HIGH_TIME);crc * 2; if (digitalRead(pinNumber) 1) //1{crc;}}return 1;}else{return 0;}
}int main(void)
{printf(PIN:%d\n, pinNumber);if (-1 wiringPiSetupGpio()) {printf(Setup wiringPi failed!);return 1;}pinMode(pinNumber, OUTPUT); // set mode to outputdigitalWrite(pinNumber, 1); // output a high level printf(Starting...\n);while (1) {pinMode(pinNumber, OUTPUT); // set mode to outputdigitalWrite(pinNumber, 1); // output a high level delay(3000);if (readSensorData()){printf(Sensor data read ok!\n);printf(RH:%d.%d\n, (databuf 24) 0xff, (databuf 16) 0xff); printf(TMP:%d.%d\n, (databuf 8) 0xff, databuf 0xff);databuf 0;}else{printf(Sensor dosent ans!\n);databuf 0;}}return 0;
}编译代码
gcc -Wall -o dht11 dht11.c -lwiringPi -o app运行代码
piraspberrypi:~/word $ ./dht11
PIN:17
Starting...
Sensor dosent ans!
Sensor data read ok!
RH:57.8
TMP:18.7【3】核心代码
通过MQTT协议连接华为云物联网平台完成数据的上传和远程命令接收控制模块完成。
#include stdio.h
#include sys/types.h /* See NOTES */
#include sys/socket.h
#include netinet/in.h
#include netinet/ip.h /* superset of previous */
#include arpa/inet.h
#include poll.h
#include unistd.h
#include stdlib.h
#include pthread.h
#include signal.h
#include mqtt.h
#include main.h
#include netdb.h
#include stdio.h
#include wiringPi.h
#include stdlib.h
#include string.h#define DeviceName Smart_home//设备名
#define ProductID LA57WTHWL6//产品ID
#define DeviceSceret 9JHiCQQcP9nuZlVDuQ2ZnQ//设备秘钥//服务器IP
#define SERVER_IP LA57WTHWL6.iotcloud.tencentdevices.com
#define SERVER_PORT 1883 //端口号//MQTT三元组
#define ClientID 64000697352830580e48df07_dev1_0_0_2023030206
#define Username 64000697352830580e48df07_dev1
#define Password a695af9883c5d0e3817bc6971beeecadf8c7c595677c461b1fe75882ed2bf449//密文 //订阅主题:
#define SET_TOPIC $oc/devices/64000697352830580e48df07_dev1/sys/messages/down//订阅
//发布主题:
#define POST_TOPIC $oc/devices/64000697352830580e48df07_dev1/sys/properties/report//发布char mqtt_message[1024*1024];//上报数据缓存区
char request_id[100];
char mqtt_cmd_message[100];
char mqtt_cmd_data[100];int sockfd;
/*获取平台下发数据*/
void *pth_work_func(void *arg)
{char buff[1024];int size0;int i0;while(1){sizeClient_GetData(buff);printf(size%d\r\n,size);if(size0)break;for(i0;isize;i){printf(%#x ,buff[i]);}buff[size]\0;if(size5){printf(%s\r\n,buff5);if(strstr((char*)buff[5],properties/set/request_id)){char *pNULL;pstrstr((char*)buff[5],request_id);if(p){ //解析数据//$oc/devices/6210e8acde9933029be8facf_dev1/sys/properties/get/request_id5f359b5c-542f-460e-9f51-85e82150ff4a{service_id:gps} strncpy(request_id,p,47); }//上报数据sprintf(mqtt_cmd_message,{\result_code\: 0,\result_desc\: \success\});sprintf(mqtt_cmd_data,$oc/devices/64000697352830580e48df07_dev1/sys/properties/set/response/%s,request_id);MQTT_PublishData(mqtt_cmd_data,mqtt_cmd_message,0);printf(应答-发布主题:%s\r\n,mqtt_cmd_data);printf(应答-发布数据:%s\r\n,mqtt_cmd_message);} if(strstr((char*)buff[5],\LED1\:1)) {digitalWrite(23,HIGH); //控制GPIO口输出高电平}if(strstr((char*)buff[5],\LED1\:0)) {digitalWrite(23,LOW); //控制GPIO口输出低电平} if(strstr((char*)buff[5],\LED2\:1)) {digitalWrite(24,HIGH); //控制GPIO口输出高电平} if(strstr((char*)buff[5],\LED2\:0)) {digitalWrite(24,LOW); //控制GPIO口输出低电平} if(strstr((char*)buff[5],\LED3\:1)) {digitalWrite(25,HIGH); //控制GPIO口输出高电平} if(strstr((char*)buff[5],\LED3\:0)) {digitalWrite(25,LOW); //控制GPIO口输出低电平} }printf(\r\n);}
}/*信号处理函数*/void signal_func(int sig)
{//printf(捕获的信号:%d\n,sig);if(sigSIGALRM){MQTT_SentHeart();//心跳包alarm(5);}
}typedef unsigned char uint8;
typedef unsigned int uint16;
typedef unsigned long uint32;#define HIGH_TIME 32int pinNumber 17;
uint32 databuf;uint8 readSensorData(void)
{uint8 crc; uint8 i;pinMode(pinNumber, OUTPUT); // set mode to outputdigitalWrite(pinNumber, 0); // output a high level delay(25);digitalWrite(pinNumber, 1); // output a low level pinMode(pinNumber, INPUT); // set mode to inputpullUpDnControl(pinNumber, PUD_UP);delayMicroseconds(27);if (digitalRead(pinNumber) 0) //SENSOR ANS{while (!digitalRead(pinNumber)); //wait to highfor (i 0; i 32; i){while (digitalRead(pinNumber)); //data clock startwhile (!digitalRead(pinNumber)); //data startdelayMicroseconds(HIGH_TIME);databuf * 2;if (digitalRead(pinNumber) 1) //1{databuf;}}for (i 0; i 8; i){while (digitalRead(pinNumber)); //data clock startwhile (!digitalRead(pinNumber)); //data startdelayMicroseconds(HIGH_TIME);crc * 2; if (digitalRead(pinNumber) 1) //1{crc;}}return 1;}else{return 0;}
}unsigned int DHT11_T;// 环境温度
unsigned int DHT11_H;// 环境湿度
int MQ2;// 烟雾浓度检测
int water;// 雨滴检测
int flame;// 火焰检测
int light;// 光强检测
int LED1;// LED1控制
int LED2;// LED2控制
int LED3;// LED3控制/*
硬件连线
MQ2烟雾传感器GPIO4
DHT11温湿度传感器GPIO17
火焰检测传感器GPIO18
光敏电阻GPIO27
蜂鸣器GPIO22
LED灯1GPIO23
LED灯2GPIO24
LED灯3GPIO25
雨滴检测传感器GPIO5
继电器模块GPIO6*/int main()
{//初始化GPIO口wiringPiSetupGpio(); //BCM编码格式//配置GPIO口的模式//输出模式pinMode(23,OUTPUT);pinMode(24,OUTPUT);pinMode(25,OUTPUT);pinMode(6,OUTPUT);pinMode(22,OUTPUT);//输入模式pinMode(4,INPUT);pinMode(18,INPUT);pinMode(27,INPUT);pinMode(5,INPUT);//DHT11温湿度初始化pinMode(pinNumber, OUTPUT); // set mode to outputdigitalWrite(pinNumber, 1); // output a high level int stat;sockfdsocket(AF_INET,SOCK_STREAM,0);if(sockfd-1){printf(网络套接字打开失败\n);return 0;}signal(SIGPIPE,SIG_IGN);/*忽略SIGPIPE信号*/signal(SIGALRM,signal_func);/*闹钟信号*//*域名解析*/struct hostent *hostent;while(1){hostentgethostbyname(SERVER_IP);if(hostentNULL){printf(域名解析失败\n);sleep(1);}else break;}printf(主机名:%s\n,hostent-h_name);printf(协议类型:%s\n,(hostent-h_addrtype AF_INET)?AF_INET:AF_INET6);printf(IP地址长度:%d\n,hostent-h_length);char *ip;for(int i0;hostent-h_addr_list[i];i){ipinet_ntoa(*(struct in_addr *)hostent-h_addr_list[i]);printf(ip%s\n,ip);} /*连接服务器*/struct sockaddr_in addr;addr.sin_familyAF_INET;//IPV4addr.sin_porthtons(SERVER_PORT);/*端口号*/addr.sin_addr.s_addrinet_addr(117.78.5.125);//inet_addr(ip);//服务器IPif(connect(sockfd, (struct sockaddr *)addr,sizeof(struct sockaddr_in))0){printf(server connect ok\n);MQTT_Init();while(1){/*登录服务器*/if(MQTT_Connect(ClientID,Username,Password)0){break;}sleep(1);printf(server connect ....\n);}printf(MQTT_Connect OK\r\n);//订阅物联网平台数据statMQTT_SubscribeTopic(SET_TOPIC,1,1);if(stat){close(sockfd);printf(MQTT_SubscribeTopic ERROR\r\n); exit(0);}printf(MQTT_SubscribeTopic ok\r\n);/*创建线程*/pthread_t id;pthread_create(id, NULL,pth_work_func,NULL);pthread_detach(id);//设置分离属性//发送心跳包// alarm(5);//闹钟函数时间到达会产生SIGALRM信号while(1){//读取DHT11温湿度数据pinMode(pinNumber, OUTPUT); // set mode to outputdigitalWrite(pinNumber, 1); // output a high level delay(3000);if (readSensorData()){printf(DHT11 Sensor data read ok!\n);printf(RH:%d.%d\n, (databuf 24) 0xff, (databuf 16) 0xff); printf(TMP:%d.%d\n, (databuf 8) 0xff, databuf 0xff);//温度整数部分DHT11_T((databuf 24) 0xff);printf(DHT11_T:%d\r\n,DHT11_T);//湿度整数部分DHT11_H((databuf 8) 0xff);printf(DHT11_H:%d\r\n,DHT11_H);databuf 0;}else{printf(Sensor dosent ans!\n);databuf 0;}//读取MQ2烟雾传感器状态MQ2digitalRead (4); //读取GPIO口电平状态printf(MQ2:%d\r\n,MQ2);//火警报警if(MQ20){digitalWrite(22,HIGH); //蜂鸣器响}else{digitalWrite(22,LOW); //蜂鸣器关}//读取火焰传感器状态flamedigitalRead (18); //读取GPIO口电平状态printf(flame:%d\r\n,flame);//读取光敏传感器状态lightdigitalRead (27); //读取GPIO口电平状态printf(light:%d\r\n,light);//读取雨滴检测传感器状态waterdigitalRead (5); //读取GPIO口电平状态printf(water:%d\r\n,water);//下雨关窗if(water0){digitalWrite(6,HIGH); //继电器开}else{digitalWrite(6,LOW); //蜂鸣器关}//读取LED1状态LED1digitalRead (23); //读取GPIO口电平状态printf(LED1:%d\r\n,LED1);//读取LED2状态LED2digitalRead (24); //读取GPIO口电平状态printf(LED2:%d\r\n,LED2);//读取LED3状态LED3digitalRead (25); //读取GPIO口电平状态printf(LED3:%d\r\n,LED3);//组合传感器状态数据sprintf(mqtt_message,{\services\: [{\service_id\: \stm32\,\properties\:{\DHT11_T\:%d,\DHT11_H\:%d,\MQ2\:%d,\water\:%d,\flame\:%d,\light\:%d,\LED1\:%d,\LED2\:%d,\LED3\:%d}}]},DHT11_T,DHT11_H,MQ2,water,flame,light,LED1,LED2,LED3);//温度//上报数据MQTT_PublishData(POST_TOPIC,mqtt_message,0);printf(MQTT_PublishData....\r\n);sleep(2);}}
}/*发送数据到服务器*/
int Client_SendData(u8 *buff,u32 len)
{int cnt0;cntwrite(sockfd,buff,len);if(cnt0)return -1;return 0;
}/*获取服务器下发数据*/
int Client_GetData(u8 *buff)
{int len1024;int size0;int stat0;struct pollfd fds{sockfd,POLLIN};statpoll(fds, 1,-1);sizeread(sockfd,buff,len);if(stat0size0){printf(服务器已经断开...\r\n);}return size;
}