纪检监察网站建设方案,ps 矢量素材网站,沈阳定制网红小熊花的地方,网站开发技术期中试题#x1f431;作者#xff1a;一只大喵咪1201 #x1f431;专栏#xff1a;《智能家居项目》 #x1f525;格言#xff1a;你只管努力#xff0c;剩下的交给时间#xff01; 目录 #x1f95e;网卡设备接入输入子系统#x1f354;测试 #x1f95e;业务子系统#… 作者一只大喵咪1201 专栏《智能家居项目》 格言你只管努力剩下的交给时间 目录 网卡设备接入输入子系统测试 业务子系统输入事件转换为统一参数根据参数控制设备定时器按键消抖 整体效果展示项目总结源码 网卡设备接入输入子系统 网络子系统实现了在我们整个项目框架中网络子系统也输入子系统中输入设备的之一所以现在要做的就是网络子系统接入到输入子系统中。 如上图所示在输入子系统中增加网卡输入设备在头文件net_input.h中提供了增加网卡输入设备的函数声明在input_system.c中的增加输入设备函数中再增加一个网卡输入设备此时在宏观层面上已经将网卡输入子系统作为输入设备接入到输入子系统中了。
但是网卡设备作为输入子系统的输入设备还需要去实现 如上图源文件中代码所示创建了一个全局的网卡输入设备并进行了初始化还实现了添加网卡输入设备的函数。
在初始化网卡输入设备的时候用ESP8266NetInputInit函数作为该设备的初始化方法在该函数中仅做了注册输入数据处理回调函数的工作只有在这里注册好了接收中断发生后才会调用这个函数来处理数据。
输入数据处理回调函数的实现需要单独讲解一下 如上图代码是输入数据处理的回调函数同样也是使用状态机模型有三个状态前面AT层中详细讲解过这里类似不同之处在于对有效数据的处理。
当有效数据读取完毕以后要构造输入事件也就是给InputEvent类型变量event赋值包括事件发生事件事件类型并且将有效数据拷贝到事件的str成员数组中去最后要在数据末尾赋值\0因为这是一个字符串。
都事件构造好以后需要将事件上报给业务子系统也就是将输入事件放入到输入事件的环形缓冲区中最后将状态机恢复到初始状态以便下一次数据处理。
此时网卡就作为输入设备接入到输入子系统中了这个过程中的核心工作就是该UART3中断函数注册回调函数下面来看测试代码。
测试 如上图代码所示在上篇文章网络子系统的测试代码中增加了部分内容如蓝色框所示。 如上图所示将程序烧带到开发板并且上电以后准备工作完成远端发送数据后ESP8266模块接收到网络数据并构造成为输入事件InputEvent类型可以看到事件类型type2并且显示了有效数据。
按键按下时也会产生输入事件可以看到输入事件类型type0。无论什么类型的事件都会构造一个InputEvent类型变量放入输入子系统的环形缓冲区中只需要不断读取环形缓冲区即可。
业务子系统
现在所有的子系统都实现了接下来就是要用这些子系统共同构成业务子系统来看下整个业务子系统有什么功能
使用按键控制LED
K1控制红灯松开后改变LED状态K2控制绿灯松开后改变LED状态
通过网络控制LED、风扇
PC端的sscom或者用微信小程序给MCU板子发送网络数据控制板子上的设备
控制灯LEDDevice设为lamp1、lamp2、lamp3一共三个LED等。
控制命令如下
状态命令开{“dev”:“lamp1”,“status”:“1”}关{“dev”:“lamp1”,“status”:“0”}反转{“dev”:“lamp1”,“status”:“2”}
控制风扇
控制命令如下
状态命令顺时针旋转{“dev”:“fan”,“status”:“1”}逆时针旋转{“dev”:“fan”,“status”:“-1”}停止{“dev”:“fan”,“status”:“0”}
离家回家模式离家时将3个LED灯和1个风扇都关闭回家时将3个LED灯和1个风扇都打开。
控制命令如下
状态命令回家{“dev”:“home”,“status”:“0”}离家{“dev”:“home”,“status”:“1”}
上面的控制命令采用Json格式以“名称 :值”对的方式存储数据名称和值之间是以冒号间隔例如Name:A-Big-MiaoMi。
Json数据由花括号括起来可以包含多个“名称:值”对以逗号隔开例如{Name:A-Big-MiaoMi,Sex:Male,Age:24}此时就存在三对数据。 底层由按键、网卡发出InputEvent输入事件。最上层用来控制设备。
根据底层发来的参数控制设备要屏蔽底层设备细节及它发来的数据上层不关心底下的是按键、遥控器还是小程序只需要告诉上层要做什么。
所以要使用Json数据来统一的参数格式比如{dev:lamp1,status:1}此时上层就知道要让设备lamp1的状态变成1它根本不用管这个数据是怎么来的。
无论是按键产生的输入事件函数网络产生的输入事件都要以Json数据格式交付给上层。
需要一个中间层将各类方式产生的InputEvent输入事件转为为Json格式的参数。 如上图所示业务子系统要实现这个中间层message.c然后再在smarthome.c中根据参数控制设备。
输入事件转换为统一参数 如上图代码所示当输入事件产生以后就调用该函数ConvertInputEventToJson来转换为Json格式。
首先判断是什么类型的输入事件如果是网络输入事件则将网络数据直接作为Json数据因为发送网络数据就是按照Json格式发送的相当于是远端和MCU之间的约定。 使用sscom发送数据时必须按照这个Json格式发送。使用小程序时点下按键以后后台会自动处理为Json格式并发送。 如果是按键输入事件先要判断按键是否松开如果没有松开则之间返回-1上层不处理LED灯状态。如果松开则再判断是哪个键按下将对应设备名和状态构造成Json格式供上层去处理LED灯状态。
根据参数控制设备 初始化各类设备连接WIFI在OLED上显示IP、端口读取InputEvent转换为Json格式的参数控制设备
按照上诉步骤来编写代码 如上图所示代码先初始化所有设备和子系统再显示启动信息表明业务系统正在启动再显示正在连接信息连接WIFI连接好之后显示ESP8266的IP地址和端口号做好所有准备以后在循环中检测输入事件并转换为Json格式。 本喵将WIFI名称和账号使用define内嵌到了程序中可以根据具体WIFI情况作修改。 各个步骤都是用一个函数实现的接下来就讲解一下这些函数的实现 如上图所示代码在初始化设备和子系统函数中初始化了LED设备风扇显示设备字库子系统所有输入子系统网络子系统每一部分初始化都按照前面各个单元测试时的步骤来。 如上图所示代码前两个函数只是用来表明业务子系统正在启动或者正在连接WIFI都是通过OLED设备显示的。在连接WIFI的时候放在一个循环中连接直到连接成功。 如上图所示代码WIFI连接成功以后将ESP8266的IP地址和端口号以及作者信息显示到OLED屏幕上。 如上图所示代码是业务子系统根据Json数据来控制设备的首先要解析Json数据格式获取设备名称以及设备状态都是使用的C库函数strstr来查找字串。
获取到的设备状态有大于0小于0以及等于0三种情况如果是小于0则状态部分有两个字节第一个字节是-说明是一个负数否则就是大于等于0的数。 ASCII码数字字符 - 0得到的就是整形数字。负的数字字符需要单独处理-和字符两个字节。 然后根据设备名字使用C库函数strncmp来判断是哪个设备如果是LED设备则把状态值status给它的Control方法来改变LED灯状态风扇也是同样的道理。
如果设备名是回家则将所有LED和风扇都打开如果是离家则都关闭。 使用for循环打开3个LED灯这里不太完美如果三个LED等的编号不是012则不能这样。 定时器按键消抖
按键输入设备中需要给按键消抖 如上图所示理想情况下每按一次按键产生一次按键中断也就是按键所在引脚的电平由高电平直接变成低电平记录一次数据。 如上图但是实际情况是按下按键以后由于按键金属片的机械振动会导致引脚电平发生反复变化就会发生多次中断假设发生了五次难道这五次需要都记录吗肯定不是我们只按下一次所以在程序理也需要只记录一次。
所以就要消除这个机械抖动通常有三种方式
硬件消抖
就是在机械结构或者电路中设计一些消抖结构或者消抖电路对于我们写软件的人来说这种方式不必考虑。
延时消抖
在前面的图中可以看到虽然电平会因为抖动而反复变化但最终还是会稳定到低电平可以让程序在机械抖动这个过程中停止不动也就是延时待抖动停止后再读取这个数据这就是延时消抖。
但是在使用HAL库的HAL_Delay()函数在按键中断中消抖时会出现问题HAL_Delay是使用SysTick计时的它也会产生中断。
但是默认情况下SysTick中断的优先级是最低的而我们一般设置的中断优先级都是比较高的所以在我们的中断函数中调用HAL_Delay时SysTick的中断就无法打断我们的中断就无法执行延时函数。
而我们的中断函数中它在等SysTick中断函数执行完毕才会继续向下执行此时就会导致程序卡死了不再动了。 我们自己的中断函数中不能调用HAL_Dealy延时函数否则会卡死不动。 定时器消抖 如上图同样是延时消抖的思想假设我们给它设置了10ms延时也就是一个timer每发生一次中断就延时一个timer直到不再抖动稳定下来才记录。
这种方式中每发生一次中断延时就推后一个timer也就是从头开始计时一个timer。 按键中断这里采用的是上升和下降沿都触发。 如上图所示代码在按键设备中的头文件gpio_key.h中增加获取按键的定时时间(延时多久了)设置按键的定时器事件(要延时多久)以及一个对按键定时器处理的函数。 如上图对应gpio_key.c中的源文件创建一个timers数组大小为2因为只有两个按键这个数组中存放的是对应按键要延时的时间值。
获取按键定时器时间就是获得这个数组中的值表示按键会延时多久设置定时器事件就是给这个数组设置值表示按键要要是多久。
对于按键定时器的处理中对两个定时器都要判断首先要判断定时器的值不是0说明该按键在延时同时再判断当前系统的时间值是否大于这个定时的值如果小于说明定时没到大于则说明到了。
定时到了之后要构建输入事件InputEvent并且放入到输入事件的环形缓冲区中上报给上层任何将定时器值赋值为0表示该定时器现在不用了。 上报输入事件的工作在这里干了不用在按键中断函数中上报了 那么是谁来设置这个定时器时间呢按键中断函数 如上图所示按键中断函数的回调函数中每发生一次按键中断就给对应按键的定时器timers[i]在当前时间基础上增加20作为新的定时时间。 此时中断函数不再负责上报输入事件了只负责设置定时器事件。当抖动时中断会产生多次定时时间也会不断推后每次推后20。 现在定时器已经设置好了处理定时器的方法也有了那么是谁去处理定时器并上报事件呢SysTick处理函数 如上图所示在SysTick_Handler函数中调用按键定时器处理函数相当于在让系统调用这个处理函数因为这个SysTick_Handler属于裸机内核的函数。
整体效果展示
将串口调试助手打开程序烧录到开发板中并且上电 如上图所示此时串口助手会打印很多调试信息之后最后出现OK等字眼说明程序启动成功。 如上图此时在OLED屏幕上会显示ESP8266模块的IP地址端口号以及项目作者。 如上图所示在微信小程序上搜索“百问网嵌入式物联网”使用百问网已经做好的配套小程序将OLED屏幕上显示的IP地址和端口号填进去然后提交。 如上图所示在小程序中点击3种颜色的灯通过串口调试助手的调试信息可以看到 如上图可以看到受到了3个灯的Json格式数据程序中会解析这几个数据并且控制相应的设备 如上图此时三个灯就都亮了同样可以使用两个按键控制白灯和蓝灯。
风扇也可以通过小程序界面去控制还有离家模式和回家模式本喵就不一一展示了。 如上图所示也可以通过远端软件sscom发送Json格式的数据如绿色框中所示但是切记不要加回车换行此时远端就会将数据发送给ESP8266然后通过串口调试助手打印接收到的信息MCU会解析数据进而控制风扇设备反转。 使用sscom发送的数据必须是Json格式的而且设备名也必须是文章开头提到的因为这是我们和MCU之间的约定。在点下小程序的某个控制块后它也会在后台发送对应的Json数据给ESP8266只是我们在手机上看不到但是可以通过串口调试助手看到。 项目总结
至此智能家居的项目裸机版本就实现了整个项目中最重要的就是在传递
面向对象的编程思想和方法分层的思想和编程架构
无论使用哪种设备哪种子系统在业务子系统层面都不用关心它们的底层实现只需要调用提供的结构就行都是按照这样的顺序来用
创建设备对象添加所有设备获取需要的设备并进行初始化调用设备的操作方法。
几乎都是按照这样的顺序去使用如果需要配合其他系统则添加相应的系统并初始化就可以了。
源码
完整裸机版智能家居项目源码。