智能家居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.mzph.cn/web/8518.shtml

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

相关文章

解放双手,利用自动点赞软件提高曝光度

在数字时代&#xff0c;社交媒体如同一片繁茂的森林&#xff0c;每一条动态、每一张照片都是树上挂着的果实&#xff0c;而点赞则仿佛是那些吸引眼球的色彩。在这个以流量为王的网络世界里&#xff0c;点赞数往往与内容的可见度直接相关&#xff0c;它不仅能够增加帖子的权重&a…

Codeforces Round 738 (Div. 2) D2. Mocha and Diana (Hard Version)

题目 思路&#xff1a; 性质1&#xff1a;能在结点u&#xff0c;v添加边的充要条件是u&#xff0c;v在第一个图和第二个图都不连通 性质2&#xff1a;可以添加的边数等于 n - 1 - max(m1, m2)&#xff0c;并且添加边的顺序不会影响结果&#xff08;即 边&#xff08;u&#x…

【25届秋招备战C++】23种设计模式

【25届秋招备战C】23种设计模式 一、简介程序员的两种思维8大设计原则 二、具体23种设计模式2.1 创建型模式2.2 结构性模式2.3 行为型模式 三、常考模式的实现四、参考 一、简介 从面向对象谈起&#xff0c; 程序员的两种思维 底层思维:向下 封装&#xff1a;隐藏内部实现 多…

DRF视图基类使用方法

【 一 】drf之请求 请求对象Request 【 0 】前言 ​ 在 Python 中&#xff0c;通常通过 request 对象来处理 HTTP 请求&#xff0c;尤其是在 web 开发中&#xff0c;比如使用 Django、Flask 等框架时会经常接触到这个对象。request 对象是框架提供的&#xff0c;用于封装客户…

【C++】二叉搜索树(手撕插入、删除、寻找)

一、什么是二叉搜索树 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值它的左…

hadoop学习---基于Hive的聊天数据分析报表可视化案例

背景介绍&#xff1a; 聊天平台每天都会有大量的用户在线&#xff0c;会出现大量的聊天数据&#xff0c;通过对聊天数据的统计分析&#xff0c;可以更好的对用户构建精准的用户画像&#xff0c;为用户提供更好的服务以及实现高ROI的平台运营推广&#xff0c;给公司的发展决策提…

C++:AVL树

概念&#xff1a; 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查 找元素相当于在顺序表中搜索元素&#xff0c;效率低下。 如图所示&#xff0c;搜索二叉树不能面对右边的树&#xff0c;这种极端的情况&#xf…

利用Github发现优质的学习项目网址

1. 直接搜索&#xff0c;star的数量越多的项目质量越高 2.Github Trending 地址: https://github.com/trending 3. Gitstar Ranking 地址: https://gistar-ranking.com/ 4. Awesome Topic 地址: https://github.com/topics/awesome

[附源码]秦时明月6.2魔改版_搭建架设教程_附GM工具_安卓苹果

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#xff0c;踩过的坑都给你们填上了 一. 演示视频 秦时明…

【电路笔记】-Twin-T振荡器

Twin-T振荡器 文章目录 Twin-T振荡器1、概述2、Twin-T振荡器3、Twin-T放大4、Twin-T 振荡器示例5、总结Twin-T 振荡器是另一种 RC 振荡器电路,它使用两个并联的 RC 网络来产生单一频率的正弦输出波形。 1、概述 Twin-T 振荡器是另一种类型的 RC 振荡器,它产生正弦波输出,用…

牛客 二叉树 NB1 牛群的最大高度

原题链接 就不采用, 递归的方式来做了, 自己弄个栈来做 用栈来保存路径, curr 表示当前的节点, pre 保留往回走时的上一步 如果是 用递归来做 它的栈链路是这样的, 可以做下参考 黄色表示返回 用栈模拟的话, 不可能模拟得一摸一样, 递归的话一个栈会经过3次, 第三次后就不…

医学论文摘要翻译 中译英哪里比较专业

论文摘要是对论文内容不加注释和评论的简短陈述&#xff0c;需要扼要说明论文的目的、研究方法和最终结论。在发表学术论文时&#xff0c;很多重要刊物会要求作者将文章的摘要翻译成英文。那么&#xff0c;针对医学论文摘要翻译&#xff0c;中译英哪里比较专业&#xff1f; 专…

【C++】详解STL容器之一的 vector

目录 概述 迭代器 数据结构 优点和缺点 接口介绍 begin end rbegin rend resize reseve insert erase 其他一些接口 模拟实现 框架 获取迭代器 深浅拷贝 赋值重载 reseve resize 拷贝构造 构造 析构 insert erase 其他 概述 vector是STL的容器之一。…

连接docker中的MySQL出现2058错误

出错场景&#xff1a;在虚拟机中用docker技术下载最新版本的MySQL&#xff0c;在本地电脑上连接发现出现2058错误。 解决方法&#xff1a; 按照以下步骤 1. 2. ALTER USER root% IDENTIFIED WITH mysql_native_password BY 自己MySQL的密码; 3.成功

redis--安装

简介 官网&#xff1a;RedisInsight - The Best Redis GUI 各个版本官网下载地址&#xff1a;http://download.redis.io/releases/ Redis和Memcached是非关系型数据库也称为NoSQL数据库&#xff0c;MySQL、Mariadb、SQL Server、PostgreSQL Oracle 数据库属于关系型数据 应用…

为什么选择ATECLOUD自动化测试平台?

在当今飞速发展的时代&#xff0c;一切都在不断进步与变革&#xff0c;电测行业也由手动测试逐步转向了自动化测试。但是随着科技的发展&#xff0c;对于产品的测试要求也越来越高&#xff0c;传统的自动化测试系统已经无法满足用户日益增长的测试需求&#xff0c;全新的ATE测试…

优化理论复习——(四)

无约束优化专题&#xff0c;主要使用了序列无约束极小化方法 无约束优化问题相关解法 最优性条件 互补松弛条件 对于一般约束优化问题&#xff1a; 整理一下就是著名的kkt条件&#xff1a; 这里只需要注意一点&#xff0c;那就是互补松弛条件只对不等式约束有限制。 然后是…

在全志H616核桃派开发板上实现超声波传感器测距

前言​ 超声波传感器是一款测量距离的传感器。其原理是利用声波在遇到障碍物反射接收结合声波在空气中传播的速度计算的得出。在测量、避障小车&#xff0c;无人驾驶等领域都有相关应用。 实验目的​ 通过python编程实现超声波传感器测距。 实验讲解​ 下图是一款市面上常…

【智能算法】雪消融优化算法(SAO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2023年&#xff0c;L Deng受到雪升华和融化行为启发&#xff0c;提出了雪消融优化算法&#xff08;Snow Ablation Optimizer, SAO&#xff09;。 2.算法原理 2.1算法思想 SAO模拟了雪的…

C语言,实现数字谱到简谱的转换(二)

C语言&#xff0c;实现数字谱到简谱的转换&#xff08;二&#xff09; 前言&#xff1a;本文初编辑于2024年5月8日 CSDN&#xff1a;https://blog.csdn.net/rvdgdsva 博客园&#xff1a;https://www.cnblogs.com/hassle 前言 结合前文使用 之前的程序默认C调4/4拍&#xff…