智能家居4 -- 添加接收消息的初步处理

 这一模块的思路和前面的语言控制模块很相似,差别只是调用TCP 去控制

废话少说,放码过来

增添/修改代码

receive_interface.c


#include <pthread.h>
#include <mqueue.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>#include "receive_interface.h"
#include "control.h"
#include "mq_queue.h"
#include "global.h"
#include "face.h"
#include "myoled.h"/*
接收模块:
对接收到消息做出相应处理
包括 oled 人脸识别 语言播报 GPIO  引脚状态配置*/static int oled_fd = -1;typedef struct  
{int msg_len;unsigned char*buffer;ctrl_info_t *ctrl_info;
}recv_msg_t;static int  receive_init(void)
{ // 设备类链表添加oled_fd = myoled_init(); // 初始化oledface_init(); // 初始化人脸识别return 0;
}static void receive_final(void) 
{face_final();if(-1 != oled_fd){close(oled_fd); // 关闭oled 打开的文件oled_fd = -1; //复位}}
//  处理设备 --  比如打开灯 和风扇等
static void*handler_device(void *arg)
{pthread_detach(pthread_self()); // 和主线程(他的父线程)分离recv_msg_t *recv_msg = NULL;if(NULL != arg){recv_msg = (recv_msg_t *)arg;printf("recv_len = %d\n",recv_msg->msg_len);printf("%s|%s|%d, handler: 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\n",__FILE__,__func__,__LINE__,recv_msg->buffer[0],recv_msg->buffer[1],recv_msg->buffer[2],recv_msg->buffer[3],recv_msg->buffer[4],recv_msg->buffer[5]);}// need to do something pthread_exit(0);
}static void* receive_get(void *arg) // 接收消息队列里面的 数据
{printf("enter receive_get\n");//  通过参数 初始化我们 定义的recv_msg_t 结构体recv_msg_t *recv_msg = NULL;unsigned char*buffer = NULL;struct mq_attr attr;pthread_t tid = -1;ssize_t read_len = -1;if(NULL != arg){recv_msg = (recv_msg_t *)malloc(sizeof(recv_msg_t));recv_msg->ctrl_info = (ctrl_info_t *)arg;// 这里实际上就获取到了mqd 和 phead(我们需要操作的struct control 链表 的头节点)recv_msg->msg_len = 0;recv_msg->buffer = NULL;}elsepthread_exit(0);if(mq_getattr(recv_msg->ctrl_info->mqd,&attr) == -1){ // 获取消息队列失败 -- 异常pthread_exit(0);}// 能获取到消息队列recv_msg->buffer = (unsigned char *)malloc(attr.mq_msgsize); // 分配内存buffer = (unsigned char *)malloc(attr.mq_msgsize); // mq_msgsize -- 每条消息的大小memset(recv_msg->buffer,0,attr.mq_msgsize); // 初始化memset(buffer,0,attr.mq_msgsize); // 初始化pthread_detach(pthread_self()); // 和主线程(他的父线程)分离while (1){read_len = mq_receive(recv_msg->ctrl_info->mqd,buffer,attr.mq_msgsize,NULL) ;printf("%s|%s|%d, recv: 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\n",__FILE__,__func__,__LINE__,buffer[0],buffer[1],buffer[2],buffer[3],buffer[4],buffer[5]);printf("%s|%s|%d: read_len = %ld\n",__FILE__,__func__,__LINE__,read_len);if(-1 == read_len){// 接收失败if(errno == EAGAIN){printf("queue is empty\n");}else{break;}}// 以下是接收到正常数据的情况 else if(buffer[0] == 0xAA && buffer[1] == 0x55 &&buffer[4]==0x55 && buffer[5]==0xAA){recv_msg->msg_len = read_len;memcpy(recv_msg->buffer,buffer,read_len);//  创建线程去 处理我们的接收到的信号pthread_create(&tid,NULL,handler_device,(void*)recv_msg);}}if(NULL != recv_msg)free(recv_msg);if(NULL !=  buffer)free(buffer);pthread_exit(0);}struct  control receive_control ={.control_name = "receive",.init = receive_init,.final = receive_final,.get = receive_get,.set = NULL, //不需要实现 设置.next = NULL
};struct control *add_receive_to_ctrl_list(struct control *phead)
{//头插法实现 添加链表节点return add_interface_to_ctrl_list(phead,&receive_control);};



receive_interface.h


#ifndef ___RECEIVE_INTERFACE_H___
#define ___RECEIVE_INTERFACE_H___#include "control.h"
struct control *add_receive_to_ctrl_list(struct control *phead);#endif

修改的main.c


#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <wiringPi.h>#include "control.h"
#include "mq_queue.h"
#include "voice_interface.h"
#include "socket_interface.h"
#include "smoke_interface.h"
#include "receive_interface.h"
#include "global.h"// msg_queue_createint main() {pthread_t thread_id;struct control *control_phead = NULL;struct control *pointer = NULL;ctrl_info_t *ctrl_info = NULL;ctrl_info = (ctrl_info_t *)malloc(sizeof(ctrl_info_t));ctrl_info->ctrl_phead = NULL;ctrl_info->mqd = -1;int node_num = 0; // 统计节点数if(-1 == wiringPiSetup())// 初始化 wiringPi 库{perror("wiringPi Init");return -1;}// 创建消息队列ctrl_info->mqd = msg_queue_create();if(-1 == ctrl_info->mqd)// 创建消息队列失败{printf("%s|%s|%d, mqd= %d\n",__FILE__,__func__,__LINE__,ctrl_info->mqd);return -1;}//  头插法插入 , so 头一直在变化ctrl_info->ctrl_phead = add_voice_to_ctrl_list(ctrl_info->ctrl_phead);ctrl_info->ctrl_phead = add_tcpsocket_to_ctrl_list(ctrl_info->ctrl_phead);ctrl_info->ctrl_phead = add_smoke_to_ctrl_list(ctrl_info->ctrl_phead);ctrl_info->ctrl_phead = add_receive_to_ctrl_list(ctrl_info->ctrl_phead);pointer = ctrl_info->ctrl_phead;while(NULL!=pointer) // 对所有控制结构体初始化,并且统计节点数{if(NULL != pointer->init){printf("%s|%s|%d   control_name = %s\n",__FILE__,__func__,__LINE__,pointer->control_name);pointer->init();}pointer = pointer->next;node_num++; // 统计节点数}// 根据节点的总数 --> 创建对应数目的线程pthread_t *tid = (pthread_t *)malloc(sizeof(int) *node_num);pointer = ctrl_info->ctrl_phead;for(int i=0;i<node_num;++i)//遍历所有节点{if(NULL != pointer->get){printf("%s|%s|%d   control_name = %s\n",__FILE__,__func__,__LINE__,pointer->control_name);pthread_create(&tid[i],NULL,(void *)pointer->get,(void *)ctrl_info); // 传入这个结构体参数,方便同时调用多组线程里面的API}pointer = pointer->next;}for(int i=0;i<node_num;++i){pthread_join(tid[i],NULL);}for(int i=0;i<node_num;++i){if(NULL != pointer->final)pointer->final(); // 接打开的使用接口关闭pointer = pointer->next;}msq_queue_final(ctrl_info->mqd);if(NULL != ctrl_info)free(ctrl_info); // 这个是malloc 堆区申请的内存 -->  需要手动的释放if(NULL != tid)free(tid);return 0;
}

编译执行:

编译:

make

发送到arm-64平台

scp ./obj/smarthome  orangepi@192.168.1.11:/home/orangepi

// 需要用到阿里云人脸识别接口,需要调用 py文件,一起传过去
 scp src/face.py  orangepi@192.168.1.11:/home/orangepi

执行:

sudo -E ./smarthome

可以看到我们的 hanler 函数已经接收到对的数据了,剩下的就是对这些数据的处理了,我们将在下一篇实现,让代码和关联设备们起来,进一步完善我们的功能。

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

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

相关文章

李廉洋:5.8黄金原油多次小跌,今日必看独家策略。

黄金消息面分析&#xff1a;联储卡什卡利表示&#xff0c;需要更多的数据才能知道通胀回到2%目标的进展是否已经停滞&#xff0c;现在就宣布肯定已经停滞不前还为时过早。卡什卡利说&#xff1a;“我们现在的情况很好&#xff0c;劳动力市场依然强劲&#xff0c;我们可以慢慢获…

【实验3.1]使用Scrapy采集豆瓣读书评分在9分以上的图书数据。 要求采集每本图书的数据,包括图书名、评分、作者、出版社和出版年份。

目录 1.项目代码如图所示&#xff1a; 2.代码详情 __init__.py dbbook.py __init__.py items.py pipelines.py setting.py main.py scrapy.cfg 4.实验前准备&#xff1a; 1.项目代码如图所示&#xff1a; 2.代码详情 __init__.py # This package will contain the…

remmina无法连接远程桌面,Remmina无法连接远程桌面的原因与解决办法

在解决Remmina无法连接远程桌面的问题时&#xff0c;我们需要考虑多种可能的原因&#xff0c;并采取相应的解决办法。以下是一些常见的原因及其对应的解决方案&#xff1a; 1、网络问题 原因&#xff1a;不稳定的网络连接或中断可能导致无法建立远程桌面连接。 解决办法&#x…

stack的使用

1.栈的定义 我们可以看到模板参数里面有一个容器适配器 &#xff0c;什么是适配器&#xff1f;比如充电器就叫做电源适配器&#xff0c;用在做转换&#xff0c;对电压进行相关的转换适配我们的设备。栈&#xff0c;队列不是自己直接管理数据&#xff0c;是让其他容器管理数据&a…

D3CTF2024

文章目录 前言notewrite_flag_where【复现】D3BabyEscapePwnShell 前言 本次比赛笔者就做出两道简单题&#xff0c;但队里师傅太快了&#xff0c;所以也没我啥事。然后 WebPwn 那题命令行通了&#xff0c;但是浏览器不会调试&#xff0c;然后就简单记录一下。 note 只开了 N…

Python专题:四、字符串(1)

str是类 字符串可以是任意内容 &#xff08;单引号&#xff09; ""&#xff08;双引号&#xff09; 三引号可跨行输入 print&#xff08;&#xff09;打印字符串 字符 下面这些也都是字符 字符——>数字&#xff0c;ASCII编码&#xff0c;美国信息交换标准代码&a…

鸿蒙开发全攻略:华为应用系统如何携手嵌入式技术开启新篇章~

鸿蒙操作系统是华为自主创新的成果&#xff0c;打破了传统操作系统的局限。通过结合嵌入式技术&#xff0c;鸿蒙实现了跨平台、跨设备的高度融合&#xff0c;提供了流畅、智能的体验。华为应用系统与嵌入式技术的结合&#xff0c;提升了性能&#xff0c;丰富了用户体验。鸿蒙与…

基于springboot+vue+Mysql的口腔管理平台

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

深入理解Python的类,实例和type函数

问题起源&#xff1a; class t():pass s1 t() s2 type("Student2",(),{}) isinstance(s1, type), isinstance(s2, type)为什么第一个是false&#xff0c;第二个是true呢 根因定位&#xff1a; 在Python中&#xff0c;一切皆对象&#xff0c;类是对象&#xff0c…

MindSponge分子动力学模拟——定义一个分子系统

技术背景 在前面两篇文章中&#xff0c;我们分别介绍了分子动力学模拟软件MindSponge的软件架构和安装与使用。这里我们进入到实用化阶段&#xff0c;假定大家都已经在本地部署好了基于MindSpore的MindSponge的编程环境&#xff0c;开始用MindSponge去做一些真正的分子模拟的工…

Nacos单机模式集成MySQL

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Nacos支持三种部署…

《编译原理》阅读笔记:p1-p3

《编译原理》学习第 1 天&#xff0c;p1-p3总结&#xff0c;总计 3 页。 一、技术总结 1.compiler(编译器) p1, But, before a program can be run, it first must be translated into a form in which it can be executed by a computer. The software systems that do thi…