基于orangePi的智能家居系统

目录

 一.接线图

1.orangePi接线

2.继电器接线 

二.语音模块的配置

1.pin脚的配置

2.命令词自定义信息

 三.测试

1.通过gpio指令测试烟雾检测器是否正确连接

2.编写脚本测试其他模组接线是否正常

四.人脸识别方案

1.首先开通人脸搜索识别服务

2. 点击产品控制台,向人脸数据库中添加人脸样本数据

3.去香橙派终端执行此命令,下载阿里云SDK包

4.下载完成后,配置环境变量

5.切换至下列目录,点击人脸搜索示例代码

6.封装python代码为一个函数,并且取返回结果中最大的score值作为最终比对结果

7.C语言调用python阿里云接口

五.POSIX消息队列

1.基本API用法

 2. mq_notiy函数的使用

六.智能家居的实现

1.项目的整体框架大致如下:

2.整个项目开启4个监听线程,分别是:

3.项目结构大致如下

3.1首先,从香橙派上利用apt download下载依赖包的头文件和库文件,并拷贝到宿主机里:

3.2解压到/home/mi/Desktop/smarthome/3rd/下

3.3编写Makefile

3.4智能家居具体代码实现

face.py

face.c

face.h

msg_queue.c

msg_queue.h

myoled.c

myoled.h

socket.c

socket.h

control.c

control.h

gdevice.c

gdevice.h

global.h

voice_interface.c

voice_interface.h

smoke_interface.c

smoke_interface.h

socket_interface.c

socket_interface.h

receive_interface.c

receive_interface.h

4.inih解析库介绍

定义设备控制ini文件gdevice.ini

5.Makefile文件编写


 一.接线图

1.orangePi接线

2.继电器接线 

二.语音模块的配置

进入语音模块官网  http://www.smartpi.cn/#/  ,配置词条和识别后的串口输出指令。

1.pin脚的配置


2.命令词自定义信息

 三.测试

1.通过gpio指令测试烟雾检测器是否正确连接

sudo gpio mode 6 input   设置引脚6为输入状态

sudo gpio readall              查看引脚6为高电压(此时无烟)

sudo gpio readall              查看引脚6为变为了低电压(此时有烟)

2.编写脚本测试其他模组接线是否正常

gpio mode 2 out #卧室灯
gpio mode 5 out #课厅灯
gpio mode 7 out #电磁锁
gpio mode 8 out #风扇
gpio mode 9 out #蜂鸣器#全部拉高,继电器断开
for i in 2 5 7 8 9
dogpio write $i 1
donefor i in 2 5 7 8 9
dogpio write $i 0sleep 3gpio write $i 1
done

四.人脸识别方案

这里采用的是阿里云的人脸识别方案通义实验室视觉智能开放平台

1.首先开通人脸搜索识别服务

2. 点击产品控制台,向人脸数据库中添加人脸样本数据

3.去香橙派终端执行此命令,下载阿里云SDK包

4.下载完成后,配置环境变量

~/.bashrc/etc/profile 的末尾输入下面俩行(替换为你自己的阿里云AccessKey)

export ALIBABA_CLOUD_ACCESS_KEY_ID=<access_key_id> 
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<access_key_secret>

5.切换至下列目录,点击人脸搜索示例代码

 

# -*- coding: utf-8 -*-
# 引入依赖包
# pip install alibabacloud_facebody20191230import os
from alibabacloud_facebody20191230.models import SearchFaceRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_facebody20191230.client import Client
from alibabacloud_tea_util.models import RuntimeOptionsconfig = Config(# 创建AccessKey ID和AccessKey Secret,请参考https://help.aliyun.com/document_detail/175144.html。# 如果您用的是RAM用户的AccessKey,还需要为RAM用户授予权限AliyunVIAPIFullAccess,请参考https://help.aliyun.com/document_detail/145025.html。# 从环境变量读取配置的AccessKey ID和AccessKey Secret。运行代码示例前必须先配置环境变量。access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),# 访问的域名endpoint='facebody.cn-shanghai.aliyuncs.com',# 访问的域名对应的regionregion_id='cn-shanghai'
)
runtime_option = RuntimeOptions()
search_face_request = SearchFaceRequest(db_name='Face1',image_url='http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/facebody/SearchFace/SearchFace1.png',limit=2
)
try:# 初始化Clientclient = Client(config)response = client.search_face_with_options(search_face_request, runtime_option)# 获取整体结果print(response.body)
except Exception as error:# 获取整体报错信息print(error)# 获取单个字段print(error.code)# tips: 可通过error.__dict__查看属性名称

