智能家居1.0

该系统利用树莓派3B、语音模块和火焰传感器实现语音控制灯光,并在火灾时触发报警。此外,计划开发安卓App以远程控制灯光、风扇、监控画面及CPU温度,并集成温湿度显示、人脸识别开锁和摄像头功能。硬件包括继电器、传感器和报警器等,通过多线程处理不同功能,如语音识别线程负责处理语音指令,火灾检测线程监控火警状态。

功能描述

  1. 通过语音对灯光的控制
  2. 出现火灾时报警器响起
2.0待完成的功能有:
  1. 自行制作安卓App,通过App实现对外设的控制,灯光、风扇
  2. App还具有以下功能
    • 显示监控画面+火灾报警+cpu温度+灯和锁状态
    • 除视频监控外,可实现远程操作(内网穿透)
    • 可控制摄像头功能(录像或监控画面显示)
  3. oled屏展示温湿度情况
  4. 人脸识别开锁
  5. 增加一块单片机作为子系统

硬件清单

  1. 树莓派3b
  2. 语音模块SU-03T
  3. 火焰传感器(3.3v,低电平有效)
  4. 4路继电器组(5v,低电平有效)
  5. 继电器(3.3v,低电平有效)
  6. 报警器喇叭
  7. 房子模型
  8. 面包板
  9. 电池盒

部分硬件截图:
在这里插入图片描述
由于报警器的声音实在是太响了,我选择把它包起来放进箱子里面,这样声音能减半。

主要思路

整体采用工厂模式的开发方式,主要分为指令工厂和设备工厂。
指令工厂串口、网络通信;设备工厂包括继电器控制灯、控制火灾、温湿度、报警器等模块设备。
每个功能会对应一条线程。

架构图如下(包含2.0待实现的思路)
在这里插入图片描述

代码如下

  1. 主程序(main.Pro)
#include <stdio.h>
#include "contrlDevices.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "InputCommand.h"

struct Devices        *pdeviceHead   = NULL;
struct InputCommander *pCommandHead  = NULL;
struct InputCommander *socketHandler = NULL;
struct Devices *deviceTmp = NULL;


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 openLight(char deviceName[32])
{
	deviceTmp = findDeviceByName(deviceName, pdeviceHead);
    deviceTmp->deviceInit(deviceTmp->pinNum);
    deviceTmp->open(deviceTmp->pinNum);//开浴室灯
}

void closeLight(char deviceName[32])
{
	deviceTmp = findDeviceByName(deviceName, pdeviceHead);
    deviceTmp->deviceInit(deviceTmp->pinNum);
    deviceTmp->close(deviceTmp->pinNum);//开浴室灯
}


void openGroundFloorLight(char deviceName1[32], char deviceName2[32])
{
	deviceTmp=findDeviceByName(deviceName1, pdeviceHead);
    deviceTmp->deviceInit(deviceTmp->pinNum);
    deviceTmp->open(deviceTmp->pinNum);
    
    deviceTmp=findDeviceByName(deviceName2,pdeviceHead);
    deviceTmp->deviceInit(deviceTmp->pinNum);
    deviceTmp->open(deviceTmp->pinNum);
}

void closeGroundFloorLight(char deviceName1[32], char deviceName2[32])
{
	deviceTmp=findDeviceByName(deviceName1, pdeviceHead);
    deviceTmp->deviceInit(deviceTmp->pinNum);
    deviceTmp->close(deviceTmp->pinNum);
    
    deviceTmp=findDeviceByName(deviceName2,pdeviceHead);
    deviceTmp->deviceInit(deviceTmp->pinNum);
    deviceTmp->close(deviceTmp->pinNum);
}


