智能家居 (8) ——智能家居项目整合(网络控制线程、语音控制线程,火灾报警线程)

目录

  • mainPro.c(主函数)
  • 指令工厂
    • inputCommand.h
    • voiceControl.c(语音控制)
    • socketControl.c(网络线程)
  • 控制工厂
    • contrlEquipments.h
    • bathroomLight.c(浴室灯)
    • secondfloorLight.c(二楼灯)
    • livingroomLight.c(客厅灯)
    • restaurantLight.c(餐厅灯)
    • fireDetection.c(火焰传感器)
    • buzzer.c 文件(蜂鸣器)
  • 测试验证
  • 往期文章

mainPro.c(主函数)

#include <stdio.h>
#include <string.h>
#include "contrlEquipments.h"
#include "inputCommand.h"
#include <pthread.h>
#include <unistd.h>struct Equipment *findEquipByName(char *name,struct Equipment *phead);		//一些函数声明
struct Command *findCommandByName(char *name,struct Command *phead);
void *voiceControlThread(void *data);
void *socketControlThread(void *data);
void *socketReadThread(void *data);
void *fireAlarmThread(void *data);struct Equipment *equiphead = NULL;			//设备工厂链表头节点
struct Command *cmdhead = NULL;				//指令控制工厂链表节点头
struct Command *socketHandler = NULL;		//“网络控制线程”执行的函数使用到的全局变量int main()
{if(wiringPiSetup() == -1){					//使用wiringPi库需要初始化printf("wiringPiSetup failed!\n");return -1; }pthread_t voiceControl_thread;pthread_t socketControl_thread;pthread_t fireAlarm_thread;//1、设备工厂初始化equiphead = addBathroomLightToEquipmentLink(equiphead);			//各设备加入设备工厂equiphead = addSecondfloorLightToEquipmentLink(equiphead);	equiphead = addLivingroomLightToEquipmentLink(equiphead);equiphead = addRestaurantLightToEquipmentLink(equiphead);equiphead = addFireDetectionToEquipmentLink(equiphead);equiphead = addBuzzerToEquipmentLink(equiphead);struct Equipment *tmpequiphead = equiphead;while(tmpequiphead != NULL){						//设备工厂所有设备初始化tmpequiphead->Init(tmpequiphead->pinNum);tmpequiphead = tmpequiphead->next;}//2、指令工厂初始化cmdhead = addVoiceControlToCommandLink(cmdhead);				//各指令控制加入指令控制工厂cmdhead = addSocketControlToCommandLink(cmdhead);//3、线程池建立//3.1 语音线程   //int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);  pthread_create(&voiceControl_thread,NULL,voiceControlThread,NULL);		//创建线程:语音控制//3.2 网络线程 		pthread_create(&socketControl_thread,NULL,socketControlThread,NULL);	//创建线程:网络控制//3.3 火灾线程 	pthread_create(&fireAlarm_thread,NULL,fireAlarmThread,NULL);			//创建线程:火灾报警系统//3.4 摄像头线程 pthread_join(voiceControl_thread, NULL);		//主函数等待线程退出pthread_join(socketControl_thread, NULL);		//主函数等待线程退出pthread_join(fireAlarm_thread, NULL);			//主函数等待线程退出return 0;
}void *voiceControlThread(void *data)			//“语音控制线程”执行的函数
{int nread;char *temName = NULL;struct Command *voiceHandler = NULL;struct Equipment *linkHandler;voiceHandler = findCommandByName("voiceControl",cmdhead);		//寻找“语音控制”所在节点,返回给voiceHandlerif(voiceHandler == NULL){printf("find voiceHandler error\n");pthread_exit(NULL);}if(voiceHandler->Init(voiceHandler) < 0){				//“语音控制”功能初始化printf("voiceControl init error\n");pthread_exit(NULL);}while(1){nread = voiceHandler->getCommand(voiceHandler);			//获取指令if(nread == 0){											//没有获取到指令printf("No voiceCommand received\n");}else{													//获取到指令printf("Get voice command:%s\n",voiceHandler->command);//以下为根据不用指令执行相应操作//语音模块串口传出来的后面带\r\n,不加对比不出来if(strcmp("kysd\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("bathroomLight",equiphead);linkHandler->open(linkHandler->pinNum);printf("已打开浴室灯\n");}if(strcmp("gysd\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("bathroomLight",equiphead);linkHandler->close(linkHandler->pinNum);printf("已关闭浴室灯\n");}if(strcmp("keld\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("secondfloorLight",equiphead);linkHandler->open(linkHandler->pinNum);}if(strcmp("geld\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("secondfloorLight",equiphead);linkHandler->close(linkHandler->pinNum);}if(strcmp("kktd\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("livingroomLight",equiphead);linkHandler->open(linkHandler->pinNum);}if(strcmp("gktd\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("livingroomLight",equiphead);linkHandler->close(linkHandler->pinNum);}if(strcmp("kctd\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("restaurantLight",equiphead);linkHandler->open(linkHandler->pinNum);}if(strcmp("gctd\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("restaurantLight",equiphead);linkHandler->close(linkHandler->pinNum);}if(strcmp("kqbd\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("bathroomLight",equiphead);linkHandler->open(linkHandler->pinNum);linkHandler = findEquipByName("secondfloorLight",equiphead);linkHandler->open(linkHandler->pinNum);linkHandler = findEquipByName("livingroomLight",equiphead);linkHandler->open(linkHandler->pinNum);linkHandler = findEquipByName("restaurantLight",equiphead);linkHandler->open(linkHandler->pinNum);}if(strcmp("gqbd\r\n",voiceHandler->command) == 0){linkHandler = findEquipByName("bathroomLight",equiphead);linkHandler->close(linkHandler->pinNum);linkHandler = findEquipByName("secondfloorLight",equiphead);linkHandler->close(linkHandler->pinNum);linkHandler = findEquipByName("livingroomLight",equiphead);linkHandler->close(linkHandler->pinNum);linkHandler = findEquipByName("restaurantLight",equiphead);linkHandler->close(linkHandler->pinNum);}}}
}void *socketControlThread(void *data)				//“网络控制线程”执行的函数
{int c_fd;struct sockaddr_in c_addr;memset(&c_addr,0,sizeof(struct sockaddr_in));socklen_t clen = sizeof(struct sockaddr_in);pthread_t socketRead_thread; //线程里面套线程,网络连接后信息通信socketHandler = findCommandByName("socketControl",cmdhead);		//寻找“网络控制”所在节点,返回给socketHandlerif(socketHandler == NULL){printf("find socketHandler error\n");pthread_exit(NULL);}if(socketHandler->Init(socketHandler) < 0){				//“网络控制”功能初始化printf("socketControl init error\n");pthread_exit(NULL);}while(1){c_fd = accept(socketHandler->s_fd,(struct sockaddr*)&c_addr,&clen);		//接收连接请求,阻塞至有客户端完成三次握手socketHandler->fd = c_fd;					//将套接字描述符返回给“网络控制”链表节点pthread_create(&socketRead_thread,NULL,socketReadThread,NULL);			//创建新线程:用于读取TCP端口指令
//只要有连接,就创建线程去对接。线程共用内存资源,同一时刻,所有设备只有一种状态。也可PV操作
//所有线程 只操控一个结构体 再新来一个线程(新手机客户端接入) 前一个客户端失效 因为c_fd被改了。fork()可实现多个客户端同时控制
//不过好像寄存器和内存不是完全同步的 可能缓存没改?还可以多个客户端同时控制?
//如果直接把socketReadThread()拿过来循环的话,则同时刻不能接受新的客户端接入了,因为循环卡在了socketReadThread()函数里面了}
}void *socketReadThread(void *data)				//“读取tcp端口指令线程”执行的函数
{int nread;struct Equipment *linkHandler;//这里没加while循环,客户端只能发送一次printf("socketConnect...");while(1){memset(socketHandler->command,'\0',sizeof(socketHandler->command));		//将指令存放的空间置空nread = read(socketHandler->fd,socketHandler->command,sizeof(socketHandler->command));		//读取指令if(nread == 0){printf("No socketCommand received\n");			//没有读取到指令}else{printf("Get socketCommand:%s\n",socketHandler->command);		//读取到指令//以下为根据不用指令执行相应操作if(strcmp("kysd",socketHandler->command) == 0){linkHandler = findEquipByName("bathroomLight",equiphead);linkHandler->open(linkHandler->pinNum);}if(strcmp("gysd",socketHandler->command) == 0){linkHandler = findEquipByName("bathroomLight",equiphead);linkHandler->close(linkHandler->pinNum);}if(strcmp("keld",socketHandler->command) == 0){linkHandler = findEquipByName("secondfloorLight",equiphead);linkHandler->open(linkHandler->pinNum);}if(strcmp("geld",socketHandler->command) == 0){linkHandler = findEquipByName("secondfloorLight",equiphead);linkHandler->close(linkHandler->pinNum);}if(strcmp("kktd",socketHandler->command) == 0){linkHandler = findEquipByName("livingroomLight",equiphead);linkHandler->open(linkHandler->pinNum);}if(strcmp("gktd",socketHandler->command) == 0){linkHandler = findEquipByName("livingroomLight",equiphead);linkHandler->close(linkHandler->pinNum);}if(strcmp("kctd",socketHandler->command) == 0){linkHandler = findEquipByName("restaurantLight",equiphead);linkHandler->open(linkHandler->pinNum);}if(strcmp("gctd",socketHandler->command) == 0){linkHandler = findEquipByName("restaurantLight",equiphead);linkHandler->close(linkHandler->pinNum);}if(strcmp("kqbd",socketHandler->command) == 0){linkHandler = findEquipByName("bathroomLight",equiphead);linkHandler->open(linkHandler->pinNum);linkHandler = findEquipByName("secondfloorLight",equiphead);linkHandler->open(linkHandler->pinNum);linkHandler = findEquipByName("livingroomLight",equiphead);linkHandler->open(linkHandler->pinNum);linkHandler = findEquipByName("restaurantLight",equiphead);linkHandler->open(linkHandler->pinNum);}if(strcmp("gqbd",socketHandler->command) == 0){linkHandler = findEquipByName("bathroomLight",equiphead);linkHandler->close(linkHandler->pinNum);linkHandler = findEquipByName("secondfloorLight",equiphead);linkHandler->close(linkHandler->pinNum);linkHandler = findEquipByName("livingroomLight",equiphead);linkHandler->close(linkHandler->pinNum);linkHandler = findEquipByName("restaurantLight",equiphead);linkHandler->close(linkHandler->pinNum);}}}
}void *fireAlarmThread(void *data)				//“火灾报警器线程”执行的函数
{int status;struct Equipment *firetmp = NULL;struct Equipment *buztmp = NULL;firetmp = findEquipByName("fireDetection",equiphead);		//寻找“火焰传感器”链表节点,返回给firetmpbuztmp = findEquipByName("buzzer",equiphead);				//寻找“蜂鸣器”链表节点,返回给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);		//关闭蜂鸣器}}
}struct Equipment *findEquipByName(char *name,struct Equipment *phead)		//根据名字寻找设备工厂链表链节函数,并返回链节
{struct Equipment *tmp = phead;if(phead == NULL){return NULL;}while(tmp != NULL){if(strcmp(name,tmp->equipName) == 0){return tmp;}tmp = tmp->next;}return NULL;
}struct Command *findCommandByName(char *name,struct Command *phead)			//根据名字寻找指令控制工厂链表链节函数,并返回链节
{struct Command *tmp = phead;if(phead == NULL){return NULL;}while(tmp != NULL){if(strcmp(name,tmp->commandName) == 0){return tmp;}tmp = tmp->next;}return NULL;
}

指令工厂

inputCommand.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>struct Command								//指令控制工厂链表节点定义
{char commandName[128];					//“控制方式”名字char deviceFilesName[128];				//存放初始化功能需要打开的文件的路径char command[32];						//存放指令int fd;									//存放文件描述符 用于串口/客户端fdint (*Init)(struct Command *file);		//“初始化”函数指针int s_fd;								//存放套接字描述符char ipAdress[32];						//存放IP地址char port[12];							//存放端口号int (*getCommand)(struct Command *cmd);	//“获取指令”函数指针char log[1024];							//日志(暂未使用)struct Command *next;
};struct Command *addVoiceControlToCommandLink(struct Command *phead);		//“语音控制”加入指令控制工厂链表函数声明
struct Command *addSocketControlToCommandLink(struct Command *phead);		//“网络控制”加入指令控制工厂链表函数声明

voiceControl.c(语音控制)

#include "inputCommand.h"
#include <unistd.h>int voiceControlInit(struct Command *file);							//“语音控制”功能初始化函数声明
int voiceControlGetCommand(struct Command *cmd);					//“获取指令”函数声明
//struct Command *addVoiceControlToLink(struct Command *phead);		//“语音控制”加入指令控制工厂链表函数声明struct Command voiceControl = {				//“语音控制”链表节点.commandName = "voiceControl",.deviceFilesName = "/dev/ttyAMA0",.command = {'\0'},.Init = voiceControlInit,             //这里只是定义,还未调用改函数.getCommand = voiceControlGetCommand,.log = {'\0'},
};int voiceControlInit(struct Command *file)
{int fd;if((fd = serialOpen(file->deviceFilesName,9600)) == -1){		//打开树莓派串口,波特率为9600exit(-1);}file->fd = fd;				//打开串口文件成功,返回“文件描述符”到“语音控制”链表节点中
}int voiceControlGetCommand(struct Command *cmd)					//“获取指令”函数
{int nread = 0;memset(cmd->command,'\0',sizeof(cmd->command));					//防止老的消息影响新的消息nread = read(cmd->fd,cmd->command,sizeof(cmd->command));		//返回读取到数据的字节数return nread;
}struct Command *addVoiceControlToCommandLink(struct Command *phead)		//头插法将“语音控制”链表节点加入指令控制工厂链表函数
{if(phead == NULL){return &voiceControl;}else{voiceControl.next = phead;phead = &voiceControl;return phead;}
}

socketControl.c(网络线程)

#include "inputCommand.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>int socketControlInit(struct Command *file);					//“网络控制”功能初始化函数声明
//struct Command *addSocketControlToLink(struct Command *phead);	//“网络控制”加入指令控制工厂链表函数声明struct Command socketControl = {		//“网络控制”链表节点.commandName = "socketControl",.command = {'\0'},.Init = socketControlInit,.ipAdress = "192.168.0.19",		//树莓派连接网络时的IP地址.port = "8088",						//树莓派打开待外界连接的端口号.log = {'\0'},
};int socketControlInit(struct Command *file)
{int s_fd;											//套接字描述符struct sockaddr_in s_addr;memset(&s_addr,0,sizeof(struct sockaddr_in));s_fd = socket(AF_INET,SOCK_STREAM,0);				//创建套接字if(s_fd == -1){										//创建套接字失败时perror("socketControl error");exit(-1);}s_addr.sin_family = AF_INET;s_addr.sin_port = htons(atoi(file->port));inet_aton(file->ipAdress,&s_addr.sin_addr);if(bind(s_fd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr_in)) == -1){		//套接字与端口号绑定perror("bind error");exit(-1);}if(listen(s_fd,10) == -1){		//打开监听 accept放到主函数线程里perror("listen error");exit(-1);}file->s_fd = s_fd;						//套接字描述符返回到“网络控制”链表节点
}struct Command *addSocketControlToCommandLink(struct Command *phead)			//头插法将设备节点加入设备工厂链表函数
{if(phead == NULL){return &socketControl;}else{socketControl.next = phead;phead = &socketControl;return phead;}
}

