功能描述
- 通过语音对灯光的控制
- 出现火灾时报警器响起
2.0待完成的功能有:
- 自行制作安卓App,通过App实现对外设的控制,灯光、风扇
- App还具有以下功能
- 显示监控画面+火灾报警+cpu温度+灯和锁状态
- 除视频监控外,可实现远程操作(内网穿透)
- 可控制摄像头功能(录像或监控画面显示)
- oled屏展示温湿度情况
- 人脸识别开锁
- 增加一块单片机作为子系统
硬件清单
- 树莓派3b
- 语音模块SU-03T
- 火焰传感器(3.3v,低电平有效)
- 4路继电器组(5v,低电平有效)
- 继电器(3.3v,低电平有效)
- 报警器喇叭
- 房子模型
- 面包板
- 电池盒
部分硬件截图:

由于报警器的声音实在是太响了,我选择把它包起来放进箱子里面,这样声音能减半。
主要思路
整体采用工厂模式的开发方式,主要分为指令工厂和设备工厂。
指令工厂串口、网络通信;设备工厂包括继电器控制灯、控制火灾、温湿度、报警器等模块设备。
每个功能会对应一条线程。
架构图如下(包含2.0待实现的思路)

代码如下
- 主程序(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;
}
- 外设设备的头文件 (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);
- 控制的头文件(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);
- 语音模块(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;
}
}
- 火焰传感器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;
}
- 浴室灯(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;
}
- 卧室灯(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;
}
- 泳池灯(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;
}
- 厨房灯(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;
}
- 客厅灯(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;
}
运行结果
语音控制灯:
语音控制
火灾报警:
火灾报警
该系统利用树莓派3B、语音模块和火焰传感器实现语音控制灯光,并在火灾时触发报警。此外,计划开发安卓App以远程控制灯光、风扇、监控画面及CPU温度,并集成温湿度显示、人脸识别开锁和摄像头功能。硬件包括继电器、传感器和报警器等,通过多线程处理不同功能,如语音识别线程负责处理语音指令,火灾检测线程监控火警状态。
734

被折叠的 条评论
为什么被折叠?



