智能家居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.rhkb.cn/news/322174.html

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

相关文章

[初阶数据结构】单链表

前言 &#x1f4da;作者简介&#xff1a;爱编程的小马&#xff0c;正在学习C/C&#xff0c;Linux及MySQL。 &#x1f4da;本文收录于初阶数据结构系列&#xff0c;本专栏主要是针对时间、空间复杂度&#xff0c;顺序表和链表、栈和队列、二叉树以及各类排序算法&#xff0c;持…

k8s安装nginx Ingress超详细指南

在本全面的 Ingress 指南中&#xff0c;您将学习如何在 Kubernetes 上设置 Nginx Ingress控制器并使用 DNS 配置 Ingress。 目前有两种 Nginx Ingress 控制器。 kubernetes 社区的 Nginx Ingress 控制器Nginx Inc 开发的 Nginx Ingress 控制器 我们将使用 Kubernetes 社区 N…

论文分享[cvpr2018]Non-local Neural Networks非局部神经网络

论文 https://arxiv.org/abs/1711.07971 代码https://github.com/facebookresearch/video-nonlocal-net 非局部神经网络 motivation:受计算机视觉中经典的非局部均值方法[4]的启发&#xff0c;非局部操作将位置的响应计算为所有位置的特征的加权和。 非局部均值方法 NLM&#…

用keras识别狗狗

一、需求场景 从照片从识别出狗狗 from keras.applications.resnet50 import ResNet50 from keras.preprocessing import image from keras.applications.resnet50 import preprocess_input, decode_predictions import numpy as np# 加载预训练的ResNet50模型 model ResNet5…

Flask-HTTP请求、响应、上下文、进阶实验

本节主要目录如下&#xff1a; 一、请求响应循环 二、HTTP请求 2.1、请求报文 2.2、Request对象 2.3、在Flask中处理请求 2.4、请求钩子 三、HTTP响应 3.1、响应报文 3.2、在Flask中生成响应 3.3、响应格式 3.4、Cookie 3.5、session&#xff1a;安全的Cookie 四、…

【仪酷LabVIEW AI工具包案例】使用LabVIEW AI工具包+YOLOv5结合Dobot机械臂实现智能垃圾分类

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f384;所属专栏&#xff1a;『仪酷LabVIEW AI工具包案例』 &#x1f4d1;上期文章&#xff1a;『【YOLOv9】实战二&#xff1a;手把手教你使用TensorRT实现YOLOv…

数据结构学习——线性表、顺序表

1.线性表 线性表 &#xff08; linear list &#xff09; 是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构&#xff0c;也就说是连续的一…

项目管理-项目资源管理2/2

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 资源管理&#xff1a;6个过程“硅谷火箭管控” ①规划资源管理&#xff1a; 写计划 ②估算活动资源&#xff1a;估算团队资源&…

渗透之sql盲注(时间/boolean盲注)

sql盲注&#xff1a;sql盲注意思是我们并不能在web页面中看到具体的信息&#xff0c;我们只能通过输入的语句的真假来判断。从而拿到我们想要的信息。 我们通常使用ascii值来进行盲注。 目录 手动注入&#xff1a; 时间盲注&#xff1a; 布尔盲注&#xff1a; python脚本注…

LabVIEW波浪发电平台浮筒取能效率数据采集系统

LabVIEW波浪发电平台浮筒取能效率数据采集系统 随着化石能源的逐渐减少以及能源价格的上升&#xff0c;寻找可替代的、可再生的、清洁的能源成为了世界各国的共识。波浪能作为一种重要的海洋能源&#xff0c;因其巨大的潜力和清洁性&#xff0c;近年来受到了广泛关注。开发了一…

(六)JSP教程——out对象

out对象是在JSP中经常使用到的对象&#xff0c;它本质上是一个输出流&#xff0c;前面已经多次使用&#xff0c;我们经常使用它的print()和println()方法&#xff0c;这些方法主要用于实现客户端数据的输出。通过out对象也可以直接向客户端发送一个由程序动态生成的HTML文件。 …

Docker-Compose 容器集群的快速编排

Docker-compose 简介 Docker-Compose项目是Docker官方的开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层&#xff0c;分别是 工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&#xff09;以及容器&…

JavaEE企业级开发中常用的JDK7和JDK8的时间类

JDK7时间类 全世界的时间有一个统一的计算标准 在同一条经线上的时间是一样的 格林威治时间 简称GMT 计算核心 地球自转一天是24小时 太阳直射正好是12小时 但是误差太大 现在用原子钟来代替 用铯原子震动的频率来计算时间&#xff0c;作为世界的标准时间UTC 中国标准时间…

在国企分公司做信息宣传新闻投稿的经验分享

作为一名国企分公司的信息宣传工作者,我亲历了从传统投稿方式到数字化转型的全过程,这段经历既充满了挑战,也收获了成长。回首最初的日子,那些用邮箱投稿的时光,至今仍让我感慨万千。 初尝辛酸,邮箱投稿的艰难岁月 刚接手信息宣传工作时,我满腔热情,却很快被现实的冷水浇了个透…

c语言实现贪吃蛇小游戏————附全代码!!!

目录 1.Win32 API 1.1控制台应用程序 1.2控制台的名称&#xff0c;控制台窗口大小 1.3设置控制台光标位置 COORD - 光标坐标 GetStdHandle - 获取句柄 SetConsoleCursorPosition - 设置光标位置 封装一个设置光标的函数 1.4设置控制台光标的属性 CONSOLE_CURSOR_INFO …

栈PART 1

目录 1. 栈 1.1 栈的概念和结构 1.2 栈的实现 1.2.1 栈的顺序储存结构 1.2.2 栈的基本操作 1.3 有效的括号 1. 栈 1.1 栈的概念和结构 堆栈又名栈&#xff08;stack&#xff09;&#xff0c;它是一种运算受限的线性表。 限定仅在表尾进行插入和删除操作的线性表。这一端…

C++进阶之路:深入理解编程范式,从面向过程到面向对象(类与对象_上篇)

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

java-函数式编程-语法

目录 1、函数表现形式 分类 lambda表达式 参数类型可以全写&#xff0c;也可以全不写&#xff0c;但不能一部分写&#xff0c;一部分不写lambda 的省略策略&#xff1a;凡是可推导&#xff0c;都可以省略 方法引用 练习-判断语法正确性 练习-写出与方法引用等价的lambda表达式…

TCP三次握手四次挥手 UDP

TCP是面向链接的协议&#xff0c;而UDP是无连接的协议 TCP的三次握手 三次传输过程是纯粹的不涉及数据&#xff0c;三次握手的几个数据包中不包含数据内容。它的应用层&#xff0c;数据部分是空的&#xff0c;只是TCP实现会话建立&#xff0c;点到点的连接 TCP的四次挥手 第四…

VMware虚拟机提示内存不足

VMware虚拟机&#xff0c;k8s集群搭建内存不足的问题 疑问&#xff1a;我的电脑是8G8G双通道的内存&#xff0c;当我在搭建k8s集群时给master-2G内存&#xff0c;node1-3G内存&#xff0c;node2-3G内存&#xff1b; 当依次打开虚拟机到node2时VM提示“物理内存不足&#xff0c;…