控制工厂

contrlEquipments.h

#include <wiringPi.h>				//wiringPi库
#include <stdio.h>
#include <stdlib.h>struct Equipment								//设备工厂链表节点定义
{char equipName[128];						//设备名int pinNum;									//引脚号int status;									//“初始化设备”函数指针int (*Init)(int pinNum);					//“打开设备”函数指针int (*open)(int pinNum);					//“关闭设备”函数指针int (*close)(int pinNum);int (*readStatus)(int pinNum);				//“读取设备状态”函数指针int (*changeStatus)(int status);			//“改变设备状态函数指针”struct Equipment *next;
};struct Equipment *addBathroomLightToEquipmentLink(struct Equipment *phead);			//“浴室灯”设备节点加入设备工厂链表函数声明
struct Equipment *addSecondfloorLightToEquipmentLink(struct Equipment *phead);		//“二楼灯”设备节点加入设备工厂链表函数声明
struct Equipment *addLivingroomLightToEquipmentLink(struct Equipment *phead);		//“客厅灯”设备节点加入设备工厂链表函数声明
struct Equipment *addRestaurantLightToEquipmentLink(struct Equipment *phead);		//“餐厅灯”设备节点加入设备工厂链表函数声明
struct Equipment *addFireDetectionToEquipmentLink(struct Equipment *phead);			//“火焰传感器”设备节点加入设备工厂链表函数声明
struct Equipment *addBuzzerToEquipmentLink(struct Equipment *phead);					//“蜂鸣器”设备节点加入设备工厂链表函数声明