void* voice_thread(void *datas)
{
	struct InputCommander *voiceHandler;
	int nread;
	
	voiceHandler = findCommandByName("voice", pCommandHead);

	if(voiceHandler == NULL){
		printf("find voiceHandler error\n");
		pthread_exit(NULL);
	}else{
		if(voiceHandler->Init(voiceHandler, NULL, NULL) < 0){
			printf("voice init error\n");
			pthread_exit(NULL);
		}else{
			printf("%s init success\n",voiceHandler->commandName);
		}
		while(1){
			nread = voiceHandler->getCommand(voiceHandler);
			if(nread < 0){
				 printf("voice init error\n");
				 pthread_exit(NULL);
			}else{
				printf("do divece contrl:%s\n", voiceHandler->command);
				
				if(strstr(voiceHandler->command, "B") != NULL){
					printf("bathroomLight\n");  //开浴室灯
					openLight("bathroomLight");
				}
				if(strstr(voiceHandler->command,"U") != NULL){
					printf("upstairLight\n");  //开客厅灯
					openLight("upstairLight");
				}
				if(strstr(voiceHandler->command,"l") != NULL){
					printf("livingLight\n");  //开卧室灯
					openLight("livingLight");
	            }
				if(strstr(voiceHandler->command,"R") != NULL){
					printf("restaurantLight\n");  //开厨房灯
					openLight("restaurantLight");
	            }
				if(strstr(voiceHandler->command,"P") != NULL){
					printf("poolLight\n");  //开泳池灯
					openLight("poolLight");
            	}
				if(strstr(voiceHandler->command,"f") != NULL){
					openGroundFloorLight("bathroomLight", "livingLight");  //开二楼灯
				}
				if(strstr(voiceHandler->command,"h") != NULL){
					closeGroundFloorLight("bathroomLight", "livingLight"); //关二楼灯
				}
				if(strstr(voiceHandler->command,"e") != NULL){ //开一楼灯
					openGroundFloorLight("upstairLight", "restaurantLight");
				}
				if(strstr(voiceHandler->command,"g") != NULL){
					closeGroundFloorLight("upstairLight", "restaurantLight"); //关一楼灯
				}
				if(strstr(voiceHandler->command,"i") != NULL){
					closeLight("poolLight"); //关泳池灯
            	}
	                
	        }
		}
	}
}

void* read_thread(void *datas)
{
	int n_read;
	memset(socketHandler->command, '\0', sizeof(socketHandler->command));
	n_read = read(c_fd, socketHandler->command, sizeof(socketHandler->command));
	if(n_read == -1){
		perror("read");
	}else if(n_read > 0){
		printf("\nget: %d,%s\n", n_read, socketHandler->command); 
	}else{
		printf("client quit\n");
	}
	
}

void* socket_thread(void *datas)
{
    pthread_t readthread;
    struct sockaddr_in c_addr;
	
	memset(&c_addr, 0, sizeof(struct sockaddr_in));
    int clen=sizeof(struct sockaddr_in);
	
	socketHandler = findCommandByName("socketServer", pCommandHead);

	if(socketHandler == NULL){
		printf("find socketHandler error\n");
		pthread_exit(NULL);
	}else{
        printf("%s init success\n",socketHandler->commandName);
    }
	socketHandler->Init(socketHandler, NULL, NULL);
	while(1){
		c_fd =accept(socketHandler->sfd, (struct sockaddr *)&c_addr, &clen);
		pthread_create(&readthread, NULL, read_thread, NULL);
	}
}

void *fireAlarm_thread(void * datas)
{
	int firestatus;

	struct Devices *fireTmp = NULL;
	fireTmp = findDeviceByName("fireIfOrNot",pdeviceHead);
	fireTmp->deviceInit(fireTmp->pinNum);
	while(1){
		firestatus = fireTmp->readStatus(fireTmp->pinNum);
		if(firestatus == 0){
			printf("fire happen\n");
			delay(1000);
		}
		if(firestatus == 1){
			printf("no fire!!!\n");
			delay(1000);
		}
	 	delay(1000);
	}
}


int main()
{
	char name[128];
	
	struct Devices *tmp = NULL;

	pthread_t voiceThread;
	pthread_t socketThread;
	pthread_t fireAlarmThread;
	
	//wiring库初始化
    if(wiringPiSetup() == -1){
        printf("wiringPi setup error!\n");
        return -1;
    }
	//1.指令工厂初始化
	pCommandHead = addvoiceContrlLightToDeviceLink(pCommandHead);
	pCommandHead = addsocketContrlLightToDeviceLink(pCommandHead);

	//2.设备控制初始化
	pdeviceHead = addBathroomLightToDeviceLink(pdeviceHead);
	pdeviceHead = addUpstairLightToDeviceLink(pdeviceHead);
	pdeviceHead = addLivingLightToDeviceLink(pdeviceHead);
	pdeviceHead = addrestaurantLightToDeviceLink(pdeviceHead);
	pdeviceHead = addPoolLightToDeviceLink(pdeviceHead);
	pdeviceHead = addFireToDeviceLink(pdeviceHead);
	
	// int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
	//3.线程池建立
	
    //3.1 语音线程
	pthread_create(&voiceThread, NULL, voice_thread, NULL);

	//3.2 socket线程
	pthread_create(&socketThread, NULL, socket_thread, NULL);
	
	//3.3 监控摄像头线程
	
	//3.4 火灾线程
	pthread_create(&fireAlarmThread, NULL , fireAlarm_thread ,NULL);
	

	pthread_join(voiceThread, NULL);    
    pthread_join(socketThread, NULL);
	pthread_join(fireAlarmThread,NULL);

	return 0;
}
  1. 外设设备的头文件 (contrlDevices.h)
