【ARM-Linux篇】项目:智能家居

一、项目概述

•项目功能

通过语音控制客厅灯、卧室灯、风扇、人脸识别开门等,可以进行火灾险情监测,可以并且实现Sockect发送指令远程控制各类家电等
•项目描述

全志H616通过串口连接各模块硬件,检测语音的识别结果,分析语音识别的结果来对家电设备进行控制。摄像头拍摄到人脸之后通过阿里云平台人脸识别方案对比阿里云人脸数据库来进行人脸识别开锁。该项目采用设计模式中的简单工厂模式,让设备端和控制端都采用链表管理,提高了项目代码的稳定性和拓展性。

二、系统框图

三、硬件搭建

语音模块及人脸识别方案配置参考: 语音模块配置      人脸识别方案

四、软件框架

整个项目开启4个监听线程, 分别是:
1. 语音监听线程:用于监听语音指令, 当有语音指令过来后, 通过消息队列的方式给消息处理线程发送指令
2. 网络监听线程:用于监听网络指令,当有网络指令过来后, 通过消息队列的方式给消息处理线程发送指令
3. 火灾检测线程:当存在煤气泄漏或者火灾闲情时, 发送警报指令给消息处理线程
4. 消息监听线程: 用于处理以上3个线程发过来的指令,并根据指令要求配置GPIO引脚状态,OLED屏显示、语音播报,还有人脸识别开门
上述四个线程采用统一个对外接口接口,同时添加到监听链表中。 

 统一的监听模块接口如下:

struct control
{
    char control_name[128]; //监听模块名称
    int (*init)(void); //初始化函数
    void (*final)(void);//结束释放函数
    void *(*get)(void *arg);//监听函数,如语音监听
    void *(*set)(void *arg); //设置函数,如语音播报
    struct control *next;
};
struct control *add_device_to_ctrl_list(struct control *phead, struct control *device);

统一的设备类接口如下:

struct gdevice
{
    char dev_name[128]; //设备名称
    int key; //key值,用于匹配控制指令的值
    int gpio_pin; //控制的gpio引脚
    int gpio_mode; //输入输出模式
    int gpio_status; //高低电平状态
    int check_face_status; //是否进行人脸检测状态
    int voice_set_status; //是否语音语音播报
    struct gdevice *next;
};
struct gdevice *add_device_to_gdevice_list(struct gdevice *phead, struct gdevice *device);
struct gdevice *find_gdevice_by_key(struct gdevice *pdev, unsigned char key);
int set_gpio_gdevice_status(struct gdevice *pdev);

 五、项目代码

本项目代码量较大,仅展示部分源代码,项目开源地址:https://gitee.com/GeekerGao/smart-home

(一)

监听模块接口加入链表

control.c

#include <stdio.h>
#include "control.h"

struct control *add_interface_to_control_list(struct control *phead,struct control *control_interface)
{
    //头插法添加节点
    if(NULL == phead)
    {   
        phead = control_interface; 
    }
    else
    {
        control_interface->next = phead;
        phead = control_interface;   
    }

    return phead;
};

control.h

#ifndef __CONTROL_H__
#define __CONTROL_H__

struct control
{
    char control_name[128]; //监听模块名称
    int (*init)(void); //初始化函数
    void (*final)(void);//结束释放函数
    void *(*get)(void *arg);//监听函数,如语音监听
    void *(*set)(void *arg); //设置函数,如语音播报
    struct control *next;
};

struct control *add_interface_to_control_list(struct control *phead,struct control *control_interface);

#endif

消息队列的接口 

msg_queue.c

#include <stdio.h>
#include "msg_queue.h"

// 定义消息队列的名称
#define QUEQUE_NAME "/test_queue"
// 创建一个新的消息队列
mqd_t msg_queue_create(void)
{
    // 初始化mqd_t变量mqd为-1,表示未成功打开消息队列
    mqd_t mqd = -1;
    
    // 定义并初始化消息队列的属性结构体
    struct mq_attr attr;
    // 设置消息队列属性:默认为阻塞模式
    attr.mq_flags = 0;           
    // 消息队列最大消息数量为10
    attr.mq_maxmsg = 10;         
    // 每条消息的最大字节数为256
    attr.mq_msgsize = 256;       
    // 当前消息队列中消息数量初始化为0
    attr.mq_curmsgs = 0;         
    // 使用mq_open函数创建消息队列,如果不存在则根据属性创建(O_CREAT),并设置读写权限(O_RDWR)
    // 第三个参数是权限位,0666表示所有用户都有读写权限,实际权限还需参考umask值
    // 第四个参数是指向消息队列属性的指针
    mqd = mq_open(QUEQUE_NAME, O_CREAT | O_RDWR, 0666, &attr);    
    // 打印消息队列描述符,用于调试
    printf("%s | %s | %d:mqd = %d\n", __FILE__,__func__,__LINE__,mqd);
    // 返回创建的消息队列描述符
    return mqd; 
}
// 清理并关闭消息队列
void msg_queue_fianl(mqd_t mqd)
{
    // 如果消息队列描述符有效,则关闭消息队列
    if(-1 != mqd)
        mq_close(mqd);
    
    // 删除消息队列
    mq_unlink(QUEQUE_NAME);    
    
    // 保险起见,再次将mqd设为-1
    mqd = -1;   
}
// 向消息队列发送消息
int send_message(mqd_t mqd,void *msg,int msg_len)
{
    int byte_send = -1;
    // 使用mq_send函数发送消息到消息队列,第四个参数0为消息的优先级,默认情况下优先级不影响消息的发送顺序
    byte_send = mq_send(mqd, (char *)msg, msg_len, 0);   
    // 返回发送的字节数,成功时应等于msg_len,失败时返回-1
    return byte_send;
}

 msg_queue.h