bathroomLight.c(浴室灯)

#include "contrlEquipments.h"int bathroomLightInit(int pinNum);				//一些函数声明
int bathroomLightOpen(int pinNum);
int bathroomLightClose(int pinNum);
//struct Equipment *addBathroomLightToLink(struct Equipment *phead);struct Equipment bathroomLight = {		//“浴室灯”设备链表节点.equipName = "bathroomLight",.pinNum = 26,						//树莓派gpio引脚21.Init = bathroomLightInit,         .open = bathroomLightOpen,.close = bathroomLightClose,
};int bathroomLightInit(int pinNum)			//初始化函数
{pinMode(pinNum,OUTPUT);					//配置引脚为输出引脚digitalWrite(pinNum,HIGH);				//引脚输出高电平,即默认为关闭状态
}int bathroomLightOpen(int pinNum)			//打开函数
{digitalWrite(pinNum,LOW);
}int bathroomLightClose(int pinNum)			//关闭函数
{digitalWrite(pinNum,HIGH);
}struct Equipment *addBathroomLightToEquipmentLink(struct Equipment *phead)		//头插法将设备节点加入设备工厂链表函数
{if(phead == NULL){return &bathroomLight;}else{bathroomLight.next = phead;phead = &bathroomLight;return phead;}
}

