【智能家居项目】裸机版本——网卡设备接入输入子系统 | 业务子系统 | 整体效果展示

news2024/11/18 5:49:51

🐱作者:一只大喵咪1201
🐱专栏:《智能家居项目》
🔥格言:你只管努力,剩下的交给时间!
请添加图片描述

目录

  • 🥞网卡设备接入输入子系统
    • 🍔测试
  • 🥞业务子系统
    • 🍔输入事件转换为统一参数
    • 🍔根据参数控制设备
    • 🍔定时器按键消抖
  • 🥞整体效果展示
  • 🥞项目总结
  • 🥞源码

🥞网卡设备接入输入子系统

图
网络子系统实现了,在我们整个项目框架中,网络子系统也输入子系统中输入设备的之一,所以现在要做的就是网络子系统接入到输入子系统中。

图
如上图所示,在输入子系统中增加网卡输入设备,在头文件net_input.h中提供了增加网卡输入设备的函数声明,在input_system.c中的增加输入设备函数中再增加一个网卡输入设备,此时在宏观层面上已经将网卡输入子系统作为输入设备接入到输入子系统中了。

但是网卡设备作为输入子系统的输入设备还需要去实现:

图

如上图源文件中代码所示,创建了一个全局的网卡输入设备并进行了初始化,还实现了添加网卡输入设备的函数。

在初始化网卡输入设备的时候,用ESP8266NetInputInit函数作为该设备的初始化方法,在该函数中仅做了注册输入数据处理回调函数的工作,只有在这里注册好了,接收中断发生后才会调用这个函数来处理数据。

输入数据处理回调函数的实现需要单独讲解一下:

图
如上图代码是输入数据处理的回调函数,同样也是使用状态机模型,有三个状态,前面AT层中详细讲解过,这里类似,不同之处在于对有效数据的处理。

当有效数据读取完毕以后,要构造输入事件,也就是给InputEvent类型变量event赋值,包括事件发生事件,事件类型,并且将有效数据拷贝到事件的str成员数组中去,最后要在数据末尾赋值'\0',因为这是一个字符串。

都事件构造好以后,需要将事件上报给业务子系统,也就是将输入事件放入到输入事件的环形缓冲区中,最后将状态机恢复到初始状态以便下一次数据处理。

此时网卡就作为输入设备接入到输入子系统中了,这个过程中的核心工作就是该UART3中断函数注册回调函数,下面来看测试代码。

🍔测试

图
如上图代码所示,在上篇文章网络子系统的测试代码中增加了部分内容,如蓝色框所示。

图
如上图所示,将程序烧带到开发板并且上电以后,准备工作完成,远端发送数据后,ESP8266模块接收到网络数据,并构造成为输入事件InputEvent类型,可以看到,事件类型type=2,并且显示了有效数据。

按键按下时也会产生输入事件,可以看到输入事件类型type=0。无论什么类型的事件,都会构造一个InputEvent类型变量放入输入子系统的环形缓冲区中,只需要不断读取环形缓冲区即可。

🥞业务子系统

现在所有的子系统都实现了,接下来就是要用这些子系统共同构成业务子系统,来看下整个业务子系统有什么功能:

  1. 使用按键控制LED
  • K1控制红灯:松开后改变LED状态
  • K2控制绿灯:松开后改变LED状态
  1. 通过网络控制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灯状态。

🍔根据参数控制设备

tu

  • 初始化各类设备
  • 连接WIFI
  • 在OLED上显示IP、端口
  • 读取InputEvent
  • 转换为Json格式的参数
  • 控制设备

按照上诉步骤来编写代码:

tu
如上图所示代码,先初始化所有设备和子系统,再显示启动信息,表明业务系统正在启动,再显示正在连接信息,连接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等的编号不是0,1,2则不能这样。

🍔定时器按键消抖

按键输入设备中,需要给按键消抖:

图
如上图所示,理想情况下,每按一次按键,产生一次按键中断,也就是按键所在引脚的电平由高电平直接变成低电平,记录一次数据。

图
如上图,但是实际情况是,按下按键以后,由于按键金属片的机械振动,会导致引脚电平发生反复变化,就会发生多次中断,假设发生了五次,难道这五次需要都记录吗?肯定不是,我们只按下一次,所以在程序理也需要只记录一次。

所以就要消除这个机械抖动,通常有三种方式:

  • 硬件消抖