6.封装python代码为一个函数,并且取返回结果中最大的score值作为最终比对结果

# -*- coding: utf-8 -*-
# 引入依赖包
# pip install alibabacloud_facebody20191230
# face.pyimport os
import io
from urllib.request import urlopen
from alibabacloud_facebody20191230.client import Client
from alibabacloud_facebody20191230.models import SearchFaceAdvanceRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptionsconfig = Config(# 创建AccessKey ID和AccessKey Secret,请参考https://help.aliyun.com/document_detail/175144.html。# 如果您用的是RAM用户的AccessKey,还需要为RAM用户授予权限AliyunVIAPIFullAccess,请参考https://help.aliyun.com/document_detail/145025.html。# 从环境变量读取配置的AccessKey ID和AccessKey Secret。运行代码示例前必须先配置环境变量。access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),# 访问的域名endpoint='facebody.cn-shanghai.aliyuncs.com',# 访问的域名对应的regionregion_id='cn-shanghai'
)def alibaba_face():search_face_request = SearchFaceAdvanceRequest()# 场景一:文件在本地stream0 = open(r'/tmp/SearchFace.jpg', 'rb')search_face_request.image_url_object = stream0#场景二:使用任意可访问的url#url = 'https://viapi-test-bj.oss-cn-beijing.aliyuncs.com/viapi-3.0domepic/facebody/SearchFace1.png'#img = urlopen(url).read()#search_face_request.image_url_object = io.BytesIO(img)# 阿里云人脸数据库的名称为'default'search_face_request.db_name = 'default'search_face_request.limit = 5runtime_option = RuntimeOptions()try:# 初始化Clientclient = Client(config)response = client.search_face_advance(search_face_request, runtime_option)print(response.body)match_list = response.body.to_map()['Data']['MatchList']Scores = [item['Score'] for item in match_list[0]['FaceItems']] #set集合,无序不重复的数据集合max_score = max(Scores)# 获取整体结果value = round(max_score, 2)return valueexcept Exception as error:# 获取整体报错信息print(error)# 获取单个字段print(error.code)return 0.0# tips: 可通过error.__dict__查看属性名称#关闭流#stream0.close()if __name__ == "__main__":alibaba_face()

运行结果

7.C语言调用python阿里云接口

 face.c

#include <Python.h>#define WGET_CMD "wget http://127.0.0.1:8080/?action=snapshot -O /tmp/SearchFace.jpg"
#define SEARCHFACE_FILE "/tmp/SearchFace.jpg"void face_init(void){// 初始化Python解释器Py_Initialize(); // 导入 sys 模块PyObject *sys = PyImport_ImportModule("sys");// 获取 sys 模块的 path 属性PyObject *path = PyObject_GetAttrString(sys, "path");// 将当前路径添加到 sys.path 中PyList_Append(path, PyUnicode_FromString("."));Py_DECREF(sys);  // 释放 sys 引用Py_DECREF(path); // 释放 path 引用
}void face_final(void){// 关闭Python解释器Py_Finalize();
}double face_category(void)
{double result = 0.0;// A.使用 wget 命令从本地服务器下载一张快照图片system(WGET_CMD);// B.检查刚才下载的图片文件是否存在if (0 != access(SEARCHFACE_FILE, F_OK)){return result;}// C.导入 Python 模块PyObject *pModule = PyImport_ImportModule("face"); //face.py if (!pModule){PyErr_Print(); // 如果导入失败,使用 PyErr_Print() 打印错误信息printf("Error: failed to load face.py\n");goto FAILED_MODULE; // 通过 goto 跳转到 FAILED_MODULE 标签,进行清理工作并退出}// D.从模块中获取 alibaba_face 函数PyObject *pFunc = PyObject_GetAttrString(pModule, "alibaba_face");if (!pFunc){PyErr_Print(); // 如果导入失败,使用 PyErr_Print() 打印错误信息printf("Error: failed to load alibaba_face\n");goto FAILED_FUNC; // 通过 goto 跳转到 FAILED_FUNC 标签,进行清理工作并退出}// E.调用alibaba_face函数PyObject *pValue = PyObject_CallObject(pFunc, NULL); if (!pValue){PyErr_Print();printf("Error: function call failed\n");goto FAILED_VALUE;}// F.解析调用alibaba_face函数的返回值,转行成c语言格式if (!PyArg_Parse(pValue, "d", &result)) {PyErr_Print();printf("Error: parse failed");goto FAILED_VALUE;}printf("result=%0.2lf\n", result);FAILED_VALUE:Py_DECREF(pValue);
FAILED_FUNC:Py_DECREF(pFunc);
FAILED_MODULE:Py_DECREF(pModule);return result;
}