secondfloorLight.c(二楼灯)

#include "contrlEquipments.h"int secondfloorLightInit(int pinNum);				//一些函数声明
int secondfloorLightOpen(int pinNum);
int secondfloorLightClose(int pinNum);struct Equipment *addSecondfloorLightToEquipmentLink(struct Equipment *phead);
struct Equipment secondfloorLight = {		//“二楼灯”设备链表节点.equipName = "secondfloorLight",.pinNum = 27,							//树莓派gpio引脚22.Init = secondfloorLightInit,.open = secondfloorLightOpen,.close = secondfloorLightClose,
//	.changeStatus = secondfloorLightChangeStatus,
};int secondfloorLightInit(int pinNum)			//初始化函数
{pinMode(pinNum,OUTPUT);					//配置引脚为输出引脚digitalWrite(pinNum,HIGH);				//引脚输出高电平,即默认为关闭状态
}int secondfloorLightOpen(int pinNum)			//打开函数
{digitalWrite(pinNum,LOW);
}int secondfloorLightClose(int pinNum)			//关闭函数
{digitalWrite(pinNum,HIGH);
}struct Equipment *addSecondfloorLightToEquipmentLink(struct Equipment *phead)		//头插法将设备节点加入设备工厂链表函数
{if(phead == NULL){return &secondfloorLight;}else{secondfloorLight.next = phead;phead = &secondfloorLight;return phead;}
}

