基于OrangePi Zero2的智能家居项目(开发阶段)

news2024/12/27 11:20:35

智能家居项目的软件实现

紧接上文 基于OrangePi Zero2的智能家居项目(准备阶段)-CSDN博客

目录

一、项目整体设计

1.1项目整体设计

1.2具体划分

二、开发工作的前期准备

1、进行分类,并用Makefile文件进行管理

参考:自己创建Makefile文件管理项目工程-CSDN博客

三、具体开发项目

1、添加语音监听接口

1.1 消息队列的实现

1.2语音控制模块的实现

​编辑

1.3 消息队列函数的继续实现(在main函数里面实现)

1.4 放到香橙派上面进交叉编译

2、添加网络监听接口

2.1增加文件

2.2整理框架

2.3 优化细节,注意改动

2.4、编译好传送过去执行找问题

2.5 网络调试助手启动!

上面这张图的结果其实是错误的!!!

3、添加烟雾监听的接口

3.1 增加相应的文件

额外补充

3.2 补全smoke_interface.c

3.3 编译并发送

 3.4 具体演示(见后续安装)

ps:优化之前写的代码(语音,socket,火灾)

4、添加消息接收监听接口

4.1 添加相应的文件

4.2 补全一部分代码,初始化消息,关闭消息

4.3 receive_get函数的实现

4.4 实现控制 设备(灯、风扇)线程的功能函数

4.5 编译测试成功

5、添加设备类结点接口(用消息接收监听队列去控制设备)

5.1 创建被控设备的链表结点​编辑

5.2 添加相应的文件(毕竟是个被控设备链表)

5.3 具体实现控制的设备要怎么控制

6、添加各类的被控设备结点

6.1 添加被控设备----客厅灯

ps:对oled显示做一个处理

编译测试.....(待补充)

6.2 添加卧室灯控制代码

编译测试.....(待补充)

6.3 添加风扇控制代码

编译测试.....(待补充)

6.4添加火灾报警(烟雾报警)检测功能

添加对应的文件

修改一下smoke_interface.c里面的值

增加蜂鸣器的报警

编译测试.....(待补充)

6.5 增加OLED显示功能

编译测试.....(待补充)

7 添加人脸识别开锁

7.1 添加对应的文件

7.2判断人脸的数据才能开门

7.3 开门之后也要关门

7.4 配置摄像头

7.5 报错

7.6 编译测试

四、ini文件解析本次项目

前言

1、什么是 ini文件配置格式 

2、下载源码和解析文件

3、在项目中运用ini文件

3.1 编译运行

3.2 项目优化

4、用ini配置文件去优化本次项目的代码

4.1 先把以前的设备文件删除

4.2 添加新的代码

4.3 更改配置文件的路径


一、项目整体设计

1.1项目整体设计

1.2具体划分

定义两个统一特征的结构体(控制与被控),都是通过链表进行连接

控制设备

被控设备

二、开发工作的前期准备

1、进行分类,并用Makefile文件进行管理

参考:自己创建Makefile文件管理项目工程-CSDN博客

三、具体开发项目

1、添加语音监听接口

1.1 消息队列的实现

1.2语音控制模块的实现

.

头插法的实现,串成一个一个的设备节点

main.c

1.3 消息队列函数的继续实现(在main函数里面实现)

main.c里面继续封装消息队列的实现

终于知道voice_get里面的mqd怎么传参了

编译通过

1.4 放到香橙派上面进交叉编译

再用mqtest传到香橙派进行测试

2、添加网络监听接口

2.1增加文件

2.2整理框架

2.3 优化细节,注意改动

2.4、编译好传送过去执行找问题

2.5 网络调试助手启动!

上面这张图的结果其实是错误的!!!

3、添加烟雾监听的接口

3.1 增加相应的文件

smoke.h

补全一部分的smoke_interface.c

额外补充

3.2 补全smoke_interface.c

3.3 编译并发送

 3.4 具体演示(见后续安装)

ps:优化之前写的代码(语音,socket,火灾)

4、添加消息接收监听接口

    

4.1 添加相应的文件

4.2 补全一部分代码,初始化消息,关闭消息

4.3 receive_get函数的实现

4.4 实现控制 设备(灯、风扇)线程的功能函数

4.5 编译测试成功

5、添加设备类结点接口(用消息接收监听队列去控制设备)

5.1 创建被控设备的链表结点

5.2 添加相应的文件(毕竟是个被控设备链表)

5.3 具体实现控制的设备要怎么控制

6、添加各类的被控设备结点

6.1 添加被控设备----客厅灯

往消息接收线程函数里面,声明客厅灯的初始化

ps:对oled显示做一个处理

