家庭网络做网站,wordpress制作网站步骤,网络规划与设计开题报告,什么网站可以学习建设工程法律实践系统框图 前情提要:
智能家居1 -- 实现语音模块-CSDN博客
智能家居2 -- 实现网络控制模块-CSDN博客
智能家居3 - 实现烟雾报警模块-CSDN博客
智能家居4 -- 添加接收消息的初步处理-CSDN博客
智能家居5 - 实现处理线程-CSDN博客
智能家居6 -- 配置 ini文件优化设备添加-CS…
系统框图 前情提要:
智能家居1 -- 实现语音模块-CSDN博客
智能家居2 -- 实现网络控制模块-CSDN博客
智能家居3 - 实现烟雾报警模块-CSDN博客
智能家居4 -- 添加接收消息的初步处理-CSDN博客
智能家居5 - 实现处理线程-CSDN博客
智能家居6 -- 配置 ini文件优化设备添加-CSDN博客 实现主要程序: 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 i0;inode_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 i0;inode_num;i){pthread_join(tid[i],NULL);}for(int i0;inode_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;
} 语言控制模块 - voice_interface.c #if 0
struct control
{
char control_name[128]; //监听模块名称
int (*init)(void); //初始化函数
void (*final)(void);//结束释放函数
void *(*get)(void *arg);//监听函数如语音监听
void *(*set)(void *arg); //设置函数如语音播报
struct control *next;
};
#endif#include pthread.h
#include stdio.h
#include voice_interface.h
#include mq_queue.h
#include uartTool.h
#include global.hstatic int serial_fd -1; // static 这个 变量只在当前文件有效static int voice_init(void )
{serial_fd myserialOpen(SERIAL_DEV,BAUD); // 初始化并且打开串口printf(%s|%s|%d serial_fd %d\n,__FILE__,__func__,__LINE__,serial_fd);return serial_fd;
}static void voice_final(void)
{if(-1 ! serial_fd) // 打开串口成功{close(serial_fd); // 关闭我们打开的串口serial_fd -1; // 复位}
}
// 接收语言指令
static void* voice_get(void *arg)// mqd 通过arg 传参获得
{int len 0;mqd_t mqd -1;ctrl_info_t * ctrl_info NULL; if(NULL ! arg)ctrl_info (ctrl_info_t*)arg;unsigned char buffer[6] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // 初始化 bufferif (-1 serial_fd){//打开串口serial_fd voice_init();// 尝试打开串口if (-1 serial_fd){ //还是打开失败printf(%s | %s | %d:open serial failed\n, __FILE__, __func__, __LINE__); // 三个宏的含义: 文件名 - main.c,函数名 - pget_voice ,行号 - 138pthread_exit(0); } // 串口打开失败 --退出}mqd ctrl_info-mqd; if((mqd_t)-1 mqd){pthread_exit(0); }pthread_detach(pthread_self());// 与父线程分离printf(%s thread start\n,__func__);while (1){len serialGetstring(serial_fd, buffer); // 通过串口获得语言输入printf(%s|%s|%d, 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:len %d\n,__FILE__,__func__,__LINE__,len);if (len 0) // 判断是否 接到识别指令{if(buffer[0] 0xAA buffer[1] 0x55 buffer[4]0x55 buffer[5]0xAA){printf(%s|%s|%d, send: 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]);send_msg(mqd,buffer,len); // 注意获取len长度不能使用strlen() -- 0x00 会识别为截止位--只能读取到三个字节(但不是我们实际的截止位(0x55 0xAA ))}memset(buffer,0,sizeof(buffer)); // 复位buffer}}pthread_exit(0);}
// 语音播报static void* voice_set(void *arg)
{pthread_detach(pthread_self());// 与父线程分离unsigned char *buffer (unsigned char*)arg;if (-1 serial_fd){//打开串口serial_fd voice_init();// 尝试打开串口if (-1 serial_fd){ //还是打开失败printf(%s | %s | %d:open serial failed\n, __FILE__, __func__, __LINE__); // 三个宏的含义: 文件名 - main.c,函数名 - pget_voice ,行号 - 138pthread_exit(0); } // 串口打开失败 --退出}if(NULL ! buffer){ // 接收到数据serialSendstring(serial_fd,buffer,6); // 向串口发送接收到的数据// 语言模块识别到串口发送的数据后就进行相应的语言输出 }pthread_exit(0);
}struct control voice_control {.control_name voice,.init voice_init,.final voice_final,.get voice_get,.set voice_set,.next NULL
};struct control *add_voice_to_ctrl_list(struct control *phead)
{//头插法实现 添加链表节点return add_interface_to_ctrl_list(phead,voice_control);}; 网络控制模块 - socket_interface.c
#include pthread.h#include socket_interface.h
#include control.h
#include socket.h
#include mq_queue.h
#include global.h
#include netinet/tcp.h // 设置 tcp 心跳 的参数static int s_fd -1;static int tcpsocket_init(void)
{s_fd socket_init(IPADDR,IPPORT);//return s_fd;return -1;
}static void tcpsocket_final(void)
{close(s_fd);s_fd -1;
}static void* tcpsocket_get(void *arg)
{int c_fd -1;unsigned char buffer[BUF_SIZE];int ret -1;struct sockaddr_in c_addr;mqd_t mqd -1;ctrl_info_t * ctrl_info NULL; int keepalive 1; // 开启TCP_KEEPALIVE选项int keepidle 10; // 设置探测时间间隔为10秒int keepinterval 5; // 设置探测包发送间隔为5秒int keepcount 3; // 设置探测包发送次数为3次pthread_detach(pthread_self()); // 和主线程(他的父线程)分离printf(%s|%s|%d s_fd %d\n, __FILE__, __func__, __LINE__, s_fd);if(-1 s_fd) // 判断是否初始化成功{s_fd tcpsocket_init();if(-1 s_fd){printf(tcpsocket_init error\n);pthread_exit(0);}}if(NULL ! arg)ctrl_info (ctrl_info_t*)arg;if(NULL ! ctrl_info)mqd ctrl_info-mqd; if((mqd_t)-1 mqd){pthread_exit(0); }memset(c_addr, 0, sizeof(struct sockaddr_in));int clen sizeof(struct sockaddr_in);printf(%s thread start\n, __func__);while (1) // 一直等待接收{c_fd accept(s_fd, (struct sockaddr *)c_addr, clen); // 获得新的客户端 描述符if (c_fd -1){continue;}ret setsockopt(c_fd, SOL_SOCKET, SO_KEEPALIVE, (void *)keepalive,sizeof(keepalive));if(-1 ret){perror(setsockopt);break;}ret setsockopt(c_fd, IPPROTO_TCP, TCP_KEEPIDLE, (void *)keepidle, sizeof(keepidle));if(-1 ret){perror(setsockopt);break;}ret setsockopt(c_fd, IPPROTO_TCP, TCP_KEEPINTVL, keepinterval,sizeof(keepinterval));if(-1 ret){perror(setsockopt);break;}ret setsockopt(c_fd, IPPROTO_TCP, TCP_KEEPCNT, keepcount,sizeof(keepcount)); if(-1 ret){perror(setsockopt);break;}// 打印调试信息printf(%s | %s | %d: Access a connection from %s:%d\n, __FILE__, __func__, __LINE__, inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port));while (1){memset(buffer, 0, BUF_SIZE);ret recv(c_fd, buffer, BUF_SIZE, 0); // 等待接收// 将接收到数据打印出来printf(%s|%s|%d, 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]);if (ret 0){if(buffer[0] 0xAA buffer[1] 0x55 buffer[4]0x55 buffer[5]0xAA){printf(%s|%s|%d, send: 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]);send_msg(mqd,buffer,ret); }}else if (0 ret || -1 ret) // 没读到or 读到空{break;}}}pthread_exit(0);}struct control tcpsocket_control {.control_name tcpsocket,.init tcpsocket_init,.final tcpsocket_final,.get tcpsocket_get,.set NULL, //不需要实现 设置.next NULL
};struct control *add_tcpsocket_to_ctrl_list(struct control *phead)
{//头插法实现 添加链表节点return add_interface_to_ctrl_list(phead,tcpsocket_control);};
烟雾报警模块 - smoke_interfac.c #include pthread.h
#include wiringPi.h
#include stdio.h#include smoke_interface.h
#include control.h
#include mq_queue.h
#include global.h
#include netinet/tcp.h // 设置 tcp 心跳 的参数#define SMOKE_PIN 6 // 烟雾报警模块接的引脚
#define SMOKE_MODE INPUTstatic int s_fd -1;static int smoke_init(void)
{printf(%s|%s|%d\n,__FILE__,__func__,__LINE__);pinMode(SMOKE_PIN, SMOKE_MODE); // 引脚 和 模式配置return 0;
}static void smoke_final(void)
{// do nothing
}static void* smoke_get(void *arg)
{// AA 55 45 00 55 AA -- 45 00 --触发警报int status HIGH; //低电平有效 -- 默认设置为高电平int switch_status 0; // 报警开关 -- 默认设置为不开 -- 0ssize_t byte_send -1;unsigned char buffer[6] {0xAA,0x55,0x00,0x00,0x55,0xAA};mqd_t mqd -1;ctrl_info_t * ctrl_info NULL; if(NULL ! arg)ctrl_info (ctrl_info_t*)arg;if(NULL ! ctrl_info)mqd ctrl_info-mqd; if((mqd_t)-1 mqd){pthread_exit(0); }pthread_detach(pthread_self()); // 父子线程分离printf(%s thread start.\n,__func__);while(1){status digitalRead(SMOKE_PIN); // 读取当前引脚状态if(LOW status) // 探测到烟雾 -- 发生报警{switch_status 1; // 打开报警器开关buffer[2] 0x45;buffer[3] 0x00;// 低电平触发警报 --//蜂鸣器是低电平触发 -- 我们这里把buffer 修改得与beep匹配方便与他产生联系printf(%s|%s|%d, 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]);byte_send mq_send(mqd, buffer, 6,0); // 向消息队列里面发送数据 -- 接收到后语言模块会识别播报 - 火灾警报if (-1 byte_send){continue;}}else if(HIGH status 1 switch_status) // 未探测到烟雾并且报警器开关还没关闭 -- 关闭报警器开关{switch_status 0; // 关闭报警器开关buffer[2] 0x45;buffer[3] 0x01;//警报结束printf(%s|%s|%d, 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]);byte_send mq_send(mqd, buffer, 6,0);if (-1 byte_send){continue;}}sleep(5);}pthread_exit(0); // 退出线程
}struct control smoke_control {.control_name smoke,.init smoke_init,.final smoke_final,.get smoke_get,.set NULL, //不需要实现 设置.next NULL
};struct control *add_smoke_to_ctrl_list(struct control *phead)
{return add_interface_to_ctrl_list(phead,smoke_control);}接收处理线程 - receive_interface.c #include pthread.h
#include mqueue.h
#include string.h
#include errno.h
#include stdlib.h
#include stdio.h
#include wiringPi.h#include receive_interface.h
#include control.h
#include mq_queue.h
#include global.h
#include face.h
#include myoled.h
//#include lrled_gdevice.h
#include gdevice.h
// #include fan_gdevice.h
// #include bled_gdevice.h
// #include beep_gdevice.h
// #include lock_gdevice.h#include ini.h
#include face.h#define MATCH(s, n) strcmp(section, s) 0 strcmp(name, n) 0/*
接收模块:
对接收到消息做出相应处理
包括 oled 人脸识别 语言播报 GPIO 引脚状态配置*/static int oled_fd -1;
static struct gdevice *pdevhead NULL;typedef struct
{int msg_len;unsigned char *buffer;ctrl_info_t *ctrl_info;
} recv_msg_t;static int handler_gdevice(void *user, const char *section, const char *name, const char *value)
{struct gdevice *pdev NULL;if (NULL pdevhead){pdevhead (struct gdevice *)malloc(sizeof(struct gdevice));memset(pdevhead, 0, sizeof(struct gdevice));pdevhead-next NULL;strcpy(pdevhead-dev_name, section);}// printf(section %s, name %s, value %s\n, section, name, value);else if (0 ! strcmp(section, pdevhead-dev_name)) // 当section对不上的时候表示到了下一个设备{// 把新节点(设备)使用头插法插入pdev (struct gdevice *)malloc(sizeof(struct gdevice));memset(pdev, 0, sizeof(struct gdevice));strcpy(pdev-dev_name, section);pdev-next pdevhead;pdevhead pdev;}if (NULL ! pdevhead){if (MATCH(pdevhead-dev_name, key)){sscanf(value, %x, pdevhead-key); // 把value(string)的值 转为int类型 16进行格式 传递给 pdevhead-key)printf(%d pdevhead-key 0x%x\n, __LINE__, pdevhead-key);}else if (MATCH(pdevhead-dev_name, gpio_pin)){pdevhead-gpio_pin atoi(value);}else if (MATCH(pdevhead-dev_name, gpio_mode)){if (strcmp(value, OUTPUT) 0){pdevhead-gpio_mode OUTPUT;}else if (strcmp(value, INPUT) 0){pdevhead-gpio_mode INPUT;}else{printf(gpio_mode error\n);}}else if (MATCH(pdevhead-dev_name, gpio_status)){if (strcmp(value, LOW) 0){pdevhead-gpio_mode LOW;}else if (strcmp(value, HIGH) 0){pdevhead-gpio_mode HIGH;}else{printf(gpio_status error\n);}}else if (MATCH(pdevhead-dev_name, check_face_status)){pdevhead-check_face_status atoi(value);}else if (MATCH(pdevhead-dev_name, voice_set_status)){pdevhead-voice_set_status atoi(value);}}return 1;
}static int receive_init(void)
{// pdevhead add_lrled_to_gdevice_list(pdevhead); // 头插法加入 客厅灯// pdevhead add_bled_to_gdevice_list(pdevhead); // 加入卧室灯// pdevhead add_fan_to_gdevice_list(pdevhead); // 加入风扇// pdevhead add_beep_to_gdevice_list(pdevhead); // 蜂鸣器// pdevhead add_lock_to_gdevice_list(pdevhead); // 开锁if (ini_parse(/etc/gdevice.ini, handler_gdevice, NULL) 0) {printf(Cant load gdevice.ini\n);return 1;}struct gdevice *pdev NULL;pdev pdevhead;while (pdev ! NULL){// printf(inside %d,__LINE__);printf(dev_name:%s\n, pdev-dev_name);printf(key:%x\n, pdev-key);printf(gpio_pin:%d\n, pdev-gpio_pin);printf(gpio_mode:%d\n, pdev-gpio_mode);printf(gpio_status:%d\n, pdev-gpio_status);printf(check_face_status:%d\n, pdev-check_face_status);printf(voice_set_status:%d\n, pdev-voice_set_status);pdev pdev-next;}// 设备类链表添加oled_fd myoled_init(); // 初始化oledface_init(); // 初始化人脸识别return oled_fd;
}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;struct gdevice *cur_gdev NULL;char success_or_failed[20] success;pthread_t tid -1;int smoke_status 0;double face_result 0.0; //存放人脸匹配度int ret -1;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 somethingif (NULL ! recv_msg NULL ! recv_msg-buffer) // if 消息队列非空并且buffer 里面接收到数据{// recv_msg-buffer[2] -- 第三位 用于存放设备类型cur_gdev find_device_by_key(pdevhead, recv_msg-buffer[2]);printf(%s|%s|%d,find success buffer[2] 0x%x \n, __FILE__, __func__, __LINE__, recv_msg-buffer[2]);}if (NULL ! cur_gdev) // if 能找到的这设备 -- 设备存在{printf(%s|%s|%d, cur_gdev \n, __FILE__, __func__, __LINE__);// BUFFER 的第四个参数 用于 存放开关状态 0 表示开 1 表示关cur_gdev-gpio_status recv_msg-buffer[3] 0 ? LOW : HIGH; // 获取状态存入cur_gdev中//人脸识别if(1 cur_gdev-check_face_status){face_result face_status(); //得到人脸识别的匹配度if(face_result 0.6){ //匹配成功ret set_gpio_device_status(cur_gdev); // 设置电平 -- 开锁recv_msg-buffer[2] 0x47; //识别成功的语音播报}else{recv_msg-buffer[2] 0x46;}}else if( 0 cur_gdev-check_face_status){// printf(%s|%s|%d,Set before set_gpio_device_status\n,__FILE__,__func__,__LINE__);ret set_gpio_device_status(cur_gdev); // 将获取到的状态真正赋值给引脚// printf(%s|%s|%d, after set_gpio_device_status \n,__FILE__,__func__,__LINE__);}printf(%s|%s|%d, %d\n, __FILE__, __func__, __LINE__,cur_gdev-voice_set_status);// 需要语言播报if (1 cur_gdev-voice_set_status) {printf(%s|%s|%d,2\n, __FILE__, __func__, __LINE__);if (NULL ! recv_msg NULL ! recv_msg-ctrl_info NULL ! recv_msg-ctrl_info-ctrl_phead){printf(%s|%s|%d,2\n, __FILE__, __func__, __LINE__);struct control *pcontrol recv_msg-ctrl_info-ctrl_phead;while (NULL ! pcontrol){if (strstr(pcontrol-control_name, voice)) //匹配到语言播报{if (0x45 recv_msg-buffer[2] 0 recv_msg-buffer[3]) // 语音播报 打开{smoke_status 1;}pthread_create(tid, NULL, pcontrol-set, (void *)recv_msg-buffer); // 新开线程区进行语言播报break;}pcontrol pcontrol-next;}}}printf(%s|%s|%d,2\n, __FILE__, __func__, __LINE__);if (-1 ret) // 设置失败{printf(%s|%s|%d,2\n, __FILE__, __func__, __LINE__);memset(success_or_failed, \0, sizeof(success_or_failed));strncpy(success_or_failed, failed, 6);}printf(%s|%s|%d,2\n, __FILE__, __func__, __LINE__);// 配置OLEDchar oled_msg[512];memset(oled_msg, 0, sizeof(oled_msg));char *change_status cur_gdev-gpio_status LOW ? Open : Close;sprintf(oled_msg, %s %s %s!\n, change_status, cur_gdev-dev_name, success_or_failed);if(smoke_status 1){memset(oled_msg, 0, sizeof(oled_msg));sprintf(oled_msg, A risk of fire!\n);} myoled_show(oled_msg);//让门打开5s自动关闭if(1 cur_gdev-check_face_status 0 ret face_result 0.6){sleep(5); //开门5s后关门cur_gdev-gpio_status HIGH; //设置高电平(低电平有效)ret set_gpio_device_status(cur_gdev); //关门}}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);
};编译运行 环境配置:
// 我们人脸识别开门模块调用了阿里云的sdk请确保arm设上已经安装了对应SDK和阿里云服务配置请去这里安装指示配置(按照指示下载SDK添加阿里云AccessKey)
人脸识别_身份验证识别_客流分析系统_人脸门禁闸机-阿里云 (aliyun.com) 编译
由于文件众多我们采用Makefile来编译
Makefile
CC : aarch64-linux-gnu-gccSRC : $(shell find src -name *.c)INC : ./inc \./3rd/usr/local/include \./3rd/usr/include \./3rd/usr/include/python3.10 \./3rd/usr/include/aarch64-linux-gnu/python3.10 \./3rd/usr/include/aarch64-linux-gnuOBJ : $(subst src/,obj/,$(SRC:.c.o))TARGETobj/smarthomeCFLAGS : $(foreach item, $(INC),-I$(item)) # -I./inc -I./3rd/usr/local/includeLIBS_PATH : ./3rd/usr/local/lib \./3rd/lib/aarch64-linux-gnu \./3rd/usr/lib/aarch64-linux-gnu \./3rd/usr/lib/python3.10 \
#L
LDFLAGS : $(foreach item, $(LIBS_PATH),-L$(item)) # -L./3rd/usr/local/libsLIBS : -lwiringPi -lpython3.10 -pthread -lexpat -lz -lcryptobj/%.o:src/%.cmkdir -p obj$(CC) -o $ -c $ $(CFLAGS)$(TARGET) :$(OBJ)$(CC) -o $ $^ $(CFLAGS) $(LDFLAGS) $(LIBS)scp obj/smarthome ini/gdevice.ini orangepi192.168.1.18:/home/orangepicompile : $(TARGET)clean:rm $(TARGET) obj $(OBJ) -rf
debug:echo $(CC)echo $(SRC)echo $(INC)echo $(OBJ)echo $(TARGET)echo $(CFLAGS)echo $(LDFLAGS)echo $(LIBS).PHONY: clean compile debug 可以看到我的Makefile 里面添加了scp传送请根据自己的派的ip进行修改 运行: sudo -E ./smarthome sudo -- 因为我们调用了wiringpi库来调节电平需要访问到系统文件
-E 保持环境即我们可以使用root用户里面配置的AccessKey来访问阿里云的接口 文章转载自: http://www.morning.gczzm.cn.gov.cn.gczzm.cn http://www.morning.ddqdl.cn.gov.cn.ddqdl.cn http://www.morning.wdprz.cn.gov.cn.wdprz.cn http://www.morning.xxlz.cn.gov.cn.xxlz.cn http://www.morning.fkdts.cn.gov.cn.fkdts.cn http://www.morning.bzqnp.cn.gov.cn.bzqnp.cn http://www.morning.ngqty.cn.gov.cn.ngqty.cn http://www.morning.dmhs.cn.gov.cn.dmhs.cn http://www.morning.hcwlq.cn.gov.cn.hcwlq.cn http://www.morning.ydnxm.cn.gov.cn.ydnxm.cn http://www.morning.mnkhk.cn.gov.cn.mnkhk.cn http://www.morning.wsjnr.cn.gov.cn.wsjnr.cn http://www.morning.fwlch.cn.gov.cn.fwlch.cn http://www.morning.mnwmj.cn.gov.cn.mnwmj.cn http://www.morning.qcfcz.cn.gov.cn.qcfcz.cn http://www.morning.pbxkk.cn.gov.cn.pbxkk.cn http://www.morning.ybmp.cn.gov.cn.ybmp.cn http://www.morning.jybj.cn.gov.cn.jybj.cn http://www.morning.zkjqj.cn.gov.cn.zkjqj.cn http://www.morning.sskhm.cn.gov.cn.sskhm.cn http://www.morning.wbqk.cn.gov.cn.wbqk.cn http://www.morning.wnnfh.cn.gov.cn.wnnfh.cn http://www.morning.jqkrt.cn.gov.cn.jqkrt.cn http://www.morning.yfmxn.cn.gov.cn.yfmxn.cn http://www.morning.kpnpd.cn.gov.cn.kpnpd.cn http://www.morning.nspbj.cn.gov.cn.nspbj.cn http://www.morning.jbkcs.cn.gov.cn.jbkcs.cn http://www.morning.wnhsw.cn.gov.cn.wnhsw.cn http://www.morning.zrks.cn.gov.cn.zrks.cn http://www.morning.trffl.cn.gov.cn.trffl.cn http://www.morning.yhwxn.cn.gov.cn.yhwxn.cn http://www.morning.lnnc.cn.gov.cn.lnnc.cn http://www.morning.mfrb.cn.gov.cn.mfrb.cn http://www.morning.kmqwp.cn.gov.cn.kmqwp.cn http://www.morning.tkchm.cn.gov.cn.tkchm.cn http://www.morning.kkjlz.cn.gov.cn.kkjlz.cn http://www.morning.cnlmp.cn.gov.cn.cnlmp.cn http://www.morning.rpljf.cn.gov.cn.rpljf.cn http://www.morning.fnssm.cn.gov.cn.fnssm.cn http://www.morning.crrjg.cn.gov.cn.crrjg.cn http://www.morning.qfnrx.cn.gov.cn.qfnrx.cn http://www.morning.bby45.cn.gov.cn.bby45.cn http://www.morning.qqhfc.cn.gov.cn.qqhfc.cn http://www.morning.cwpny.cn.gov.cn.cwpny.cn http://www.morning.zlxkp.cn.gov.cn.zlxkp.cn http://www.morning.qzpw.cn.gov.cn.qzpw.cn http://www.morning.mrfbp.cn.gov.cn.mrfbp.cn http://www.morning.rtpw.cn.gov.cn.rtpw.cn http://www.morning.kqrql.cn.gov.cn.kqrql.cn http://www.morning.mllmm.cn.gov.cn.mllmm.cn http://www.morning.ngdkn.cn.gov.cn.ngdkn.cn http://www.morning.qxjck.cn.gov.cn.qxjck.cn http://www.morning.jnbsx.cn.gov.cn.jnbsx.cn http://www.morning.kgrwh.cn.gov.cn.kgrwh.cn http://www.morning.qykxj.cn.gov.cn.qykxj.cn http://www.morning.blzrj.cn.gov.cn.blzrj.cn http://www.morning.jgzmr.cn.gov.cn.jgzmr.cn http://www.morning.nchlk.cn.gov.cn.nchlk.cn http://www.morning.lznfl.cn.gov.cn.lznfl.cn http://www.morning.nqbkb.cn.gov.cn.nqbkb.cn http://www.morning.sbkb.cn.gov.cn.sbkb.cn http://www.morning.bgxgq.cn.gov.cn.bgxgq.cn http://www.morning.jfch.cn.gov.cn.jfch.cn http://www.morning.rfwkn.cn.gov.cn.rfwkn.cn http://www.morning.dqrhz.cn.gov.cn.dqrhz.cn http://www.morning.iqcge.com.gov.cn.iqcge.com http://www.morning.cwrpd.cn.gov.cn.cwrpd.cn http://www.morning.mhmdx.cn.gov.cn.mhmdx.cn http://www.morning.qytby.cn.gov.cn.qytby.cn http://www.morning.xknsn.cn.gov.cn.xknsn.cn http://www.morning.mbmtn.cn.gov.cn.mbmtn.cn http://www.morning.xblrq.cn.gov.cn.xblrq.cn http://www.morning.wqkzf.cn.gov.cn.wqkzf.cn http://www.morning.rdzlh.cn.gov.cn.rdzlh.cn http://www.morning.lmqfq.cn.gov.cn.lmqfq.cn http://www.morning.pbzgj.cn.gov.cn.pbzgj.cn http://www.morning.lhxdq.cn.gov.cn.lhxdq.cn http://www.morning.pbsqr.cn.gov.cn.pbsqr.cn http://www.morning.nynlf.cn.gov.cn.nynlf.cn http://www.morning.cklld.cn.gov.cn.cklld.cn