livingroomLight.c(客厅灯)

#include "contrlEquipments.h"int livingroomLightInit(int pinNum);				//一些函数声明
int livingroomLightOpen(int pinNum);
int livingroomLightClose(int pinNum);
//struct Equipment *addLivingroomLightToLink(struct Equipment *phead);struct Equipment livingroomLight = {		//“客厅灯”设备链表节点.equipName = "livingroomLight",.pinNum = 28,							//树莓派gpio引脚23.Init = livingroomLightInit,.open = livingroomLightOpen,.close = livingroomLightClose,
};int livingroomLightInit(int pinNum)				//初始化函数
{pinMode(pinNum,OUTPUT);					//配置引脚为输出引脚digitalWrite(pinNum,HIGH);				//引脚输出高电平,即默认为关闭状态
}int livingroomLightOpen(int pinNum)				//打开函数
{digitalWrite(pinNum,LOW);
}int livingroomLightClose(int pinNum)			//关闭函数
{digitalWrite(pinNum,HIGH);
}struct Equipment *addLivingroomLightToEquipmentLink(struct Equipment *phead)			//头插法将设备节点加入设备工厂链表函数
{if(phead == NULL){return &livingroomLight;}else{livingroomLight.next = phead;phead = &livingroomLight;return phead;}
}

restaurantLight.c(餐厅灯)