编译测试.....(待补充)

6.2 添加卧室灯控制代码

编译测试.....(待补充)

6.3 添加风扇控制代码

编译测试.....(待补充)

6.4添加火灾报警(烟雾报警)检测功能

这里补充一下,蜂鸣器报警的流程:先是烟雾传感器检测到有烟雾时,将数据发送给板子,板子接收到发过来的数据之后,再去触发蜂鸣器

添加对应的文件

这里的.voice_set_status 其实是“1”  要设置的

修改一下smoke_interface.c里面的值

增加蜂鸣器的报警

pthread_create就这样就行了,不用在添加其他的东西

编译测试.....(待补充)

6.5 增加OLED显示功能

编译测试.....(待补充)

7 添加人脸识别开锁

7.1 添加对应的文件

7.2判断人脸的数据才能开门

7.3 开门之后也要关门

7.4 配置摄像头

参考文章:

基于OrangePi的智能垃圾桶(全程可实现)-CSDN博客

7.5 报错

记录关于智能家居的路程的一个bug___Segmentation fault(段错误)-CSDN博客

7.6 编译测试

四、ini文件解析本次项目

前言

上述的项目的基本功能都已实现,但是存在值得优化的地方

解决办法:写一个固定的配置文件,直接添加设备就行了

所以就引入了 ini文件配置格式

1、什么是 ini文件配置格式 

关键就是 键值对

2、下载源码和解析文件

apt-cache search libinih

一个简单的ini文件的一个解析

sudo apt source libinih-dev

安装源码包(此时可以尝试使用root权限来安装)

进入文件夹

查看 示例代码

3、在项目中运用ini文件

3.1 编译运行

这里补充一点:代码中没有循环语句,说明这个handle是多次调用的

3.2 项目优化

把文件添加到ini文件夹进行测试

ini_test.c 

/* Example: parse a simple configuration file */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ini.h"
#include "gdevice.h"

#ifndef OUTPUT
#define OUTPUT 1
#define INPUT 0
#endif

#ifndef LOW
#define LOW 0
#define HIGH 1
#endif 




//像receive文件里面那样添加被控设备链表
static struct gdevice *pdevhead = NULL;

#define MATCH(s, n) strcmp(section, s) == 0 && strcmp(name, n) == 0
 //  if (MATCH("protocol", "version"))

static int handler_gdevice(void* user, const char* section, const char* name,
                   const char* value)
{
    //创建被控设备的临时的指针
    struct gdevice *pgdev = NULL;
    //找设备的逻辑就是:如果section都是一个字段,那么其他的东西(name value)肯定都是一个设备的
    //所以,我们只要找到一个section,那么这个section下面的所有name value就是同一个设备的
    //先找到section,再找name value,或者创建一个结构体,存放name value这些值
    if(NULL == pdevhead)
    {
        pdevhead = (struct gdevice *)malloc(sizeof(struct gdevice));
        pdevhead->next = NULL;
        memset(pdevhead, 0, sizeof(struct gdevice));
        strcpy(pdevhead->dev_name, section);    //把section赋值给当前设备的名字
    }
    //第一个添加结点是没错这样,但是第二个结点添加进来的时候就有空间了
    else if (0 != strcmp(pdevhead->dev_name, section))
    {
        pgdev = (struct gdevice *)malloc(sizeof(struct gdevice));
        memset(pgdev, 0, sizeof(struct gdevice));
        strcpy(pgdev->dev_name, section);
        //头插法
        pgdev->next = pdevhead;
        pdevhead = pgdev;
    }

    if(NULL != pdevhead)
    {
        if(MATCH(pdevhead->dev_name, "key"))  //假如第一个进来的是lock,就是挨着挨揍去比对他的key、gpio_pin、gpio_mode、gpio_status、check_face_status、voice_set_status这些值
        {
            sscanf(value , "%x" , &pdevhead->key);  //value是一个作为输入的值,想让其输出为16进制变成指令,所以%x
            printf("%d | pdevhead->key = %x\n" , __LINE__,pdevhead->key);
        }
        else if (MATCH(pdevhead->dev_name, "gpio_pin"))
        {
            pdevhead->gpio_pin = atoi(value);  //把字符串转换成整数

        }
        else if(MATCH(pdevhead->dev_name, "gpio_mode"))
        {
            if(strcmp(value, "OUTPUT") == 0)
            {
                pdevhead->gpio_mode = OUTPUT;  //OUTPUT
            }
            else if(strcmp(value, "INPUT") == 0)
            {
                pdevhead->gpio_mode = INPUT;  //INPUT
            }
        }
        else if(MATCH(pdevhead->dev_name, "gpio_status"))
        {
            if(strcmp(value, "LOW") == 0)
            {
                pdevhead->gpio_mode = LOW;  
            }
            else if(strcmp(value, "HIGH") == 0)
            {
                pdevhead->gpio_mode = HIGH;  
            }
        }
        else if(MATCH(pdevhead->dev_name, "check_face_status"))
        {
             pdevhead->check_face_status = atoi(value);  //把字符串转换成整数
        }
        else if(MATCH(pdevhead->dev_name, "voice_set_status"))
        {
             pdevhead->voice_set_status = atoi(value);  //把字符串转换成整数
        }

    }


    //打印有多少个ini文件里面的设备
    printf("---secition: %s, name: %s, value: %s\n", section, name, value);

    return 1;
}

