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

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);		//寻找“语音控制”所在节点,返回给voiceHandler
	if(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);		//寻找“网络控制”所在节点,返回给socketHandler
	if(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);		//寻找“火焰传感器”链表节点,返回给firetmp
	buztmp = findEquipByName("buzzer",equiphead);				//寻找“蜂鸣器”链表节点,返回给buztmp

	while(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;									//存放文件描述符 用于串口/客户端fd
	int (*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){		//打开树莓派串口,波特率为9600
		exit(-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端控制

  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行稳方能走远

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值