#include "contrlEquipments.h"int restaurantLightInit(int pinNum);				//一些函数声明
int restaurantLightOpen(int pinNum);
int restaurantLightClose(int pinNum);
//struct Equipment *addRestaurantLightToLink(struct Equipment *phead);struct Equipment restaurantLight = {		//“餐厅灯”设备链表节点.equipName = "restaurantLight",.pinNum = 29,							//树莓派gpio引脚24.Init = restaurantLightInit,.open = restaurantLightOpen,.close = restaurantLightClose,
};int restaurantLightInit(int pinNum)				//初始化函数
{pinMode(pinNum,OUTPUT);					//配置引脚为输出引脚digitalWrite(pinNum,HIGH);				//引脚输出高电平,即默认为关闭状态
}int restaurantLightOpen(int pinNum)				//打开函数
{digitalWrite(pinNum,LOW);
}int restaurantLightClose(int pinNum)			//关闭函数
{digitalWrite(pinNum,HIGH);
}struct Equipment *addRestaurantLightToEquipmentLink(struct Equipment *phead)			//头插法将设备节点加入设备工厂链表函数
{if(phead == NULL){return &restaurantLight;}else{restaurantLight.next = phead;phead = &restaurantLight;return phead;}
}

fireDetection.c(火焰传感器)

#include "contrlEquipments.h"int fireDetectionInit(int pinNum);					//一些函数声明
int readFireDetectionStatus(int pinNum);
//struct Equipment *addFireDetectionToLink(struct Equipment *phead);struct Equipment fireDetection = {			//“火焰传感器”设备链表节点.equipName = "fireDetection",.pinNum = 21,							//树莓派gpio引脚25.Init = fireDetectionInit,.readStatus = readFireDetectionStatus,
};int fireDetectionInit(int pinNum)			//初始化函数
{pinMode(pinNum,INPUT);					//配置引脚为输入引脚digitalWrite(pinNum,HIGH);				//引脚输出高电平,即默认为关闭状态
}int readFireDetectionStatus(int pinNum)		//读取“火焰传感器”状态函数
{return digitalRead(pinNum);
}struct Equipment *addFireDetectionToEquipmentLink(struct Equipment *phead)
{if(phead == NULL){return &fireDetection;}else{fireDetection.next = phead;phead = &fireDetection;return phead;}
}

buzzer.c 文件(蜂鸣器)

#include "contrlEquipments.h"int buzzerInit(int pinNum);					//一些函数声明
int buzzerOpen(int pinNum);
int buzzerClose(int pinNum);
struct Equipment *addBuzzerToEquipmentLink(struct Equipment *phead);struct Equipment buzzer = {			//“蜂鸣器”设备链表节点.equipName = "buzzer",.pinNum = 22,					//树莓派gpio引脚29.Init = buzzerInit,.open = buzzerOpen,.close = buzzerClose,
};int buzzerInit(int pinNum)					//初始化函数
{pinMode(pinNum,OUTPUT);					//配置引脚为输出引脚digitalWrite(pinNum,HIGH);				//引脚输出高电平,即默认为关闭状态
}int buzzerOpen(int pinNum)					//打开函数
{digitalWrite(pinNum,LOW);
}int buzzerClose(int pinNum)					//关闭函数
{digitalWrite(pinNum,HIGH);
}struct Equipment *addBuzzerToEquipmentLink(struct Equipment *phead)			//头插法将设备节点加入设备工厂链表函数
{if(phead == NULL){return &buzzer;}else{buzzer.next = phead;phead = &buzzer;return phead;}
}

测试验证

所有代码均可编译运行,3个线程均通过实验验证。

后期将网络线程整合在手机app上,从而实现手机端远程控制和监测智能家居,需要继续学习JAVA以及Android知识。

往期文章

智能家居 (1) ——智能家居整体功能框架
智能家居 (2) ——设计模式的引入
智能家居 (3) ——工厂模式继电器控制灯
智能家居 (4) ——工厂模式火焰报警
智能家居 (5) —— LD3320语音模块二次开发
智能家居 (6) ——语音识别线程控制
智能家居 (7) ——网络服务器线程控制
智能家居 (8) ——智能家居项目整合(网络控制线程、语音控制线程,火灾报警线程)
网络编程知识预备(1) ——了解OSI网络模型
网络编程知识预备(2) ——浅显易懂的三次握手与四次挥手
网络编程知识预备(3) ——SOCKET、TCP、HTTP之间的区别与联系
网络编程知识预备(4) ——了解HTTP协议与HTTPS协议
网络编程知识预备(5) ——libcurl库简介及其编程访问百度首页
智能家居 (9) ——人脸识别摄像头安装实现监控功能
智能家居 (10) ——人脸识别祥云平台编程使用
智能家居 (11) ——树莓派摄像头捕捉人脸并识别
智能家居 (12) ——人脸识别整合到智能家居系统
智能家居 (13) ——智能家居加入手机app端控制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/265820.shtml

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