#ifndef __MSG_QUEUE_H__
#define __MSG_QUEUE_H__

#include <mqueue.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

mqd_t msg_queue_create(void);
void msg_queue_fianl(mqd_t mqd);
int send_message(mqd_t mqd,void *msg,int msg_len);

#endif

语音监听接口 

global.h

#ifndef __GLOBAL_H__
#define __GLOBAL_H__    
typedef struct {
    mqd_t mqd;
    struct control *ctrl_phead;
}ctrl_info_t;

#endif

voice_interface.c

#include <stdio.h>
#include <pthread.h> // 线程库
#include "voice_interface.h" // 语音接口头文件
#include "uartTool.h" // 串口操作工具库
#include "msg_queue.h" // 消息队列操作库
#include "global.h" // 全局变量和宏定义头文件

// 串口文件描述符,初始设为-1
static int serial_fd = -1;
// 初始化语音模块
static int voice_init(void)
{
    // 打开指定的串口设备,BAUD为波特率宏定义
    serial_fd = myserialOpen(SERIAL_DEV, BAUD);
    // 打印日志,显示串口文件描述符
    printf("%s|%s|%d:serial_fd = %d\n", __FILE__, __FUNCTION__, __LINE__, serial_fd);
    return serial_fd;
}
// 释放语音模块资源
static void voice_final(void)    
{
    if(-1 != serial_fd) // 如果串口已打开
    {
        // 关闭串口
        close(serial_fd);
        // 重置串口文件描述符为-1
        serial_fd = -1;
    }
}
// 线程函数,用于接收语音指令
static void *voice_get(void *arg)
{
    unsigned char buffer[6] = {0}; // 初始化缓冲区
    int len; // 接收长度
    mqd_t mqd 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Superagent:一个开源的AI助手框架与API

在人工智能日益普及的今天,如何将AI助手无缝集成到应用中成为了开发者们关注的焦点。今天,我们要介绍的Superagent正是一个为这一需求量身打造的开源框架与API。它结合了LLM、检索增强生成(RAG)和生成式AI技术,为开发者们提供了一个强大而灵活的解决方案。 一、Superagen…

PID原理及控制算法详解

文章目录 1. 概念 1.1 PID框图 1.2 具体示例&#xff1a;无人机高度控制 2. PID原理 3. 常用术语 4. 计算过程 4.1 比例控制&#xff08;Proportional&#xff09; 4.2 积分控制&#xff08;Integral&#xff09; 4.3 微分控制&#xff08;Derivative&#xff09; 5.…

6.18-6.26 旧c语言

第一章 概述 32关键字 9种控制语句 优点&#xff1a;能直接访问物理地址&#xff0c;位操作&#xff0c;代码质量高&#xff0c;执行效率高 可移植性好 面向过程&#xff1a;以事件为中心 面向对象&#xff1a;以实物为中心 printf&#xff1a;系统定义的标准函数 #include&l…

[图解]建模相关的基础知识-19

1 00:00:00,640 --> 00:00:04,900 前面讲了关系的这些范式 2 00:00:06,370 --> 00:00:11,570 对于我们建模思路来说&#xff0c;有什么样的作用 3 00:00:12,660 --> 00:00:15,230 我们建模的话&#xff0c;可以有两个思路 4 00:00:16,790 --> 00:00:20,600 一个…

《Redis设计与实现》阅读总结-3

第 12 章 事件 Redis服务器是一个事件驱动程序&#xff0c;服务器需要处理两类事件&#xff1a;文件事件和时间事件 一、文件事件 1. 文件处理器&#xff1a;Redis基于Reactor模式开发了自己的网络事件处理器被称为文件处理器 文件事件处理器使用I/O多路复用程序来同时监听多…

electron线上跨域问题

一、配置background.js win new BrowserWindow({webPreferences: {nodeIntegration: true, // 使渲染进程拥有node环境//关闭web权限检查&#xff0c;允许跨域webSecurity: false,// Use pluginOptions.nodeIntegration, leave this alone// See nklayman.github.io/vue-cli-p…

win11系统重装?正版系统Windows11安装重启!保姆级重装系统攻略!

随着科技的不断发展&#xff0c;Windows 11系统已经逐渐成为了众多电脑用户的新选择。然而&#xff0c;当当电脑出现严重故障、受到病毒攻击、软件冲突、系统升级失败、硬件更换或升级、系统性能下降或个性化需求等情况时&#xff0c;重装系统可能是一个有效的解决方案。本文将…

江协科技51单片机学习- p16 矩阵键盘

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

武汉星起航:跨境电商浪潮下,中国卖家扬帆出海,书写国际新篇章

随着全球化进程的加速和互联网技术的飞速发展&#xff0c;跨境出口电商模式已成为中国卖家海外拓展的重要渠道。这一模式不仅为商家带来了巨大的市场机遇&#xff0c;更为中国卖家在全球舞台上展示其独特魅力和竞争力提供了宝贵平台。武汉星起航将从多个维度探讨中国卖家海外发…

基于 GD32F450 的Zephyr 的基本测试-编译工程

一、cmake 编译 hello world 测试 打开示例工程 hello world cd ~/zephyrproject/zephyr/samples/hello_world新建 build 目前&#xff0c;用于存放临时文件目录&#xff0c;并进入该目录 mkdir -p build && cd build通过 cmake 指令 生成 gd32f450z 工程的 makefil…

聚观早报 | 小鹏MONA M03曝光;iPhone 16系列电池改进

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 6月25日消息 小鹏MONA M03曝光 iPhone 16系列电池改进 一加Ace 3 Pro三款配色 字节跳动与博通合作开发AI芯片 蚂…

【efinix】efinity如何安装官方补丁patch

efinix官网可以下载efinity的官方补丁。 下载 efinity-2023.2.307.5.10-windows-x64-patch.zip 解压缩补丁zip 压缩包内容 files/ : updated files to be copied into the Efinity installation run.sh : patch installation script (Linux on…

Open3D 显示带有强度的点云数据

目录 一、概述 1.1强度信息的意义 1.2应用场景 二、代码实现 三、实现效果 一、概述 在点云数据中&#xff0c;强度&#xff08;Intensity&#xff09;指的是激光雷达传感器在扫描环境时&#xff0c;每个点返回的反射强度值。这些强度值代表了激光脉冲返回的能量&#xff…

python目录树生成器

代码如下&#xff1a; import os from colorama import Fore, Style, init from tkinter import Tk, Label, Entry, Button, Text, Scrollbar, RIGHT, Y, END# 初始化 colorama init(autoresetTrue)def print_directory_tree(root_dir, text_widget, indent, lastTrue):"…

Qt Quick Effect Maker 工具使用介绍

一、介绍 随着 Qt 版本的不断升级,越来越多的功能被加入 Qt,一些新的工具也随之应运而生,Qt Quick Effect Maker 工具是 Qt 6.5 之后才新添加的工具,之前的名字应该是叫做 Qt shader tool 这个模块。 以下是官方的释义:Qt Quick Effect Maker是一个用于为Qt Quick创建自定…

SpringAOP执行流程——从源码画流程图

文章目录 了解ProxyFactory入门操作添加多个Advice的执行顺序关于异常Advice关于proceed()方法指定方法才进行增强逻辑 创建代理对象的其他方式ProxyFactoryBeanBeanNameAutoProxyCreatorDefaultAdvisorAutoProxyCreator 对SpringAOP的理解TargetSourceProxyFactory选择JDK/CJL…

安卓免费短剧大全v1.0.2/全部无需VIP实时更新全平台短剧

在当今社会&#xff0c;时间成为了许多人最为宝贵的资源。忙碌的工作与繁重的日常事务&#xff0c;常常让我们难以拨出时间沉浸于长篇大幅的影视作品中。对于那些热爱剧情、渴望在生活中点缀一抹戏剧色彩的朋友们而言&#xff0c;这无疑是一种挑战。 然而&#xff0c;随着免费…

Ubuntu挂载window的网络共享文件夹爱

1.进入win10创建一个用户smb密码也是smb 2.右键进入文件夹共享 3.进入Ubuntu安装支持cifs-utils sudo apt update sudo apt install cifs-utils 4.sudo mkdir /mnt/shared 5.挂载&#xff1a; sudo mount -t cifs -o usernamesm bpasswordsmb //172.16.11.37(windowsIP)/s…

C语言学习记录20240626

飞船无论朝哪边行驶&#xff0c;都能通过结构体记录获取它的初始坐标、转向角度和在该方向行进的距离&#xff0c;需要根据这些信息计算飞船移动后的坐标。 向量(vector)指具有大小(magnitude)和方向(direction)的量&#xff0c;可以理解为有方向的线段。 标量或纯量(scalar)指…

甲子光年专访天润融通CEO吴强:客户经营如何穿越低速周期?

作者&#xff5c;陈杨、编辑&#xff5c;栗子 社会的发展从来都是从交流和联络开始的。 从结绳记事到飞马传信&#xff0c;从电话电报到互联网&#xff0c;人类的联络方式一直都在随着时代的发展不断进步。只是传统社会通信受限于技术导致效率低下&#xff0c;对经济社会产生影…