智能家居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(); // 初始化oled
  face_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;
  }
  else
     pthread_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_create



int 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.mfbz.cn/a/604397.html

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

相关文章

渐进淡出背景个人导航页源码(火影版)

渐进淡出背景个人导航页源码&#xff08;火影版&#xff09; 效果图部分源码领取源码下期更新预报 效果图 部分源码 <!DOCTYPE html> <html> <head> <!--小K网 www.xkwo.com --><meta charset"UTF-8"><title>火影版个人主页<…

如果出现一个工具,可以让前端开发彻底不用再手写UI,这个工具意义大吗?干货!

求这样的一个工具&#xff0c;可以让后端开发、嵌入式开发、产品经理、UI设计师都能用&#xff0c;注意&#xff0c;不是在一个简单的静态页生成&#xff0c;也不是类似飞冰那种 generator &#xff0c;而是真正让设计师和开发者在各自的那侧达成自治&#xff0c;可以做到吗&am…

异构图神经网络——Heterogeneous Graph Neural Networks

相关代码见文末 1.回顾同构图 1.1 GNN GNN基本计算方法——邻接矩阵乘以节点,聚合相邻节点的特征,得到本节点的特征表达 1.2 Graph Attention Network 引入图注意力,实现边的权重可学习,最简单的方法是,将两个节点的特征进行拼接,使用一组可学习的权重参数映射为边的权…

搜狗输入法 PC端 v14.4.0.9307 去广告绿化版.

软件介绍 搜狗拼音输入法作为众多用户计算机配置的必备工具&#xff0c;其功能的全面性已为众所周知&#xff0c;并且以其高效便捷的输入体验受到广大使用者的青睐。然而&#xff0c;该软件在提供便利的同时&#xff0c;其内置的广告元素常常为用户带来一定的干扰。为此&#…

游戏理解入门:Rust+Bracket开发一个小游戏

1. Game loop 使用game loop可以使得游戏运行更加流畅和顺滑&#xff0c;它可以&#xff1a; 初始化窗口、图形和其他资源&#xff1b;每当屏幕刷新他都会运行(通常是每秒30,60 )&#xff1b;每次通过循环&#xff0c;他都会调用游戏的tick()函数。 大致的原理流程如下&…

利用生成式AI重新构想ITSM的未来

对注入 AI 的生成式 ITSM 的需求&#xff0c;在 2023 年 Gartner AI 炒作周期中&#xff0c;生成式 AI 达到预期值达到顶峰后&#xff0c;三分之二的企业已经将生成式 AI 集成到其流程中。 你问为什么这种追求&#xff1f;在预定义算法的驱动下&#xff0c;IT 服务交付和管理中…

又发现一个ai生成音乐的网站-heymusic

网址 https://heymusic.ai/ 尴尬&#xff0c;不挂梯子能登录进来&#xff0c;但是谷歌账号注册不了&#xff0c;刷新了几遍也没注册上。 看了下价格&#xff0c;应该不是免费的&#xff0c;所以也没了试用的兴趣。 我也不想用别的邮箱注册了&#xff0c;所以只能简单的水一…

固定资产管理系统参考论文(论文 + 源码)

【免费】固定资产管理系统.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89282536 固定资产管理系统 摘 要 随着计算机信息技术的发展以及对资产、设备的管理科学化、合理化的高要求&#xff0c;利用计算机实现设备及资产的信息化管理已经显得非常重要。 固…

IO 5.8日

1&#xff1a;使用 dup2 实现错误日志功能 使用 write 和 read 实现文件的拷贝功能&#xff0c;注意&#xff0c;代码中所有函数后面&#xff0c;紧跟perror输出错误信息&#xff0c;要求这些错误信息重定向到错误日志 err.txt 中去 2&#xff1a;判断一个文件是否拥有用户可写…

LeetCode509:斐波那契数(使用动态规划)

题目描述 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 n > 1…

BFS专题——FloodFill算法:200.岛屿数量