五.POSIX消息队列

1.基本API用法

#include <mqueue.h>
//创建或打开消息队列
mqd_t mq_open(const char *name, int oflag,mode_t mode, struct mq_attr attr ); 
//关闭消息队列
int mq_close(mqd_t mqdes);  
//删除消息队列                                                  
int mq_unlink(const char *name);      
//发送消息                                        
int mq_send(mqd_t mqdes, const char *ptr, size_tlen, unsigned int prio);      
//接受消息
ssize_t mq_receive(mqd_t mqdes, char *ptr, size_tlen, unsigned int *prio);    //消息队列的属性
struct mq_attr{long mq_flags;//阻塞标志,0(阻塞)或O_NONBLOCKlong mq_maxmsg;//最大消息数long mq_msgsize;//每个消息最大大小long mq_curmsgs;//当前消息数
};
#endif
#include <mqueue.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>// 消息队列的名字
#define QUEUE_NAME "/test_queue"
// 要发送的消息
#define MESSAGE "hello,world"void *sender_thread(void *arg) {sleep(10);mqd_t mqd = *(mqd_t *)arg;// 发送消息char message[] = MESSAGE;printf("sender_thread message is: %s, mqd = %d\n", message, (int)mqd);if (mq_send(mqd, message, strlen(message) + 1, 0) == -1) {switch (errno) {case EAGAIN:// 消息队列已满,且设置了 O_NONBLOCK 标志printf("Error: The message queue is full.\n");break;case EBADF:// 描述符无效或未打开为写printf("Error: Invalid message queue descriptor or not open for writing.\n");break;}perror("mq_send");} else {// 消息发送成功的处理printf("Message sent successfully.\n");}return NULL;
}void *receiver_thread(void *arg) {sleep(10);// 获取消息队列描述符mqd_t mqd = *(mqd_t *)arg;// 定义合理大小的消息缓冲区char message[256];// 接受消息ssize_t size = mq_receive(mqd, message, sizeof(message), NULL);// 错误检查if (size >= 0) {printf("Message receive successfully.\n");printf("receiver_thread message is: %s, size is: %zd, mqd = %d\n", message, size, (int)mqd);} else {// 根据错误码进行不同的处理switch (errno) {case EAGAIN: //消息队列已经满fprintf(stderr, "mq_receive error: The queue is empty and O_NONBLOCK was set.\n");break;case EBADF: //检查mqd是否成功打开fprintf(stderr, "mq_receive error: Invalid descriptor or not opened for reading.\n");break;}}return NULL;
}int main(int argc, char *argv[]) {pthread_t sender, receiver;mqd_t mqd = -1;struct mq_attr attr = {0}; // 初始化结构体attr.mq_flags = 0; // 阻塞模式attr.mq_maxmsg = 10; // 最大消息数为10条attr.mq_msgsize = 256; // 每个消息的最大大小attr.mq_curmsgs = 0; // 当前消息数// 创建消息队列mqd = mq_open(QUEUE_NAME, O_CREAT | O_RDWR, 0666, &attr);if (mqd == (mqd_t)-1) {perror("mq_open");return -1;}// 创建线程if (pthread_create(&sender, NULL, sender_thread, (void *)&mqd) != 0) {perror("Create sender_thread failed!\n");return -1;}if (pthread_create(&receiver, NULL, receiver_thread, (void *)&mqd) != 0) {perror("Create receiver_thread failed!\n");return -1;}// 线程等待pthread_join(sender, NULL);pthread_join(receiver, NULL);// 关闭消息队列mq_close(mqd);// 删除消息队列mq_unlink(QUEUE_NAME);return 0;
}