相关文章

mpu 配置内存空间_ARM存储器之:存储保护单元MPU

本文引用地址&#xff1a;http://www.eepw.com.cn/article/257010.htm15.4.2内存访问顺序当ARM处理器产生一个内存访问信号时&#xff0c;内存保护单位MPU将负责检查要访问的地址是否在被定义的域中。①如果地址不在任何域中&#xff0c;存储器产生异常。如果内核预取指令则MPU…

对象创建过程之二(类加载器)

2019独角兽企业重金招聘Python工程师标准>>> JAVA为我们提供了两种动态加载机制。 第一种是隐式机制。其实new一个对象和调用类的静态方法时&#xff0c;就是隐式机制在工作。 第二种是显示机制。显示的机制又有两种策略 第一种是用public static Class<?> …

Python_堆栈和队列

堆栈和队列 (1)堆栈&#xff0c;新放进去的先取出 #encodingutf-8 >>> stack [3, 4, 5] >>> stack.append(6) >>> stack.append(7) >>> print (stack) [3, 4, 5, 6, 7] >>> print (stack.pop()) 7 >>> print (stack) […

智能家居 (10) ——人脸识别祥云平台编程使用(编译libcurl库支持SSL,安装SSL依赖库libssl、libcrypto)

目录说明人工智能OCR识别平台介绍人脸识别接口购买编程打通OCR后台实现人脸识别&#xff08;ubuntu上实现&#xff09;问题发现编译libcurl库支持SSL安装SSL依赖库openSSL(使用工具wget)curl库重新配置&#xff0c;编译&#xff0c;安装开启SSL后重新编译人脸识别.C文件传入图片…

解决Centos 7 VNC黑屏

在配置Centos 7下VNC时发现root用户可以正常登陆VNC桌面&#xff0c;而普通用户VNC桌面黑屏&#xff0c;分析~/.vnc/xstarup 后发现是普通用户没有执行/etc/X11/xinit/xinitrc的权限 #!/bin/shunset SESSION_MANAGER unset DBUS_SESSION_BUS_ADDRESS /etc/X11/xinit/xinitrc #…

MFC控件(7):Split Button

VS2008中可以看到MFC有一个叫Split Button的控件,要想看它的效果,瞧下QQ那聊天窗口的"发送", "消息记录"这两个按钮就知道了.实际上就是还有点像Combo Box了.不过它的实现应该是button加menu.所以它的消息处理可以分开成button的处理和menu的处理 往dialog…

srs 服务关闭命令_【经验总结】如何做到网络版工作站与服务器时间同步?

随着行业发展&#xff0c;越来越多的实验室色谱数据工作站由原来的单机版&#xff0c;升级为网络版。升级后带来的益不必多说&#xff0c;那么升级带来的困难你遇到过吗&#xff1f;快来跟小析姐一起看看牛人是如何解决问题的吧。最近公司将色谱工作站进行了升级&#xff0c;采…

oss图片尺寸调用方式_是时候来一场轰轰烈烈的OSS升级了

【摘要】伴随5G和云网部署的持续推进&#xff0c;运营商OSS升级建设都已经在不断加速。| 科 | 技 | 杂 | 谈 |中国通信行业第一自媒体【1】运营商的IT支撑系统&#xff0c;正迫切需要新一轮的调整转型。今天&#xff0c;中国移动在2020全球合作伙伴大会上宣布&#xff0c;全球最…

由C过渡到C++-入门知识点

从C语言过渡到C&#xff0c;这些知识点应该是比较重要的。 目录 第一个C程序名称空间特性coutcin 缺省参数重载提问&#xff1a;为什么C语言不支持重载而C支持 引用常引用 引用与函数返回值对于指针和引用的区别引用的底层实现两者在语法上两者在物理上两者的不同之处 内联函数…

gdb pwndbg插件安装