#include <wiringPi.h>
#include <stdlib.h>

struct Devices
{
	char deviceName[128];
	int status;
	int pinNum;
	
	int (*open)(int pinNum);
	int (*close)(int pinNum);
	int (*deviceInit)(int pinNum);

	int (*readStatus)(int pinNum);
	int (*changeStatus)(int status);

	struct Devices *next;
};

struct Devices *addBathroomLightToDeviceLink(struct Devices *phead);
struct Devices* addUpstairLightToDeviceLink(struct Devices *phead);
struct Devices* addLivingLightToDeviceLink(struct Devices *phead);
struct Devices* addrestaurantLightToDeviceLink(struct Devices *phead);
struct Devices* addPoolLightToDeviceLink(struct Devices *phead);
struct Devices* addFireToDeviceLink(struct Devices *phead);
  1. 控制的头文件(inputCommand.h)
#include <wiringPi.h>
#include <stdlib.h>

struct InputCommander
{
	char commandName[128];
	char command[32];
	char deviceName[128];

	int (*Init)(struct InputCommander *voicer, char *ipAdress, char *port);
	int (*getCommand)(struct InputCommander *voicer);

	char log[1024];
	int fd;
	char port[12];
	char ipAddress[32];
	int sfd;

	struct InputCommander *next;
};

struct InputCommander* addvoiceContrlLightToDeviceLink(struct InputCommander* phead);
struct InputCommander* addsocketContrlLightToDeviceLink(struct InputCommander* phead); 
  1. 语音模块(voiceContrl.c)
#include <stdio.h>
#include <stdlib.h>
#include <wiringSerial.h>
#include <wiringPi.h>
#include <string.h>
#include <unistd.h>
#include "InputCommand.h"

int voiceGetCommand(struct InputCommander *voicer)
{
	int nread;
    memset(voicer->command, '\0', sizeof(voicer->command));
	serialGetchar(voicer->fd);
	nread = read(voicer->fd, voicer->command, sizeof(voicer->command));
	return nread;
}

int voiceInit(struct InputCommander *voicer, char *ipAdress, char *port)
{
	int fd;
    if((fd = serialOpen(voicer->deviceName,9600)) == -1){
        exit(-1);
    }
	voicer->fd = fd;
	return fd;
}

struct InputCommander voiceContrl  = {
	.commandName = "voice",
	.command = {'\0'},
	.deviceName = "/dev/ttyAMA0",
	.Init = voiceInit,
	.getCommand = voiceGetCommand,
	.log = {'\0'},
	.next = NULL
};

struct InputCommander* addvoiceContrlLightToDeviceLink(struct InputCommander* phead)
{
	if(phead == NULL){   
		return &voiceContrl;            
	}else{
		voiceContrl.next = phead;
		phead = &voiceContrl;
	}
}

  1. 火焰传感器fire.c
#include "contrlDevices.h"
#include <stdlib.h>
#include <stdio.h>

int fireIfOrNotInit(int pinNum)
{
	printf("fireIfOrNotInit pinNum = %d\n, pinNum");
	pinMode(pinNum, INPUT);
	//digitalWrite(pinNum, HIGH);
	digitalWrite(pinNum, HIGH);
}

int fireStatusRead(int pinNum)
{
	return digitalRead(pinNum);
}

struct Devices fireIfOrNot = {
	.deviceName = "fireIfOrNot",
	.pinNum = 28,
    .deviceInit = fireIfOrNotInit,
    .readStatus = fireStatusRead
};


struct Devices* addFireToDeviceLink(struct Devices *phead)
{
	if(phead == NULL){
		return &fireIfOrNot;
	}else{
		fireIfOrNot.next = phead;
		phead = &fireIfOrNot;
	}
	return phead;
}
  1. 浴室灯(bathroomLight.c)
#include "contrlDevices.h"
#include <stdlib.h>


int bathroomLightOpen(int pinNum)
{
	digitalWrite(pinNum, LOW);
}


int bathroomLightClose(int pinNum)
{
	digitalWrite(pinNum, HIGH);
}


int bathroomLightCloseInit(int pinNum)
{
	pinMode(pinNum, OUTPUT);
	digitalWrite(pinNum, HIGH);
}

int bathroomLightCloseStatus(int status)
{
	
}