int main(int argc, char* argv[])
{
    if (ini_parse("gdevice.ini", handler_gdevice, NULL) < 0) {
        printf("Can't load 'gdevice.ini'\n");
        return 1;
    }

    //测试
    struct gdevice *pdev = pdevhead;
    while(pdev)
    {
        printf("pdev->dev_name = %s\n", pdev->dev_name);
        printf("pdev->key = %x\n", pdev->key);
        printf("pdev->gpio_pin = %d\n", pdev->gpio_pin);
        printf("pdev->gpio_mode = %d\n", pdev->gpio_mode);
        printf("pdev->gpio_status = %d\n", pdev->gpio_status);
        printf("pdev->check_face_status = %d\n", pdev->check_face_status);
        printf("pdev->voice_set_status = %d\n", pdev->voice_set_status);
        pdev = pdev->next;


    }

    return 0;
}

编译运行:

4、用ini配置文件去优化本次项目的代码

4.1 先把以前的设备文件删除

4.2 添加新的代码

4.3 更改配置文件的路径

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

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

相关文章

pajamas 0 publish repo fst in gitee

0. 好久没有blog了&#xff0c;真的好久了&#xff0c;先交代一波 因为半年来发生了很多&#xff0c;计划有变&#xff0c;辞工作&#xff0c;出去耍&#xff0c;找工作&#xff0c;重新计划… 从半年前开始&#xff0c;就想好了&#xff0c;最近这两年应该优先会写代码 &…

一篇讲明白 Hadoop 生态的三大部件

文章目录 每日一句正能量前言01 HDFS02 Yarn03 Hive04 HBase05 Spark及Spark Streaming关于作者推荐理由后记赠书活动 每日一句正能量 黎明时怀着飞扬的心醒来&#xff0c;致谢爱的又一天&#xff0c;正午时沉醉于爱的狂喜中休憩&#xff0c;黄昏时带着感恩归家&#xff0c;然后…

python实现模糊神经网络(pytorch版)

1 理论 模糊神经网络是一种基于模糊逻辑的神经网络模型&#xff0c;其主要用于处理模糊信息和不确定性的问题。模糊神经网络可以将输入数据映射到一个模糊集合中&#xff0c;然后通过一系列的模糊规则进行求解&#xff0c;最终输出一个模糊集合。 模糊神经网络的基本原理是将…

AMD GPUs - Radeon™ PRO W7900与NVIDIA 4000系列GPU性能

文心一言 RTX 4090的性能高于AMD Radeon PRO W7900。 RTX 4090具有760亿个晶体管、16384个CUDA核心和24GB高速镁光GDDR6X显存&#xff0c;在4K分辨率的游戏中持续以超过100FPS运行。RTX 4090采用全新的DLSS 3技术&#xff0c;相比3090TI&#xff0c;性能提升可达2~4倍&#x…

CSS实现元素边框渐变动画

前言&#xff1a; 边框流动动画是一种非常常见的效果&#xff0c;能够让网页看起来更加生动有趣。通过使用 CSS3&#xff0c;我们可以轻松地实现这种动画效果。本文将介绍如何使用 CSS3 实现边框流动效果&#xff0c;下面一起来看看吧。 示例图&#xff1a;边框是动画持续变化的…

MCRNet:用于乳腺超声成像语义分割的多级上下文细化网络

MCRNet&#xff1a;用于乳腺超声成像语义分割的多级上下文细化网络 摘要引言方法 MCRNet_ Multi-level context refinement network for semantic segmentation in breast ultrasound imaging 摘要 由于对比度差、目标边界模糊和大量阴影的不利影响&#xff0c;乳腺超声成像中…

文献阅读:通过 NeuronChat 从单细胞转录组推断神经元-神经元通信

文献介绍 「文献题目」 Inferring neuron-neuron communications from single-cell transcriptomics through NeuronChat 「研究团队」 聂青&#xff08;加利福尼亚大学欧文分校&#xff09; 「发表时间」 2023-02-28 「发表期刊」 Nature Communications 「影响因子」 16.6…