环境&#xff1a; gdb 9.2ubuntu 20(x64) 连接 pwndbggdb9.2gdb9.2网盘连接 密码: kaq4GDB中文教程 编译gdb 由于发行的gdb比较老&#xff0c;pwndbg建议使用高版本GDB&#xff0c;因此我们下载最新的GDB9.2 安装依赖 #apt install texinfo解压GDB,卸载自带GDB #tar -vxf…

Android--UI之DatePicker、TimePicker...

前言 这一篇博客分别讲解Android平台下&#xff0c;关于日期和时间的几个相关控件。包括DatePicker&#xff08;日期选择控件&#xff09;、TimePicker&#xff08;时间选择控件&#xff09;、DatePickerDialog&#xff08;日期选择对话框&#xff09;、TimePickerDialog&#…

DPDK 18 log日志系统使用

概述&#xff1a; DPDK 日志系统分为1-8个等级&#xff0c;在lib/librte_eal/common/include/rte_log.h文件中定义&#xff0c;每个DPDK模块都可以定义一个预设日志输出等级&#xff0c;只有日志输出语句的等级小于等于预设输出等级才能被输出。 以下为dpdk对日志的分级&…

递归和迭代路由_静态路由在以太网接口中的不同书写会导致路由器怎样的操作结果?...

各位小伙伴们&#xff1a;大家好&#xff01;上一节和大家分享了在不同类型的网络中应该使用什么样的静态路由配置命令&#xff1b;今天我们再来看看在常见的多路访问(MBA)网络——以太网中&#xff0c;静态路由的不同书写方式将导致路由器执行那些不同的操作。如下图&#xff…

实验报告三

学 号 201521440010 中国人民公安大学 Chinese people’ public security university 网络对抗技术 实验报告 实验三 密码破解技术 学生姓名 邱景丛 年级 2015 区队 四 指导教师 高见 信息技术与网络安全学院 2016年11月7日 实验任务总纲 2016—2017 学年 第 一 …

设计前沿:25个设计师向您展示 iOS 7 界面

我们中的许多人都对新发布的 iOS 7 用户界面有点失望。扎眼的颜色搭配&#xff0c;难看的图标和可疑的设计决策&#xff0c;导致很多的设计师在 Dribbble 和 Behance 等社交网站分享自己对 iOS 界面设计的诠释。这篇文章集合了一些伟大的想法&#xff0c;改进苹果 iOS 7 的界面…

开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...

目录 合作案例专栏&#xff1a;案例分享 开发专栏&#xff1a;项目实战 Qt开发专栏&#xff1a;开发技术 Qt开发专栏&#xff1a;三方库开发技术 Qt开发专栏&#xff1a;实用技巧 Qt开发专栏&#xff1a;各种问题解决 Qt开发专栏&#xff1a;qss样式表笔记大全 Qt开发专…

dpdk 18 ixgbe驱动初始化分析

rte_log_set_global_level rte_log_set_global_level(uint32_t level) pci bus注册 TE_REGISTER_BUS(pci, rte_pci_bus.bus); drivers/bus/pci/pci_common.c ,注册静态的设置rte_pci_bus&#xff0c;在rte_pci_bus中设置了pci bus的各个回调函数 struct rte_pci_bus rte_pc…

ATM + 购物商城程序

模拟实现一个ATM 购物商城程序 额度 15000或自定义 实现购物商城&#xff0c;买东西加入 购物车&#xff0c;调用信用卡接口结账 可以提现&#xff0c;手续费5% 每月22号出账单&#xff0c;每月10号为还款日&#xff0c;过期未还&#xff0c;按欠款总额 万分之5 每日计息 …

esp8266 擦拭_【一起玩esp8266】flash的擦除方法——专治疑难杂症

出现新问题。。。COM口没法操作 拒绝访问C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\Scripts>esptool.py --port COM6 erase_flashesptool.py v2.3.1Traceback (most recent call last):File "C:\Users\Administrator\AppData\Local\Programs\…

诗人李白小评

李白其实一生都不得志&#xff0c;他从小学文习武&#xff0c;少年时开始“行路&#xff0c;读万卷书&#xff0c;拜万家师”&#xff0c;希望走一条由人推荐&#xff0c;而一举成名的道路。可惜他忌恶如仇的性格&#xff0c;开罪了小人&#xff0c;导致小人对他仕途之路的极力…