树莓派智能家居项目整合(包含语音、socket、火灾、摄像头线程)
树莓派智能家居项目一
- 1.百度网盘下载代码链接
- 2.main.c
- 3.段错误
- 4.C语言的函数声明
- 4.1没声明的报错内容
- 5.关于报错,调试程序
坎坎坷坷,墨墨迹迹了这么久也算是完成了四个线程的同时运行。记录下代码,也分享下学习过程中的问题。
1.百度网盘下载代码链接
点我下载代码
提取码: jtzn
2.main.c
这里放下main函数,其他的在百度网盘连接里可下载
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <wiringSerial.h>#include "contrlDevices.h"
#include "InputCommand.h"#define SWITCH1 21 //四盏灯对应的引脚
#define SWITCH2 22
#define SWITCH3 23
#define SWITCH4 24
#define SWITCH5 25 //火焰传感器对应的引脚struct InputCommander *pCommandHead = NULL; //指令控制工厂链表节点头
struct Devices *pdeviceHead = NULL; //设备工厂链表头节点
struct InputCommander *socketHandler = NULL; //网络控制线程执行的函数使用到的全局变量,在read_thread线程和socket_thread都使用到了int c_fd;struct Devices* findDeviceByName(char *name,struct Devices *phead) //根据名字寻找设备工厂链表链节函数,并返回链节
{struct Devices *tmp = phead;if(phead == NULL){return NULL;}else{while(tmp != NULL){if(strcmp(tmp->deviceName,name) == 0){return tmp;}tmp = tmp->next;}return NULL;}
}struct InputCommander* findCommandByName(char *name,struct InputCommander *phead) //根据名字寻找指令控制工厂链表链节函数,并返回链节
{struct InputCommander *tmp = phead;if(phead == NULL){return NULL;}else{while(tmp != NULL){if(strcmp(tmp->commandName,name) == 0){return tmp;}tmp = tmp->next;}return NULL;}
}void *fireAlarmThread(void *data) //“火灾报警器线程”执行的函数
{int status;struct Devices *firetmp = NULL;struct Devices *buztmp = NULL;firetmp = findDeviceByName("fireIfOrNot",pdeviceHead); //寻找“火焰传感器”链表节点,返回给firetmpbuztmp = findDeviceByName("beep",pdeviceHead); //寻找“蜂鸣器”链表节点,返回给buztmpwhile(1){status = firetmp->readStatus(firetmp->pinNum); //读取“火焰传感器”状态if(status == 0){ //检测到火焰或强光源buztmp->open(buztmp->pinNum); //打开蜂鸣器delay(1000); //延时1000毫秒=1秒}if(status == 1){ //未检测到火焰、强光源或解除警报buztmp->close(buztmp->pinNum); //关闭蜂鸣器}}
}void * voice_thread(void* datas) //语音线程
{struct InputCommander *voiceHandler; struct Devices *tmp = NULL;int nread;voiceHandler = findCommandByName("voice",pCommandHead); //找到语音节点if(voiceHandler == NULL){ //防止段错误printf("find voiceHandler error\n");pthread_exit(NULL); //线程里不用return}else{if(voiceHandler->Init(voiceHandler,NULL,NULL)<0){ //判断voice的fd是否正确printf("voice init error\n");pthread_exit(NULL);}else{printf("%s init success\n",voiceHandler->commandName);}while(1){nread = voiceHandler->getCommand(voiceHandler); //指令读在voiceHandler->command里面if(nread==0){printf("waiting....\n");}else{printf("do divece contrl:%s\n",voiceHandler->command);if(strstr(voiceHandler->command,"WZ") != NULL){ //一级指令,printf("shoudaoXP\n"); }else if(strstr(voiceHandler->command,"KYS") != NULL){ //对串口收到的指令进行分析,并执行对应的操作digitalWrite(SWITCH1,LOW);}else if(strstr(voiceHandler->command,"GYS") != NULL){digitalWrite(SWITCH1,HIGH);}else if(strstr(voiceHandler->command,"KCT") != NULL){digitalWrite(SWITCH2,LOW);}else if(strstr(voiceHandler->command,"GCT") != NULL){digitalWrite(SWITCH2,HIGH);}else if(strstr(voiceHandler->command,"KEL") != NULL){digitalWrite(SWITCH3,LOW);}else if(strstr(voiceHandler->command,"GEL") != NULL){digitalWrite(SWITCH3,HIGH);}else if(strstr(voiceHandler->command,"KWS") != NULL){digitalWrite(SWITCH4,LOW);}else if(strstr(voiceHandler->command,"GWS") != NULL){digitalWrite(SWITCH4,HIGH);}}memset(voiceHandler->command,'\0',sizeof(voiceHandler->command));}}}void *cameraThread_func(void* data)//起线程的函数有格式要求
{struct Devices *cameraTemp;cameraTemp = findDeviceByName("camera", pdeviceHead); //设备都要从工厂里面取出来if(cameraTemp == NULL){ //防止段错误的必需判断,当给指针赋值是,一定要考虑NULL的情况,否则后续操作都是空谈printf("find camera error\n");pthread_exit(NULL); //在线程中不用return}cameraTemp->justDoOnce(); //调用postUrl函数
}void * read_thread(void* datas)
{int n_read;while(1){memset(socketHandler->command,'\0', sizeof(socketHandler->command));n_read = read(c_fd,socketHandler->command,sizeof(socketHandler->command)); //从套接字中读取指令放在socketHandler->command中if(n_read == -1){perror("read");}else if(n_read>0){printf("\nget: %d,%s\n",n_read,socketHandler->command); //打印出指令字节数和指令if(strstr(socketHandler->command,"KYS") != NULL){ //对socket收到的指令进行分析,并执行对应的操作digitalWrite(SWITCH1,LOW);}if(strstr(socketHandler->command,"GYS") != NULL){digitalWrite(SWITCH1,HIGH);}if(strstr(socketHandler->command,"KCT") != NULL){digitalWrite(SWITCH2,LOW);}if(strstr(socketHandler->command,"GCT") != NULL){digitalWrite(SWITCH2,HIGH);}if(strstr(socketHandler->command,"KEL") != NULL){digitalWrite(SWITCH3,LOW);}if(strstr(socketHandler->command,"GEL") != NULL){digitalWrite(SWITCH3,HIGH);}if(strstr(socketHandler->command,"KWS") != NULL){digitalWrite(SWITCH4,LOW);}if(strstr(socketHandler->command,"GWS") != NULL){digitalWrite(SWITCH4,HIGH);}if(0 == strcmp(socketHandler->command,"OPCA")){ //当指令是OPCA时创建摄像头线程,完成拍照,人脸识别pthread_t cameraThread;pthread_create(&cameraThread,NULL,cameraThread_func,NULL);//pthread_join(cameraThread, NULL);}}}
}void * socket_thread(void* datas)
{int n_read = 0;pthread_t readThread;struct sockaddr_in c_addr;memset(&c_addr, 0, sizeof(struct sockaddr_in));int clen = sizeof(struct sockaddr_in);socketHandler = findCommandByName("sockerServer",pCommandHead);if(socketHandler == NULL){ //防止段错误printf("find socketHandler error\n");pthread_exit(NULL); //在线程中不用return}else{printf("%s init success\n",socketHandler->commandName);}socketHandler->Init(socketHandler,NULL,NULL); //找到之后执行socketInit函数while(1){c_fd = accept(socketHandler->sfd, (struct sockaddr *)&c_addr, &clen); //不断连接connect,连接到后创建readThread线程pthread_create(&readThread,NULL,read_thread,NULL);}
}int main()
{char name[128];struct Devices *tmp = NULL;pthread_t voiceThread;pthread_t socketThread;pthread_t fireAlarm_thread;if(wiringPiSetup() == -1){return -1;}//1.指令工厂初始化pCommandHead = addvoiceContrlToInputCommandLink(pCommandHead);pCommandHead = addSocketContrlToInputCommandLink(pCommandHead);//2.设备控制工厂初始化pdeviceHead = addBathroomLightToDeviceLink(pdeviceHead);pdeviceHead = addUpstairLightToDeviceLink(pdeviceHead);pdeviceHead = addRestaurantLightToDeviceLink(pdeviceHead);pdeviceHead = addLivingroomLightToDeviceLink(pdeviceHead);pdeviceHead = addcameraToDeviceLink(pdeviceHead);pdeviceHead = addFireToDeviceLink(pdeviceHead);pdeviceHead = addBeepToDeviceLink(pdeviceHead);struct Devices *tmpDeviceshead = pdeviceHead;while(tmpDeviceshead != NULL){ //设备工厂所有设备初始化tmpDeviceshead->deviceInit(tmpDeviceshead->pinNum);tmpDeviceshead = tmpDeviceshead->next;}//3.线程池建立//int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);//3.1语音线程pthread_create(&voiceThread,NULL,voice_thread,NULL);//3.2socket线程pthread_create(&socketThread,NULL,socket_thread,NULL);//3.3摄像头线程//3.4火灾线程pthread_create(&fireAlarm_thread,NULL,fireAlarmThread,NULL);printf("camera init success\n");pthread_join(voiceThread,NULL); //等待语音线程调用pthread_exit函数pthread_join(socketThread,NULL); //等待socket线程调用pthread_exit函数pthread_join(fireAlarm_thread, NULL); //等待火灾线程调用pthread_exit函数return 0;
}
3.段错误
在添加摄像头线程时,改了半天错误之后,可运行了,但是给我提示 segment fault,哈哈哈,心态崩了。当时我就关了树莓派打起了LOL,这一打就是一下午。晚上接着处理段错误,无果,第二天,无果。第二天晚上在图书馆发呆想到了找段错误的一种方法:printf调试法,晚上回到宿舍用了printf调试法十分钟就找到了错误,然后改正,运行成功,人脸识别成功。
4.C语言的函数声明
有的书上是这么说的,如果函数定义放在main函数前面,可以不用写声明。如果函数放在main函数后面,就规定要写函数声明。这么说没毛病。
不过有的地方又说:如果在函数定义在这个函数调用之前,就不需要写声明。否则就要写声明。
大家稍微注意下就行。为了防止报错的话,只要是函数都给声明就行了。
4.1没声明的报错内容
warning: implicit declaration of function ‘test’ [-Wimplicit-function-declaration]
5.关于报错,调试程序
编译报错,你要正确认识报错,为什么要报错。编译报错是编译器在帮助你。不要有报错就放弃,慢慢调试,成功永远在拐角之后,否则你永远不知道你离它有多远。加油。
树莓派智能家居项目整合(包含语音、socket、火灾、摄像头线程)相关推荐
- 智能家居 (5) ——智能家居项目整合(语音控制线程,网络控制线程、烟雾报警线程)
目录 一.主函数 mianPro.c 二.指令工厂 voiceControl.c socketControl.c inputCommand.h 三.设备工厂 smokeAlarm.c buzzer.c ...
- 智能家居 (8) ——智能家居项目整合(网络控制线程、语音控制线程,火灾报警线程)
目录 mainPro.c(主函数) 指令工厂 inputCommand.h voiceControl.c(语音控制) socketControl.c(网络线程) 控制工厂 contrlEquipmen ...
- 智能家居项目开发: 设计模式(工厂模式)+ 线程池 + Socket (持续更新中)
智能家居项目开发 一.智能家居功能细节拆分 控制区: 外设区: 面向对象类和对象的概念 结构体新玩法 二.工厂模式 1. 工厂模式的概念 2. 工厂模式的实现 3. 工厂模式使用及功能验证 三.智能家 ...
- 智能家居项目(八)之树莓派+摄像头进行人脸识别
目录 1.编辑Camera.c 2.编辑contrlDevices.h 3.编辑mainPro.c 4.进行编译: 5.运行结果: ./test1 6.项目图片演示 智能家居项目(七)之Libcurl ...
- 玩转树莓派 —智能家居(语音控制电器开关 及语音模块的二次开发)
本文内容为玩转树莓派 -智能家居(语音控制电器开关 及语音模块的二次开发) 1.语音模块 本人使用的是ld3320二代语音识别开发板 通过和电脑连接的是ttl转接口 连接的时候 大家注意l连接方式 2 ...
- 智能家居项目(三)之框架设计及框架代码文件工程建立
目录 一.智能家居项目框架设计草图 二.框架代码文件工程建立 三.添加声音识别模块的串口读取功能 一.智能家居项目框架设计草图 代码思路讲解: 1.一个指令工厂,一个控制工厂,实际上就是通过链表链起来 ...
- 树莓派智能家居-天气预报和实时温湿度监控
上篇博文<树莓派智能家居-语音聊天机器人实现>实现了树莓派的语音聊天功能,在其基础上,实现语音获取天气预报和当前温湿度. 获取天气预报 目前有现成的天气预报API,直接调用即可,代码如下: ...
- 智能家居项目开发(一):简单工厂设计模式引入
智能家居项目开发 一.智能家居功能细节拆分 二.设计模式概念的引入 三.类与对象 四.结构体新玩法 五.工厂模式 一.智能家居功能细节拆分 1.控制区 我们会用到之前学过的: 语音识别模块 socke ...
- 某智能家居项目框架学习总结
这个月来第一篇博客,各种其他事情.. 之前负责过一个智能家居项目的二次开发,苏州一家公司做的,项目还是分了好几个系统,对业务流程的不同部分进行了划分,我是此项目的主要负责人,通过老师的指导,对这个项目 ...
最新文章
- 曾捡破烂为生,穷到没饭吃,现在身家395亿,给员工发3亿年终奖!
- 客户端访问https时应无浏览器(含终端)安全警告信息;_https和http有什么区别(内附详细分析)...
- 服务器flask远程访问_在Flask中使用什么API来检查远程(其他)服务器的连接?...
- Python 24天 正则表达式
- oracle segment extent block,Oracle的基础问题segment extent block
- java 字节码加载_java面试题jvm字节码的加载与卸载
- centos 6.7 安装 最新版 git
- Linux redis配置服务,Linux 安装 redis 并配置成 service 系统服务
- Django:ORM基本操作-CRUD,管理器对象objects,----->查询3(单条更新,批量更新)
- linux中安装pip镜像怎么设置_linux服务器怎么安装pip?
- 「あるいは」 「もしくは」 「または」 「それとも」的区别
- NoSQLAttack针对 mongoDB 的攻击工具
- c 语言编写个人所得税程序,C语言编写一个计算个人所得税的程序,要求输入收入金额,能够输...
- sqluldr2 配置
- 网易云音乐数仓模型设计实践
- golang mysql null_Golang将变量声明为NULL
- Python电影票房数据可视化分析基础实践
- python最好视频教程_国外最顶级的Python视频教程,赶紧收藏!(带中文字幕)
- 免费视频直播、点播H5播放器SkeyeWebPlayer适配移动端
- QDockWidget增加边框
热门文章
- (转)[视频压制/转换技术] I帧 B帧 P帧 IDR帧 等帧用途详细说明
- oracle library is not loaded解决方法
- Semantic Nighttime Image Segmentation with Synthetic Stylized Data Gradual Adaptation
- Android studio无法连接识别检测各种模拟器和手机的问题
- 8.23 正点原子领航者V1开发板学习之EEPROM
- CL210管理存储--管理共享文件系统
- 犹他大学计算机图形学硕士专业,犹他大学专业设置.doc
- 2021年5月系统集成项目管理工程师案例分析真题视频讲解(3)
- 大一作业HTML网页作业:中华传统文化题材网页设计(纯html+css实现)科普网
- 远程GPU服务器运行Python