就是在机械结构或者电路中设计一些消抖结构或者消抖电路,对于我们写软件的人来说,这种方式不必考虑。

  • 延时消抖

在前面的图中可以看到,虽然电平会因为抖动而反复变化,但最终还是会稳定到低电平,可以让程序在机械抖动这个过程中停止不动,也就是延时,待抖动停止后再读取这个数据,这就是延时消抖。

但是在使用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,只是我们在手机上看不到,但是可以通过串口调试助手看到。

🥞项目总结

至此智能家居的项目裸机版本就实现了,整个项目中最重要的就是在传递:

  • 面向对象的编程思想和方法
  • 分层的思想和编程架构

无论使用哪种设备,哪种子系统,在业务子系统层面都不用关心它们的底层实现,只需要调用提供的结构就行,都是按照这样的顺序来用:

  • 创建设备对象
  • 添加所有设备
  • 获取需要的设备并进行初始化
  • 调用设备的操作方法。

几乎都是按照这样的顺序去使用,如果需要配合其他系统则添加相应的系统并初始化就可以了。

🥞源码

完整裸机版智能家居项目源码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1076627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Astronomaly:利用 CNN 和主动学习识别 400 万张星系图像中的异常

星系中的异常现象是我们了解宇宙的关键。然而,随着天文观测技术的发展,天文数据正以指数级别增长,超出了天文工作者的分析能力。 尽管志愿者可以在线上参与对天文数据的处理,但他们只能进行一些简单的分类,还可能会遗漏…

数字孪生与GIS数据为何高度互补?二者融合后能达到什么样的效果?

山海鲸可视化作为一款数字孪生软件,在GIS的融合方面处于业内领先水平,那么为什么一款数字孪生软件要花费巨大的精力,去实现GIS的融合,实现后又能达到什么样的效果呢?下面就让我们来一探究竟。 一、为什么数字孪生需要…

OpenCV级联分类器识别车辆实践笔记

1. OpenCV 级联分类器的基本原理 基于Haar特征的级联分类器的目标检测是Paul Viola和Michael Jones在2001年的论文中提出的一种有效的目标检测方法。这是一种基于机器学习的方法,从大量的正面和负面图像中训练级联函数。然后用它来检测其他图像中的物体。 Haar特征…

终于找到了!多种类型的电子期刊模板在这里!

经过我不懈的努力和搜寻,终于找到了一个提供多种类型电子期刊模板的网站。这个网站拥有丰富多样的模板,可以满足各种不同的需求,无论是学术研究、商业报告还是个人兴趣爱好,都能在这里找到心仪的模板。 一、网站介绍 这个网站叫做…

弧形进度条,弧形百分比

要帮助同事写一个弧度的进度条&#xff0c;进度条顶部有一个小圆&#xff0c;具体如下 需要指出的是&#xff0c;我们canvas的绘制是需要弧度&#xff0c;所以我们代码中使用角度&#xff0c;等待绘制的时候再砖话为弧度值 <!DOCTYPE html> <html lang"en"…

【MATLAB源码-第45期】基于matlab的16APSK调制解调仿真,使用卷积编码软判决。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 1. 16APSK调制解调 16APSK (16-ary Amplitude Phase Shift Keying) 是一种相位调制技术&#xff0c;其基本思想是在恒定幅度的条件下&#xff0c;改变信号的相位&#xff0c;从而传送信息。 - 调制&#xff1a;在16APSK中&am…

【angular】TodoList小项目(已开源)

参考&#xff1a;https://segmentfault.com/a/1190000013519099 文章目录 准备工作headerTodo、Doing、Done样式&#xff08;HTMLCSS&#xff09;功能&#xff08;TS&#xff09;将输入框内容加入todoList&#xff08;addTodo&#xff09;将todo事件改到doing 服务 参考 效果&a…

C语言基础 C++

C语言基础 C 嘿&#xff0c;你想起点C基础知识&#xff0c;这是一个很好的开始&#xff01;C是一种通用的编程语言&#xff0c;被广泛用于开发各种应用程序&#xff0c;从简单的控制台程序到复杂的桌面应用和游戏开发。现在让我带你进入C的奇妙世界&#xff0c;看看它有什么特…

OBIA:900+ 患者、193w+ 影像,中科院基因组所发布我国首个生物影像共享数据库

看病就医&#xff0c;拍片已是常例。CT、核磁、X 光等影像资料可以用非侵入式手段透过人体&#xff0c;使内部器官、组织状况清晰可见&#xff0c;为临床诊断和疾病治疗提供可靠依据。 随着医学影像技术广泛发展&#xff0c;影像资料已占据国内医疗数据的 80% 以上&#xff0c…