struct Devices bathroomLight = {
	.deviceName = "bathroomLight",
	.pinNum = 22,
	.open = bathroomLightOpen,
    .close = bathroomLightClose,
    .deviceInit = bathroomLightCloseInit,
    .changeStatus = bathroomLightCloseStatus
};


struct Devices* addBathroomLightToDeviceLink(struct Devices *phead)
{
	if(phead == NULL){
		return &bathroomLight;
	}else{
		bathroomLight.next = phead;
		phead = &bathroomLight;
	}
	return phead;
}
  1. 卧室灯(livingroomLigth.c)
#include "contrlDevices.h"

int livingLightOpen(int pinNum)
{
	digitalWrite(pinNum, LOW);
}

int livingLightClose(int pinNum)
{
	digitalWrite(pinNum, HIGH);
}

int livingLightCloseInit(int pinNum)
{
	pinMode(pinNum, OUTPUT);
	digitalWrite(pinNum, HIGH);
}

int livingLightCloseStatus(int status)
{
	
}

struct Devices livingLight = {
	.deviceName = "livingLight",
	.pinNum = 23,
	.open = livingLightOpen,
    .close = livingLightClose,
    .deviceInit = livingLightCloseInit,
    .changeStatus = livingLightCloseStatus
};


struct Devices* addLivingLightToDeviceLink(struct Devices *phead)
{
	if(phead == NULL){
		return &livingLight;
	}else{
		livingLight.next = phead;
		phead = &livingLight;
	}
	return phead;
}
  1. 泳池灯(poolLight.c)
#include "contrlDevices.h"
#include <stdlib.h>


int poolLightOpen(int pinNum)
{
	digitalWrite(pinNum, LOW);
}

int poolLightClose(int pinNum)
{
	digitalWrite(pinNum, HIGH);
}

int poolLightCloseInit(int pinNum)
{
	pinMode(pinNum, OUTPUT);
	digitalWrite(pinNum, HIGH);
}

int poolLightCloseStatus(int status)
{
	
}

struct Devices poolLight = {
	.deviceName = "poolLight",
	.pinNum = 28,
	.open = poolLightOpen,
    .close = poolLightClose,
    .deviceInit = poolLightCloseInit,
    .changeStatus = poolLightCloseStatus
};


struct Devices* addPoolLightToDeviceLink(struct Devices *phead)
{
	if(phead == NULL){
		return &poolLight;
	}else{
		poolLight.next = phead;
		phead = &poolLight;
	}
	return phead;
}
  1. 厨房灯(restaurantLight.c)
#include "contrlDevices.h"

int restaurantLightOpen(int pinNum)
{
	digitalWrite(pinNum, LOW);
}

int restaurantLightClose(int pinNum)
{
	digitalWrite(pinNum, HIGH);
}

int restaurantLightCloseInit(int pinNum)
{
	pinMode(pinNum, OUTPUT);
	digitalWrite(pinNum, HIGH);
}

int restaurantLightCloseStatus(int status)
{
	
}

struct Devices restaurantLight = {
	.deviceName = "restaurantLight",
	.pinNum = 24,
	.open = restaurantLightOpen,
    .close = restaurantLightClose,
    .deviceInit = restaurantLightCloseInit,
    .changeStatus = restaurantLightCloseStatus
};


struct Devices* addrestaurantLightToDeviceLink(struct Devices *phead)
{
	if(phead == NULL){
		return &restaurantLight;
	}else{
		restaurantLight.next = phead;
		phead = &restaurantLight;
	}
	return phead;
}
  1. 客厅灯(upstairLight.c)
#include "contrlDevices.h"
#include <stdlib.h>


int upstairLightOpen(int pinNum)
{
	digitalWrite(pinNum, LOW);
}

int upstairLightClose(int pinNum)
{
	digitalWrite(pinNum, HIGH);
}

int upstairLightCloseInit(int pinNum)
{
	pinMode(pinNum, OUTPUT);
	digitalWrite(pinNum, HIGH);
}

int upstairLightCloseStatus(int status)
{
	
}

struct Devices upstairLight = {
	.deviceName = "upstairLight",
	.pinNum = 21,
	.open = upstairLightOpen,
    .close = upstairLightClose,
    .deviceInit = upstairLightCloseInit,
    .changeStatus = upstairLightCloseStatus
};


struct Devices* addUpstairLightToDeviceLink(struct Devices *phead)
{
	if(phead == NULL){
		return &upstairLight;
	}else{
		upstairLight.next = phead;
		phead = &upstairLight;
	}
	return phead;
}

运行结果

语音控制灯:

语音控制

火灾报警:

火灾报警

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值