mysql8 功能特点

1.查询缓存 删除了 2.secondary engine 设置&#xff1a; MySQL默认的存储引擎是InnoDB&#xff0c;而引入Secondary Engine&#xff0c;用来实现同时支持多引擎&#xff0c;在同一个MySQL Server上挂多个存储引擎&#xff0c;在支持InnoDB的同时&#xff0c;还可以把数据存放…

CommunityToolkit.Mvvm----配置

一、介绍&#xff1a; CommunityToolkit.Mvvm 包&#xff08;又名 MVVM 工具包&#xff0c;以前称为 Microsoft.Toolkit.Mvvm&#xff09;是一个现代、快速和模块化的 MVVM 库。 它是 .NET 社区工具包的一部分&#xff0c;围绕以下原则生成&#xff1a; 独立于平台和运行时 - …

Pandas | value_counts() 的详细用法

value_counts() 函数得作用 用来统计数据表中&#xff0c;指定列里有多少个不同的数据值&#xff0c;并计算每个不同值有在该列中的个数&#xff0c;同时还能根据指定得参数返回排序后结果。 返回得是Series对象 value_counts(values,sortTrue, ascendingFalse, normalizeFal…

《Linux运维实战:达梦DM8数据库之基本操作》

一、创建表空间 1.1、使用客户端工具创建 1、使用 SYSDBA 用户登录 DM 管理工具。右键表空间模块&#xff0c;点击【新建表空间】&#xff0c;如下图所示&#xff1a; 2、可根据项目需要&#xff0c;修改表空间文件、路径、大小、是否自动扩充、扩充上限等信息&#xff0c;如下…

网络类型整理

1、点到点 &#xff1a;在一个网段内只能存在&#xff0c;两个物理节点 MA-多路访问 -- 在一个网段内物理节点的数量不限制 MA--- BMA NBMA 2、BMA -- 广播型多路访问 3、NBMA--非广播型多路访问 注&#xff1a;不同网络类型实际为不同的数据链路层技术&#xff1b;由于二…

力扣--对链表进行插入排序--147

该题是不带哨兵位的&#xff01;&#xff01;&#xff01; 目录 该题是不带哨兵位的&#xff01;&#xff01;&#xff01; 首先先进行带哨兵位的代码展示&#xff1a; 但是就提论题&#xff0c;力扣上的这道题&#xff0c;没有明确说明附带哨兵位&#xff0c;我们一律按照…

11-SpringSecurity:Session共享,菜鸟驿站java面试题

pom依赖 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-security org.springframework.boot spring-boot-starter-data-redis org.springframework.session spring-session-data-redis org.projectlombok lombok …

1.java 安装

操作步骤 下载: https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html1 通过Xftp将下载下来的jdk上传到指定虚拟机上传到/usr目录下 2 通过Xshell连接到虚拟机&#xff0c;执行如下命令&#xff0c;解压文件&#xff1a; $ tar zxvf jdk-8u…

算法沉淀 —— 动态规划篇(简单多状态dp问题下)

算法沉淀 —— 动态规划篇&#xff08;简单多状态dp问题下&#xff09; 前言一、买卖股票的最佳时机含冷冻期二、买卖股票的最佳时机含手续费三、买卖股票的最佳时机 IV 前言 几乎所有的动态规划问题大致可分为以下5个步骤&#xff0c;后续所有问题分析都将基于此 1.、状态表示…

概率论经典题目-二维随机变量及分布--由概率密度求分布函数和概率

解答&#xff1a; 由概率密度函数求解分布函数的公式可知&#xff1a; 辅助图形加以确定积分上下限

LCX端口转发

LCX介绍 LCX是一款端口转发工具&#xff0c;分为Windows版和Linux版&#xff0c;Linux版本为PortMap。LCX有端口映射和端口转发两大功能&#xff0c;例如当目标的3389端口只对内开放而不对外开放时&#xff0c;可以使用端口映射将3389端口映射到目标的其他端口使用&#xff1b…

k8s1.28.8版本配置Alertmanager报警方式(邮件,企业微信)

文章目录 总结部署流程 Alertmanager 三大核心1. 分组告警2. 告警抑制3. 告警静默 报警过滤静默通知方案一&#xff1a;方案二&#xff1a; 抑制报警规则案例一 参考文档 自定义路由告警&#xff0c;分来自不同路由的告警&#xff0c;艾特不同的人员进行区分修改 alertmanager …

Spark-Scala语言实战(9)

之前的文章中&#xff0c;我们学习了如何在spark中使用RDD方法的flatMap,take,union。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark-Scala语言实战&am…