Android平台GB28181设备接入侧如何实现SIP校时

规范解读 GB/T28181-2016规范里面&#xff0c;9.10.1章节&#xff0c;关于校时基本要求&#xff1a; 联网内设备支持基于SIP方式或 NTP方式的网络校时功能&#xff0c;标准时间为北京时间。 SIP方式校时见本节具体描述&#xff1b;NTP(见IETFRFC2030)协议的网络统一校时服务…

【通信系列 2 -- 射频电路介绍】

文章目录 1.1 射频电路介绍1.1.1 射频电路的原理1.1.2 射频电路组成和特点 1.1 射频电路介绍 射频&#xff08;RF&#xff09;是Radio Frequency的缩写&#xff0c;表示可以辐射到空间的电磁波频率&#xff0c;频率范围从300kHz&#xff5e;300GHz之间。射频就是射频电流&…

美瞳小程序经营配送商城的作用是什么

美瞳是不少小姑娘喜爱的产品&#xff0c;线上线下需求都比较旺盛&#xff0c;尤其是新款或极其漂亮的产品往往会成为疯抢的对象&#xff0c;当然市场高需求的同时商家也面临着一些难题。 通过【雨科】平台搭建美瞳商城小程序&#xff0c;将所有产品线上售卖&#xff0c;摆脱第三…

复亚智能广东智慧应急项目案例:构建“空地一体化”

近日&#xff0c;广东某区深入探索“智慧应急”发展模式&#xff0c;将无人机作为赋能应急处突与“智慧应急”的重要手段&#xff0c;利用复亚智能无人机全自动飞行系统做到“平时巡查巡检、急时辅助处突”&#xff0c;实现全面监管快速响应&#xff0c;无人机自动巡检结合多样…

Web API 基础 (Web Workers API)

Web Workers API 1、指南 1.1 使用Web Workers Web Workers是一种让Web内容在后台线程中运行脚本的简单方法。工作线程可以在不干扰用户界面的情况下执行任务。此外&#xff0c;它们还可以使用XMLHttpRequest(尽管responseXML和channel属性总是为空)或fetch(没有此类限制)执…

XPS测试仪器-科学指南针

在做 X 射线光电子能谱(XPS)测试时&#xff0c;科学指南针检测平台工作人员在与很多同学沟通中了解到&#xff0c;好多同学仅仅是通过文献或者师兄师姐的推荐对XPS测试有了解&#xff0c;但是对于其测试仪器还属于小白阶段&#xff0c;针对此&#xff0c;科学指南针检测平台团队…

ant design form数组修改 关联展示

根据form 数组项修改关联其他选项 如图&#xff0c;在项目开发中&#xff0c;每个form中有多个产品&#xff0c;提货方式不同&#xff0c;有一个需要邮寄展示收货地址&#xff0c;否则不用展示 // An highlighted block <Card title"产品信息" bordered{false}&g…

VulnHub narak

一、信息收集 1.nmap扫描开发端口 2.扫描目录 利用dirb扫描目录 3.发现 /webdav目录 访问 WebDAV 基于 HTTP 协议的通信协议&#xff0c;在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法&#xff0c;使应用程序可对Web Server直接读写&#xff0c;并支持写文件锁…

vue3源码解析

vue3源码解析与前端网络安全 VUE 3 拓展 vue3 对比 vue2 响应式数据 vue2 的响应式数据是通过 Object.defineProperty 进行数据劫持&#xff0c;其存在一些缺点&#xff1a; 必须要预知劫持的 key 是什么&#xff0c;并不能很好的监听到对象属性的添加、删除&#xff1b;初…

家政服务行业怎么做微信小程序开发

随着科技的不断发展&#xff0c;微信小程序已经成为了人们生活中不可或缺的一部分。在家政服务领域&#xff0c;微信小程序也发挥出了重要的作用。本文将探讨家政服务在微信小程序上可以实现的功能。 一、展示家政服务信息 微信小程序可以作为一个展示家政服务的平台&#xff…

XML外部实体注入攻击XXE

xml是扩展性标记语言&#xff0c;来标记数据、定义数据类型&#xff0c;是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义&#xff08;可选&#xff09;、文档元素&#xff0c;一般无法直接打开&#xff0c;可以选择用excl或记事本打…