运行后,可通过ls -al /dev/mqueue/查看系统中含有哪些消息队列

<

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年四川省安全员B证证考试题库及四川省安全员B证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年四川省安全员B证证考试题库及四川省安全员B证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大…

ARM----时钟

时钟频率可以是由晶振提供的&#xff0c;我们需要高频率&#xff0c;但是外部接高的晶振会不稳定&#xff0c;所有使用PLL&#xff08;锁相环&#xff09;来放大频率。接下来就让我们学习用外部晶振提供的频率来配置时钟频率。 一.时钟源的选择 在这里我们选择外部晶振作为时钟…

数据库面试题学习

B树和B树 B树 排好序的 节点内部有多个元素 B树 排好序的 节点内多个元素 叶子节点有指针&#xff08;双向指针&#xff09; 非叶子节点冗余了一份在叶子节点 mysql定义B树 InnoDB B树是B树的升级版~ InnoDB b树是怎么产生的 mysql 页 目录 16KB 自增id uuid 一页最多可以存储…

【精选】文件摆渡系统:跨网文件传输的安全与效率之选

文件摆渡系统可以解决哪些问题&#xff1f; 文件摆渡系统&#xff08;File Shuttle System&#xff09;主要是应用于不同网络、网段、区域之间的文件数据传输流转场景&#xff0c; 用于解决以下几类问题&#xff1a; 文件传输问题&#xff1a; 大文件传输&#xff1a;系统可…

Windows bat脚本学习九(srec_cat)

一、简介 srec_cat是一个在嵌入式开发中&#xff0c;使用非常频繁的软件&#xff0c;这里做个常用功能的介绍。 二、常用参数 文件类型 在使用srec_cat指令时&#xff0c;在输入文件和输出文件时&#xff0c;要指明文件的类型&#xff0c;如&#xff1a; input.hex -intel …

2024国赛数学建模C题完整论文:农作物的种植策略

农作物种植策略优化的数学建模研究&#xff08;完整论文&#xff0c;持续更新&#xff0c;大家持续关注&#xff0c;更新见文末名片 &#xff09; 摘要 在本文中&#xff0c;建立了基于整数规划、动态规划、马尔科夫决策过程、不确定性建模、多目标优化、相关性分析、蒙特卡洛…

网络层 VII(IP多播、移动IP)【★★★★★★】

一、IP 多播 1. 多播的概念 多播是让源主机一次发送的单个分组可以抵达用一个组地址标识的若干目的主机&#xff0c;即一对多的通信。在互联网上进行的多播&#xff0c;称为 IP 多播&#xff08;multicast , 以前曾译为组播&#xff09;。 与单播相比&#xff0c;在一对多的…

Linux_kernel移植uboot07

一、移植 根据硬件平台的差异&#xff0c;将代码进行少量的修改&#xff0c;修改过后的代码在目标平台上运行起来 移植还需要考虑硬件环境&#xff0c;驱动只需要考虑内核的环境 二、移植内容 1、移植Uboot uboot属于bootloader的一种&#xff0c;还有其他的bootloader&#x…

【超简单】1分钟解决ppt全文字体一键设置

省流 ppt的全部字体需要在“幻灯片母版”里面&#xff0c;“自定义字体”去设置好标题与正文的字体之后才算全部设置完毕 “视图”---“幻灯片母版” 找到“字体”---“自定义字体” 设置好中文和西文的字体&#xff0c;都可以按照自己的选择来&#xff0c;保存即可 吐槽 之…

通信工程学习:什么是FEC前向纠错

