该项目是基于香橙派(实现)的,用到的硬件模块有香橙派,继电器组,LED灯,语音模块,超声波模块,继电器,风扇,433M无线模块,蜂鸣器,火灾传感器,门锁。
该项目架构是简单工厂模式,将每一个功能写成一个文件,分控制工厂和设备工厂;用线程池放不同功能的线程
项目实现功能:
1.通过语音识别指令开关灯
2.通过网络开光灯
3.实现火灾报警
4.通过语音识别来实现人脸识别
5.遥控开启风扇(也可以开启空调(a原理一致))
6.超声波控制开关灯
7.人脸识别开关锁
bathroomLight.c
#include "contrlDevices.h"
int bathroomLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int bathroomLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int bathroomLightInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
struct Devices bathroomLight={
.deviceName="bathroomLight",
.pinNum=16, //引脚16控制的是浴室灯
.open=bathroomLightOpen,
.close=bathroomLightClose,
.deviceInit=bathroomLightInit
};
struct Devices* addBathroomLightDeviceLink(struct Devices *phead)
{
if(phead==NULL)
{
return &bathroomLight;
}
else
{
bathroomLight.next=phead;
phead=&bathroomLight;
return phead;
}
}
beep.c
#include "contrlDevices.h"
int beepOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int beepClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int beepInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
struct Devices beep={
.deviceName="beep",
.pinNum=2, //2脚控制的是蜂鸣器
.open=beepOpen,
.close=beepClose,
.deviceInit=beepInit
};
struct Devices* addBeepDeviceLink(struct Devices *phead)
{
if(phead==NULL)
{
return &beep;
}
else
{
beep.next=phead;
phead=&beep;
return phead;
}
}
camera.c
#include
#include
#include
#include
#include
#include
#include
#include "contrlDevices.h"
// 数据类型别名用typedef 有分号
#define true 1 // 宏定义(替换)用define 无冒号
#define false 0
char buf[1024] = {'\0'};
size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)
{
strncpy(buf, ptr, 1024);
}
char *getPic(char *pic)
{
char cmd[128] = {'\0'};
memset(cmd, '\0', 128);
sprintf(cmd, "base64 %s > tmpFile", pic);
system(cmd);
int fd = open("./tmpFile", O_RDWR);
int filelen = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
char *base64Buf = (char *)malloc(filelen + 8);
memset(base64Buf, '\0', filelen + 8);
read(fd, base64Buf, filelen + 8);
close(fd);
system("rm -f tmpFile");
return base64Buf;
}
char *getFacePic(char *pic)
{
printf("人脸数据采集中...\n");
system("sudo fswebcam -d /dev/video0 --no-banner -r 1280x720 -S 5 ./image.jpg");
while (access("./image.jpg", F_OK) != 0)
; // 判断是否拍照完毕
printf("数据采集完毕\n");
char *base64BufFaceRec = getPic("./image.jpg");
system("rm image.jpg"); // 采集完成删除,防止占内存
return base64BufFaceRec; // 返回刚才拍照的base64
}
int postUrl() // POST请求
{
CURL *curl;
CURLcode res;
char *postString = NULL;
char faceData[4][24] = {"./ly.jpg", "./reba.jpg", "./pyy1.jpg", "end"};
char *base64Buf1 = getPic("./pyy2.jpg");
char *key = "LgwugBLsKaggzYt4FsCtx5";
char *secret = "64b0c42971764ac0b7075c945a954ebc";
int typeld = 21;
char *format = "xml";
int i = 0;
int len = 0;
while (strcmp(faceData[0 + i], "end") != 0)
{
char *base64Buf2 = getPic(faceData[0 + i]);
printf("%s\n", faceData[0 + i]);
i++;
len = strlen(key) + strlen(secret) + strlen(format) + strlen(base64Buf1) + strlen(base64Buf2) + 128;
printf("%d", len);
postString = (char *)malloc(len);
sprintf(postString, "img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s", base64Buf1, base64Buf2, key, secret, typeld, format);
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString); // 指定post内容:用户信息 字段之间&连接,尝试登陆新浪邮箱
curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do"); // 指定url
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData);
res = curl_easy_perform(curl); // 执行
printf("res = %d\n", res);
if (strstr(buf, "是") != NULL)
{
printf("is same people\n");
return 2;
}
else
{
printf("is not the same people\n");
}
curl_easy_cleanup(curl);
}
}
printf("not have this people,error!\n");
return true;
}
struct Devices camera = {
.deviceName = "camera",
.url = postUrl
};
struct Devices *cameraLink(struct Devices *Phead)
{
if (Phead == NULL)
{
return &camera;
}
else
{
camera.next = Phead;
Phead = &camera;
return Phead;
}
}
原代码:上面的是整合后的样子
#include
#include
#include
#include
#include
#include
#include
#include
typedef unsigned int bool;//数据类型别名用typedef
#define true 1 //宏定义用define 就是宏替换
#define false 0
char ocrRetBuf[1024] = {'\0'};//全局变量,用来接收从OCR后台返回的数据
size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)//回调函数,把从后台的数据拷贝给ocrRetBuf
{
strncpy(ocrRetBuf,ptr,1024);
}
char* getBase64FromFile(char* filePath)
{
char* base64Buf = NULL;
char cmd[256] = {'\0'};
sprintf(cmd,"base64 %s > tmpFile",filePath);//图片的base64流导入到文件中
system(cmd);
int fd = open("./tmpFile",O_RDWR);
int fileLen = lseek(fd,0,SEEK_END); //计算文件大小
lseek(fd,0,SEEK_SET);
base64Buf = (char* )malloc(fileLen+8);
memset(base64Buf,'\0',fileLen+8);
read(fd,base64Buf,fileLen+8); //从文件中读取base64流到字符串
close(fd);
system("rm -f tmpFile");
return base64Buf;//指针变量随着子程序调用结束消失,但malloc开辟的空间地址还在,我拿到了这块地址,就能读
}
bool postUrl() //根据文档,接口调用方法为post请求
{
CURL *curl;
CURLcode res;
//根据翔云平台的接口要求 分开定义,然后字符串拼接
char* base64BufPic1 = getBase64FromFile("./jd1.jpg");//图片base64流
char* base64BufPic2 = getBase64FromFile("./jd2.jpg");
char* key = "Tnf7EDJaQ1qFZkow29xxxx";
char* secret = "66d49fdbfd4944ec93035f14ea14xxxx";
int typeId = 21;
char* format = "xml";
int len = strlen(key)+strlen(secret)+strlen(base64BufPic1)+strlen(base64BufPic2)+128;//分配空间不够会>导致栈溢出
char* postString = (char* )malloc(len);
memset(postString,'\0',len);//因为postString是一个指针,不能用sizeof来计算其指向的大小
//字符串拼接函数
sprintf(postString,"img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",base64BufPic1,base64BufPic2,key,secret,typeId,format);
curl = curl_easy_init();
if(curl){
//curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt");// 指定cookie缓存文件
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);//指定post传输内容,get请求将URL和postString一次性发送
curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");// 指定url
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData); //回调函数读取返回值
res = curl_easy_perform(curl);
printf("OK:%d\n",res);
if(strstr(ocrRetBuf,"否") != NULL){ //字符串检索 判断翔云后台返回的一大堆字符串中有没有“否”
printf("不是同一个人\n");
}
else{
printf("是同一个人\n");
}
curl_easy_cleanup(curl);
}
return true;
}
int main(void)
{
postUrl();
return 0;
}
fengshan.c
#include "contrlDevices.h"
int fengOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int fengClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int fengInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
struct Devices feng={
.deviceName="feng",
.pinNum=16, //引脚16控制的是浴室灯
.open= fengOpen,
.close=fengClose,
.deviceInit=fengInit
};
struct Devices* addFengDeviceLink(struct Devices *phead)
{
if(phead==NULL)
{
return &feng;
}
else
{
feng.next=phead;
phead=&feng;
return phead;
}
}
fire.c
#include "contrlDevices.h"
int fireAlarmInit(int pinNum)
{
pinMode(pinNum,INPUT); //火灾报警器要输入,读取电平
digitalWrite(pinNum,HIGH);
}
int fireAlarmReadStatus(int pinNum)
{
digitalRead(pinNum);
}
struct Devices fireAlarm={
.deviceName="fireAlarm",
.pinNum=6, //引脚6控制的是火焰传感器
.deviceInit= fireAlarmInit,
.readStatus=fireAlarmReadStatus
};
struct Devices* addFireAlarmDeviceLink(struct Devices *phead)
{
if(phead==NULL)
{
return &fireAlarm;
}
else
{
fireAlarm.next=phead;
phead=&fireAlarm;
return phead;
}
}
livingroomLight.c
#include "contrlDevices.h"
int livingroomLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int livingroomLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int livingroomLightInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
struct Devices livingroomLight={
.deviceName="livingroomLight",
.pinNum=13, //引脚13控制的是客厅灯
.open=livingroomLightOpen,
.close=livingroomLightClose,
.deviceInit=livingroomLightInit
};
struct Devices* addLivingroomLightDeviceLink(struct Devices *phead)
{
if(phead==NULL)
{
return &livingroomLight;
}
else
{
livingroomLight.next=phead;
phead=&livingroomLight;
return phead;
}
}
lock.c
#include "contrlDevices.h"
int lockOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int lockClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int lockInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
struct Devices lock={
.deviceName="lock",
.pinNum=1, //引脚1控制的是门锁
.open=lockOpen,
.close=lockClose,
.deviceInit=lockInit
};
struct Devices* addLockDeviceLink(struct Devices *phead)
{
if(phead==NULL)
{
return &lock;
}
else
{
lock.next=phead;
phead=&lock;
return phead;
}
}
remote.c
#include "contrlDevices.h"
int remoteInit(int pinNum)
{
pinMode(pinNum,INPUT); //火灾报警器要输入,读取电平
digitalWrite(pinNum,LOW);
}
int remoteReadStatus(int pinNum)
{
digitalRead(pinNum);
}
struct Devices remote={
.deviceName="remote",
.pinNum=14, //引脚6控制的是火焰传感器
.pinNum2=12,
.deviceInit= remoteInit,
.readStatus=remoteReadStatus
};
struct Devices* addRemoteDeviceLink(struct Devices *phead)
{
if(phead==NULL)
{
return &remote;
}
else
{
remote.next=phead;
phead=&remote;
return phead;
}
}
restaurantLight.c
#include "contrlDevices.h"
int restaurantLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int restaurantLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int restaurantLightInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
struct Devices restaurantLight={
.deviceName="restaurantLight",
.pinNum=10, //引脚10控制的是餐厅灯
.open= restaurantLightOpen,
.close=restaurantLightClose,
.deviceInit=restaurantLightInit
};
struct Devices* addRestaurantLightDeviceLink(struct Devices *phead)
{
if(phead==NULL)
{
return &restaurantLight;
}
else
{
restaurantLight.next=phead;
phead=&restaurantLight;
return phead;
}
}
upstairLight.c
#include "contrlDevices.h"
int upstairLightOpen(int pinNum)
{
digitalWrite(pinNum,LOW);
}
int upstairLightClose(int pinNum)
{
digitalWrite(pinNum,HIGH);
}
int upstairLightInit(int pinNum)
{
pinMode(pinNum,OUTPUT);
digitalWrite(pinNum,HIGH);
}
struct Devices upstairLight={
.deviceName="upstairLight",
.pinNum=15, //引脚15控制的是二楼灯
.open=upstairLightOpen,
.close=upstairLightClose,
.deviceInit=upstairLightInit
};
struct Devices* addUpstairLightDeviceLink(struct Devices *phead)
{
if(phead==NULL)
{
return &upstairLight;
}
else
{
upstairLight.next=phead;
phead=&upstairLight;
return phead;
}
}
socketContrl.c
#include "InputCommand.h"
/*
int socketGetcommand(struct InputCommander *socketMes)
{
int c_fd;
int n_read;
struct sockaddr_in c_addr;
memset(&c_addr, 0, sizeof(struct sockaddr_in));
// 4.accept
int clen = sizeof(struct sockaddr_in);
c_fd = accept(socketMes->sfd, (struct sockaddr *)&c_addr, &clen);
if (c_fd == -1)
{
perror("accept");
}
n_read = read(c_fd, socketMes->command, sizeof(socketMes->command));
if(n_read == -1)
{
perror("read");
}
else
{
printf("get message: %d ,%s\n", n_read, socketMes->command);
}
return n_read;
}
*/
int socketInit(struct InputCommander *socketMes, char *ipAdress, char *port)
{
int s_fd;
struct sockaddr_in s_addr;
memset(&s_addr, 0, sizeof(struct sockaddr_in));
// 1.socket
s_fd = socket(AF_INET, SOCK_STREAM, 0);
if (s_fd == -1)
{
perror("socked");
exit(-1);
}
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(atoi(socketMes->port));
inet_aton(socketMes->ipAdress, &s_addr.sin_addr);
// bind
bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));
// 3.listen
listen(s_fd, 10);
printf("socket sever listening....\n");
socketMes->sfd = s_fd;
return s_fd;
}
struct InputCommander socketContrl = {
.commandName = "socketServer",
.command = {'\0'},
.port = "8988",
.ipAdress = "192.168.251.50",
.Init = socketInit,
.log = {'\0'},
.next = NULL
};
struct InputCommander *addSocketCommandLink(struct InputCommander *phead)
{
if (phead == NULL)
{
return &socketContrl;
}
else
{
socketContrl.next = phead;
phead = &socketContrl;
return phead;
}
}
voiceContrl.c
#include "InputCommand.h"
int voiceGetcommand(struct InputCommander *voice)
{
int nread=0;
nread=read(voice->fd,voice->command,sizeof(voice->command));
return nread;
}
int voiceInit(struct InputCommander *voice,char *ipAdress,char *port)
{
int fd;
if ((fd = serialOpen (voice->deviceName, 115200)) < 0)
{
printf("open serial failed\n");
return 1 ;
}
voice->fd=fd;
return fd;
}
struct InputCommander voiceContrl={
.commandName="voice",
.deviceName="/dev/ttyS5",
.command={'\0'},
.Init=voiceInit,
.getCommand=voiceGetcommand,
.log={'\0'},
.next=NULL
};
struct InputCommander* addVoiceCommandLink(struct InputCommander *phead)
{
if(phead==NULL)
{
return &voiceContrl;
}
else
{
voiceContrl.next=phead;
phead=&voiceContrl;
return phead;
}
}
csbContrl.c
#include "InputCommand.h"
#define Trag 5
#define Echo 7
double getDistance()
{
double dis;
struct timeval time_start;
struct timeval time_stop;
pinMode(Trag,OUTPUT);
pinMode(Echo,INPUT);
digitalWrite(Trag,LOW);
usleep(5);
digitalWrite(Trag,HIGH);
usleep(10);
digitalWrite(Trag,LOW);
while(!digitalRead(Echo));
gettimeofday(&time_start,NULL);
while(digitalRead(Echo));
gettimeofday(&time_stop,NULL);
long longTime=1000000*(time_stop.tv_sec-time_start.tv_sec)+(time_stop.tv_usec-time_start.tv_usec);
// printf("longTime=%ld\n",longTime);
dis=(double)longTime/1000000*34000/2;
return dis;
}
struct InputCommander csbContrl={
.commandName="csb",
.getDistance=getDistance,
.log={'\0'},
.next=NULL
};
struct InputCommander* addCsbCommandLink(struct InputCommander *phead)
{
if(phead==NULL)
{
return &csbContrl;
}
else
{
csbContrl.next=phead;
phead=&csbContrl;
return phead;
}
}
mainPro.c
#include
#include
#include
#include
#include "InputCommand.h"
#include "contrlDevices.h"
struct Devices *pDevicehead = NULL;
struct InputCommander *pCommandhead = NULL;
struct InputCommander *sockettmp = NULL;
static int openVoice = 0;
static int openSocket = 0;
char ocrRetBuf[1024] = {'\0'}; // 全局变量,用来接收从OCR后台返回的数据
pthread_mutex_t mutex;
// 查找设备工厂的节点
struct Devices *findDeviceByName(char *name, struct Devices *phead)
{
struct Devices *tmp = phead;
if (phead == NULL)
{
return NULL;
}
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;
}
while (tmp != NULL)
{
if (strcmp(tmp->commandName, name) == 0)
{
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
// 打开所有设备
void openAllDevices(struct InputCommander *cmd)
{
struct Devices *tmp = NULL;
pthread_mutex_lock(&mutex);
if (strncmp("AO1", cmd->command, 3) == 0)
{
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
openVoice = 1;
}
pthread_mutex_unlock(&mutex);
}
// 关闭所有设备
void closeAllDevices(struct InputCommander *cmd)
{
struct Devices *tmp = NULL;
pthread_mutex_lock(&mutex);
if (strncmp("AC1", cmd->command, 3) == 0)
{
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
openVoice = 0;
}
pthread_mutex_unlock(&mutex);
}
// 语音控制设备
void voiceCommand(struct InputCommander *cmd)
{
struct Devices *tmp = NULL; // 设备节点
if (strncmp("O1", cmd->command, 2) == 0) // 语音打开浴室灯
{
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
openVoice = 1;
}
}
if (strncmp("O2", cmd->command, 2) == 0) // 语音打开二楼灯
{
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
openVoice = 1;
}
}
if (strncmp("O3", cmd->command, 2) == 0) // 语音打开客厅灯
{
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
openVoice = 1;
}
}
if (strncmp("O4", cmd->command, 2) == 0) // 语音打开餐厅灯
{
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
openVoice = 1;
}
}
if (strncmp("C1", cmd->command, 2) == 0) // 语音关闭浴室灯
{
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
openVoice = 0;
}
}
if (strncmp("C2", cmd->command, 2) == 0) // 语音关闭二楼灯
{
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
openVoice = 0;
}
}
if (strncmp("C3", cmd->command, 2) == 0) // 语音关闭客厅灯
{
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
openVoice = 0;
}
}
if (strncmp("C4", cmd->command, 2) == 0) // 语音打开餐厅灯
{
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
openVoice = 0;
}
}
openAllDevices(cmd); // 语音打开所有灯
closeAllDevices(cmd); // 语音关闭所有灯
if (strncmp("OCR", cmd->command, 3) == 0)
{
tmp = findDeviceByName("camera", pDevicehead);
if (tmp != NULL)
{
int mark = tmp->url();
if (mark == 2)
{
tmp = findDeviceByName("lock", pDevicehead);
if (tmp != NULL)
{
tmp->open(tmp->pinNum);
printf("已经为你开门!\n");
delay(10);
tmp->close(tmp->pinNum);
}
}
else
{
printf("人脸识别失败\n");
}
}
}
}
int get_cmd_type(struct InputCommander *cmd)
{
if (!strncmp("one", cmd->command, 3))
return 1;
if (!strncmp("two", cmd->command, 3))
return 2;
if (!strncmp("there", cmd->command, 3))
return 3;
if (!strncmp("four", cmd->command, 3))
return 4;
if (!strncmp("five", cmd->command, 3))
return 5;
if (!strncmp("six", cmd->command, 3))
return 6;
if (!strncmp("seven", cmd->command, 3))
return 7;
if (!strncmp("eight", cmd->command, 3))
return 8;
if (!strncmp("night", cmd->command, 3))
return 9;
if (!strncmp("ten", cmd->command, 3))
return 10;
return -1;
}
void socketCommand(struct InputCommander *cmd)
{
struct Devices *tmp = NULL;
int ret = 0;
ret = get_cmd_type(cmd);
printf("ret=%d\n", ret);
switch (ret)
{
case 1:
printf("open bathroomLight\n");
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
printf("open bathroomLight success\n");
}
break;
case 2:
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
break;
case 3:
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
break;
case 4:
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
break;
case 5:
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
break;
case 6:
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
break;
case 7:
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
break;
case 8:
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
break;
case 9:
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
break;
case 10:
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
break;
}
}
void *firehandler()
{
struct Devices *firetmp = NULL;
struct Devices *beeptmp = NULL;
char *firename = "fireAlarm";
char *beepname = "beep";
int firestatus;
while (1)
{
firetmp = findDeviceByName(firename, pDevicehead);
// printf("%s\n",firetmp->deviceName);
if (firetmp != NULL)
{
firetmp->deviceInit(firetmp->pinNum);
firestatus = firetmp->readStatus(firetmp->pinNum);
}
beeptmp = findDeviceByName(beepname, pDevicehead);
// printf("%s\n", beeptmp->deviceName);
if (beeptmp != NULL)
{
if (firestatus == 0)
{
// printf("报警\n");
beeptmp->deviceInit(beeptmp->pinNum);
beeptmp->open(beeptmp->pinNum);
}
else
{
// printf("安全\n");
beeptmp->deviceInit(beeptmp->pinNum);
beeptmp->close(beeptmp->pinNum);
}
}
}
}
void *voicehandler()
{
struct InputCommander *voicetmp = NULL;
int nread = 0;
voicetmp = findCommandByName("voice", pCommandhead); // 查找链表中的节点,通过名字来检索
if (voicetmp == NULL)
{
printf("find voicetmp error\n");
pthread_exit(NULL);
}
else
{
if (voicetmp->Init(voicetmp, NULL, NULL) < 0)
{
printf("voice init error\n");
}
printf("%s init success\n", voicetmp->commandName);
while (1)
{
memset(voicetmp->command, 0, sizeof(voicetmp->command));
nread = voicetmp->getCommand(voicetmp);
if (nread == -1)
{
printf("no data from voice\n");
}
else
{
printf("nread:%d,get data->%s\n", nread, voicetmp->command);
voiceCommand(voicetmp); // 语音控制设备
openVoice=1;
}
}
}
}
void *readhandler()
{
int nread = 0;
while (1)
{
memset(sockettmp->command, 0, sizeof(sockettmp->command));
nread = read(sockettmp->fd, sockettmp->command, sizeof(sockettmp->command));
if (nread == -1)
{
printf("no data from socket\n");
}
else if (nread == 0) // 防止客户端退出,服务端崩掉
{
printf("client out\n");
break;
}
else
{
printf("get data:%s\n", sockettmp->command);
socketCommand(sockettmp);
openSocket=1;
}
}
}
void *sockethandler()
{
int c_fd;
pthread_t read_t;
struct sockaddr_in c_addr;
memset(&c_addr, 0, sizeof(struct sockaddr_in));
int clen = sizeof(struct sockaddr_in);
sockettmp = findCommandByName("socketServer", pCommandhead); // 查找链表中的节点,通过名字来检索
if (sockettmp == NULL)
{
printf("find voicetmp error\n");
pthread_exit(NULL);
}
else
{
if (sockettmp->Init(sockettmp, NULL, NULL) < 0)
{
printf("perror:\n");
}
printf("%s init success\n", sockettmp->commandName);
while (1)
{
c_fd = accept(sockettmp->sfd, (struct sockaddr *)&c_addr, &clen);
if (c_fd == -1)
{
perror("accept");
}
sockettmp->fd = c_fd;
pthread_create(&read_t, NULL, readhandler, NULL);
}
}
}
void *remotehandler()
{
struct Devices *remotetmp = NULL;
struct Devices *fengtmp = NULL;
int onstatus;
int offstatus;
while (1)
{
remotetmp = findDeviceByName("remote", pDevicehead);
// printf("%s\n",firetmp->deviceName);
if (remotetmp != NULL)
{
remotetmp->deviceInit(remotetmp->pinNum);
onstatus = remotetmp->readStatus(remotetmp->pinNum);
remotetmp->deviceInit(remotetmp->pinNum2);
offstatus = remotetmp->readStatus(remotetmp->pinNum2);
}
fengtmp = findDeviceByName("feng", pDevicehead);
// printf("%s\n", beeptmp->deviceName);
if (fengtmp != NULL)
{
if (onstatus == 1)
{
// printf("开启\n");
fengtmp->deviceInit(fengtmp->pinNum);
fengtmp->open(fengtmp->pinNum);
}
if (offstatus == 0)
{
// printf("关闭\n");
fengtmp->deviceInit(fengtmp->pinNum);
fengtmp->close(fengtmp->pinNum);
}
}
}
}
void *openhandler()
{
struct Devices *tmp = NULL;
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->open(tmp->pinNum);
}
usleep(500000);
}
void *closehandler()
{
struct Devices *tmp = NULL;
tmp = findDeviceByName("bathroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
tmp = findDeviceByName("upstairLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
tmp = findDeviceByName("livingroomLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
tmp = findDeviceByName("restaurantLight", pDevicehead);
if (tmp != NULL)
{
tmp->deviceInit(tmp->pinNum);
tmp->close(tmp->pinNum);
}
usleep(500000);
}
void *csbhandler()
{
struct InputCommander *csbtmp = NULL;
struct Devices *tmp = NULL;
pthread_t open_t;
pthread_t close_t;
double dis = 0;
csbtmp = findCommandByName("csb", pCommandhead); // 查找链表中的节点,通过名字来检索
if (csbtmp == NULL)
{
printf("find csbtmp error\n");
pthread_exit(NULL);
}
else
{
printf("find csb success\n");
while (1)
{
dis = csbtmp->getDistance();
if (dis < 10)
{
printf("dis=%lf\n", dis);
pthread_create(&open_t, NULL, openhandler, NULL);
// sleep(5);
//pthread_exit(NULL);
}
else
{
printf("dis=%lf\n", dis);
pthread_create(&close_t, NULL, closehandler, NULL);
}
}
}
}
int main()
{
// char name[128] = {0};
pthread_t fire_t;
pthread_t voice_t;
pthread_t socket_t;
pthread_t remote_t;
pthread_t csb_t;
pthread_t oled_t;
if (wiringPiSetup() == -1)
{
printf("init error\n");
return -1;
}
// 指令工厂初始化
pCommandhead = addVoiceCommandLink(pCommandhead); // 把对应指令节点加入到指令工厂
pCommandhead = addSocketCommandLink(pCommandhead);
pCommandhead = addCsbCommandLink(pCommandhead);
// 设备工厂初始化
pDevicehead = addBathroomLightDeviceLink(pDevicehead); // 把对应的设备节点加入到设备工厂
pDevicehead = addUpstairLightDeviceLink(pDevicehead);
pDevicehead = addLivingroomLightDeviceLink(pDevicehead);
pDevicehead = addRestaurantLightDeviceLink(pDevicehead);
pDevicehead = addFireAlarmDeviceLink(pDevicehead);
pDevicehead = addBeepDeviceLink(pDevicehead);
pDevicehead = addFengDeviceLink(pDevicehead);
pDevicehead = addRemoteDeviceLink(pDevicehead);
pDevicehead = cameraLink(pDevicehead);
pDevicehead = addLockDeviceLink(pDevicehead);
pthread_mutex_init(&mutex, NULL);
// 语音线程
pthread_create(&voice_t, NULL, voicehandler, NULL); // 语音控制设备
// socket线程
pthread_create(&socket_t, NULL, sockethandler, NULL); // 网络控制设备
// 火灾报警线程
pthread_create(&fire_t, NULL, firehandler, NULL); // 火灾报警
// 风扇线程
pthread_create(&remote_t, NULL, remotehandler, NULL);
// 超声波线程
pthread_create(&csb_t, NULL, csbhandler, NULL);
// oled线程
pthread_create(&oled_t,NULL,oledhandler,NULL);
pthread_join(fire_t, NULL);
pthread_join(voice_t, NULL);
pthread_join(socket_t, NULL);
pthread_join(remote_t, NULL);
pthread_join(csb_t, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
contrlDevices.h
#include
#include
struct Devices
{
char deviceName[128]; //设备名
int status; //设备状态
int pinNum;
int pinNum2; //第二个引脚
int (*open)(int pinNum); //打开设备
int (*close)(int pinNum); //关闭设备
int (*deviceInit)(int pinNum); //设备初始化
int (*readStatus)(int pinNum); //读取设备状态
int (*chageStatus)(int status); //改变设备状态
int (*url)();
struct Devices* next;
};
struct Devices* addBathroomLightDeviceLink(struct Devices *phead);
struct Devices* addUpstairLightDeviceLink(struct Devices *phead);
struct Devices* addLivingroomLightDeviceLink(struct Devices *phead);
struct Devices* addRestaurantLightDeviceLink(struct Devices *phead);
struct Devices* addFireAlarmDeviceLink(struct Devices *phead);
struct Devices* addBeepDeviceLink(struct Devices *phead);
struct Devices* addFengDeviceLink(struct Devices *phead);
struct Devices* addLockDeviceLink(struct Devices *phead);
struct Devices* addRemoteDeviceLink(struct Devices *phead);
struct Devices *cameraLink(struct Devices *Phead);
struct Devices* addLockDeviceLink(struct Devices *phead);
InputCommand.h
#include
#include
#include
#include
#include
#include
#include
#include /* See NOTES */
#include
#include
#include
#include
#include
#define one 1
#define two 2
#define there 3
#define four 4
#define five 5
#define six 6
#define seven 7
#define eight 8
#define night 9
#define ten 10
struct InputCommander
{
char commandName[128]; //控制设备的指令名
char deviceName[128];
char command[128]; //发送的指令
int (*Init)(struct InputCommander *name,char *ipAdress,char *port); //初始化语音和网络
int (*getCommand)(struct InputCommander *cmd); //读取指令
double (*getDistance)();
char log[1024]; //日志
char port[12];
char ipAdress[32];
int sfd;
int fd;
struct InputCommander *next;
};
struct InputCommander* addVoiceCommandLink(struct InputCommander *phead);
struct InputCommander *addSocketCommandLink(struct InputCommander *phead);
struct InputCommander* addCsbCommandLink(struct InputCommander *phead);
通过这个项目,我学习到了第三方库的使用,分析语音sdk和工厂模式,也得到了综合锻炼。