文章目录 题目描述算法原理代码实现CJava 题目描述 题目链接&#xff1a;200.岛屿数量 PS:注意题目中每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。也就是说斜角是不算了&#xff0c; 例如示例二&#xff0c;是三个岛屿。 算法原理 这道题目是 DFS&#xff0…

三维天地助力实验室质量管理工作无纸化、流程化、标准化

质量管理是实验室日常管理工作中的重点内容,目前大多数实验室信息化的方向还是以实验主流程向无纸化转变为主,质量管理工作仍然依靠线下纸质文件或者线上登记台账的方式进行,这种方式存在任务流转效率低、资源浪费等问题,此外历史数据难以保存也是实验室管理人员的一大痛点。 …

【Android】Room数据库的简单使用方法

Room数据库的使用方法 目录 1、添加Room数据库的依赖2、Entity——定义实体类 2.1 定义主键——PrimaryKey2.2 字段注解——ColumnInfo 3、Dao——定义数据访问对象4、Database——数据库 4.1 通过回调观察数据库是否创建成功 5、使用时注意点6、编写异步 DAO 查询 6.1 写异步…

24_Scala集合Map

文章目录 Scala集合Map1.构建Map2.增删改查3.Map的get操作细节 Scala集合Map –默认immutable –概念和Java一致 1.构建Map –创建kv键值对 && kv键值对的表达 –创建immutable map –创建mutable map //1.1 构建一个kv键值对 val kv "a" -> 1 print…

Java IO流(二)

1. 缓冲流 1.1 字节缓冲流概述 当对文件或其他数据源进行频繁的读/写操作时&#xff0c;效率比较低&#xff0c;这时如果使用缓存流就能够更高效地读/写信息。 比如&#xff0c;可以使用缓冲输出流来一次性批量写出若干数据减少写出次数来提高写出效率。 如果用生活中的例子做…

多模态EDA论文小记

论文地址 该论文主要改进点是&#xff1a;通过动态化局部搜索中每个集群大小&#xff0c;高斯和柯西分布共同产生个体。总的来说改进点不多&#xff0c;当然也可能是笔者还没发现。 局部搜索 划分集群 划分集群有两个策略分别是&#xff1a; 随机生成一个点作为中心点&…

什么软件可以把视频合并在一起?6个软件教你快速进行视频编辑

什么软件可以把视频合并在一起&#xff1f;6个软件教你快速进行视频编辑 当你需要对视频进行编辑和合并时&#xff0c;选择合适的软件可以极大地提高工作效率和编辑质量。以下是六款被广泛认可且功能强大的视频编辑软件&#xff0c;它们可以帮助你快速、高效地进行视频编辑和合…

PDF转word转ppt软件

下载地址&#xff1a;PDF转word转ppt软件.zip 平时工作生活经常要用到PDF转word转ppt软件&#xff0c;电脑自带的又要开会员啥的很麻烦&#xff0c;现在分享这款软件直接激活就可以免费使用了&#xff0c;超级好用&#xff0c;喜欢的可以下载

C++从入门到精通---模版

文章目录 泛型编程函数模版模版参数的匹配原则类模版类模版的定义格式类模版的实例化 总结 泛型编程 泛型编程是一种编程范式&#xff0c;旨在实现通用性和灵活性。它允许在编写代码时使用参数化类型&#xff0c;而不是具体的类型&#xff0c;从而使代码更加灵活和可重用。 在…

NodeMCU ESP8266 操作 SSD1306 OLED显示屏详解(图文并茂)

文章目录 1 模块介绍2 接线介绍3 安装SSD1306驱动库4 源码分析4.1 硬件兼容性4.2 可能存在的问题总结1 模块介绍 我们将在本教程中使用的OLED显示屏是SSD1306型号:单色0.96英寸显示屏,像素为12864,如下图所示。 OLED显示屏不需要背光,这在黑暗环境中会产生非常好的对比度。…
最新文章