FEC&#xff1a;前向纠错 FEC&#xff08;Forward Error Correction&#xff0c;前向纠错&#xff09;是一种增加数据通信可信度的技术&#xff0c;广泛应用于计算机网络、无线通信、卫星通信等多种数据传输场景中。其基本原理和特点可以归纳如下&#xff1a; 一、FEC前向纠错…

固态硬盘装系统有必要分区吗?

前言 现在的新电脑有哪一台是不使用固态硬盘的呢&#xff1f;这个好像很少很少了…… 有个朋友买了一台新的笔记本电脑&#xff0c;开机之后&#xff0c;电脑只有一个分区&#xff08;系统C盘500GB&#xff09;。这时候她想要给笔记本分区…… 这个真的有必要分区吗&#xf…

golang关于slice map函数传参的小问题

问题 函数传参了一个slice&#xff0c;在函数内触发了对长度的修改&#xff08;添加或删除&#xff09;&#xff0c;但是未影响函数外的实参由此产生了另一个问题&#xff0c;我们用map在函数内修改会不会有影响不到实参的情况&#xff1f; 结论 map作为函数参数时是引用传递…

TCP 拥塞控制

概念详解 TCP拥塞控制是网络通信中的一个关键机制&#xff0c;它通过动态调整发送数据的速率来避免网络拥塞。以下是TCP拥塞控制的详细概念解释&#xff1a; 拥塞窗口&#xff08;CWND, Congestion Window&#xff09;: 定义&#xff1a;发送方在收到接收方的确认&#xff08;…

Java 面试题:通过JProfile排查OOM问题 内存溢出与内存泄漏问题 --xunznux

文章目录 如何通过JProfile排查OOM或内存泄漏问题1、启动工具观测程序执行状态2、使用默认设置采样3、查看memory&#xff0c;Run GC无效4、查看 Live Memory发现两个byte大数组存在5、通过快照查看堆中的内存使用情况6、找到Full GC无法清除的对象通过大对象列表定位内存泄漏问…

【SpringBoot】电脑商城-12-订单功能

创建订单 1 订单-创建数据表 1.使用use命令先选中store数据库。 USE store;2.在store数据库中创建t_order和t_order_item数据表。 CREATE TABLE t_order (oid INT AUTO_INCREMENT COMMENT 订单id,uid INT NOT NULL COMMENT 用户id,recv_name VARCHAR(20) NOT NULL COMMENT …

Mac 上 YYDS 的自动切换输入法工具:好用到原地炸裂式起飞

有一种幸福的状态就是 任何时刻你都可以全力以赴 被打断、被终止也没有遗憾 因为你对结果没有那么期待 而且已经用尽全力了 当你深刻认识到你所做的事情 是多么好的时候 自然会产生一种想要分享出去 的心情 如今社会大部分工作都被电脑化了&#xff0c;在很多方面我们的…

第140天:内网安全-横向移动局域网ARP欺骗DNS劫持钓鱼中间人单双向

目录 案例一&#xff1a;局域网&工作组-ARP原理-断网限制-单向 案例二&#xff1a;局域网&工作组-ARP欺骗-劫持数据-双向 案例三&#xff1a;局域网&工作组-DNS 劫持-钓鱼渗透-双向 案例一&#xff1a;局域网&工作组-ARP原理-断网限制-单向 原理&#xff1…

数据库MySQL基础

目录 一、数据库的介绍 1.数据库概述 &#xff08;1&#xff09;数据的存储方式 &#xff08;2&#xff09;数据库 2.常见数据库排行榜 二、数据库的安装与卸载 1.数据库的安装 2.数据库的卸载 三、数据库服务的启动与登录 1.Windows 服务方式启动 &#xff08;1&…

Java反序列化漏洞-TemplatesImpl利用链分析

文章目录 一、前言二、正文1. 寻找利用链2. 构造POC2.1 生成字节码2.2 加载字节码1&#xff09;getTransletInstance2&#xff09;defineTransletClasses 2.3 创建实例 3. 完整POC 三、参考文章 一、前言 java.lang.ClassLoader#defineClass defineClass可以加载字节码&…