一.功能介绍

1.通过手机端网络调试助手,语音识别,对灯光,风扇,等电器进行远程控制。

 2.通过火焰报警,震动报警,视频监控等功能保证家庭的安全。

3.实时将环境温湿度数据,各种安防信息发送到客户端进行显示。

4.通过红外遥控也能对部分家电进行远程控制。

5.通过翔云平台提供的人脸对比识别服务,实现人脸识别开锁功能。

二.实物展示

   

                 人脸识别按钮和门锁                                                433m红外接收模块

                         摄像头                                                        火焰报警和雨滴传感器

    手机端实时显示环境状态            手机端通过指令控制家电                  网页实时视频监控

 三.程序

 编译运行:

 1.mainPro.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include"InputCommand.h"

#include"contrlDevices.h"

//为了线程里能调到链表头,要把这两个表头设置为全局变量

struct Devices *pdeviceHead = NULL;

struct InputCommander *pCommandHead = NULL;

struct InputCommander *socketHandler = NULL;

int c_fd;

//定义互斥量(锁)

pthread_mutex_t mutex;

typedef unsigned char uint8;

typedef unsigned int uint16;

typedef unsigned long uint32;

#define HIGH_TIME 32

pthread_t writeThread;

pthread_t voiceThread;

pthread_t socketThread;

pthread_t fireThread;

pthread_t DHT11Thread;

pthread_t readThread;

pthread_t shakeThread;

pthread_t windowThread;

pthread_t keyThread;

pthread_t cameraThread;

pthread_t remoteThread;

int tmp = 0;//设置火灾和振动的标志位

int wintmp1 = 0;

int wintmp2 = 0;

#define key 6 //拍照按键

char Message[4][100] = {"未启用!", "未启用!", "未启用!", "未启用!"};

int write_flag = 0; //标记位,标记通知线程是否打开 1:打开 0:关闭

int a = 0;

int b = 0;

extern uint32 databuf;

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 *window_thread(void *datas)

{

struct Devices *windowDeviceTmp = NULL;

windowDeviceTmp = findDeviceByName("window", pdeviceHead);

if(windowDeviceTmp == NULL)

{

printf("find window error\n");

pthread_exit(NULL);

}

windowDeviceTmp->deviceInit(windowDeviceTmp->pinNum);

while(1){

if(digitalRead(5) == 0){ //没雨 开窗 5引脚就是检测是否有雨水

sleep(1);

b = 1;

if(a != 0){

windowDeviceTmp->open(windowDeviceTmp->pinNum);//正转 开窗

sleep(5);

windowDeviceTmp->deviceInit(windowDeviceTmp->pinNum);//停

while(digitalRead(5) == 0);

}

}

else if(digitalRead(5) == 1){

sleep(1);

a = 1;

if(b != 0){

windowDeviceTmp->close(windowDeviceTmp->pinNum);//反转 关窗

sleep(5);

windowDeviceTmp->deviceInit(windowDeviceTmp->pinNum);//停

while(digitalRead(5) == 1);

}

}

}

}

void *shake_thread(void *datas) //震动线程

{

int tmp1 = 0;

struct Devices *shakeDeviceTmp = NULL;

struct Devices *shakebuzzerDeviceTmp = NULL;

shakeDeviceTmp = findDeviceByName("shake", pdeviceHead); //在设备工厂找到震动模块和震动蜂鸣器

shakebuzzerDeviceTmp = findDeviceByName("shakebuzzer", pdeviceHead);

if((shakeDeviceTmp == NULL)&&(shakebuzzerDeviceTmp == NULL))

{

printf("find shake or shakebuzzer error\n");

pthread_exit(NULL);

}

shakeDeviceTmp->deviceInit(shakeDeviceTmp->pinNum); //震动初始化

shakebuzzerDeviceTmp->deviceInit(shakebuzzerDeviceTmp->pinNum);//蜂鸣器初始化

while(1)

{

//tmp = 1;

if(digitalRead(26) == 1)

{

shakebuzzerDeviceTmp->open(shakebuzzerDeviceTmp->pinNum); //开震动蜂鸣器

delay(3);

shakebuzzerDeviceTmp->close(shakebuzzerDeviceTmp->pinNum);

memset(Message[3], 0, sizeof Message[3]); //清空数组

sprintf(Message[3], "无震动 "); //更新震动信息

}

else

{

memset(Message[3], 0, sizeof Message[3]); //清空数组

sprintf(Message[3], "有震动! ");

shakebuzzerDeviceTmp->close(shakebuzzerDeviceTmp->pinNum); //关震动蜂鸣器

}

}

}

void *fire_thread(void *datas) //火灾线程

{

struct Devices *fireDeviceTmp = NULL;

struct Devices *buzzerDeviceTmp = NULL;

fireDeviceTmp = findDeviceByName("fireIfOrNot", pdeviceHead); //在设备工厂找到火焰模块和火焰蜂鸣器

buzzerDeviceTmp = findDeviceByName("buzzer", pdeviceHead);

if((fireDeviceTmp == NULL)&&(buzzerDeviceTmp == NULL))

{

printf("find fire or buzzer error\n");

pthread_exit(NULL);

}

fireDeviceTmp->deviceInit(fireDeviceTmp->pinNum); //火灾模块初始化

buzzerDeviceTmp->deviceInit(buzzerDeviceTmp->pinNum);//蜂鸣器初始化

while(1)

{

if(digitalRead(25) == 1)

{

buzzerDeviceTmp->open(buzzerDeviceTmp->pinNum); //开火灾蜂鸣器

memset(Message[2], 0, sizeof Message[2]); //清空数组

sprintf(Message[2], "无火灾"); //更新火灾信息

}

else

{

buzzerDeviceTmp->close(buzzerDeviceTmp->pinNum); //关火灾蜂鸣器

memset(Message[2], 0, sizeof Message[2]); //清空数组

sprintf(Message[2], "有火灾! ");

tmp = 0;

}

}

}

void *voice_thread(void* datas)//语音线程

{

struct InputCommander *voiceHandler;

struct Devices *deviceTmp = NULL;

int nread;

voiceHandler = findCommandByName("voice", pCommandHead);//找语音节点

if(voiceHandler == NULL)

{

printf("find voice 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);

}

pthread_mutex_lock(&mutex); //加锁

//语音读取一级指令的时候,为了避免其它线程对于 紧接着读取二级指令的干扰

while(1)

{ //读数据

memset(voiceHandler->command, '\0', sizeof(voiceHandler->command));

nread = voiceHandler->getCommand(voiceHandler);//获取语音模块发来的数据

printf("get voice command:%s\n", voiceHandler->command);

if(nread == 0)

{

printf("nodata from voice\n");

}

else if(strstr(voiceHandler->command, "kycd") != NULL) //1如果收到数据

{

deviceTmp = findDeviceByName("livingRoomLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开泳池灯

}

else if(strstr(voiceHandler->command, "gycd") != NULL)

{

deviceTmp = findDeviceByName("livingRoomLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关泳池灯

}

else if(strstr(voiceHandler->command, "kwsd") != NULL) //

{

deviceTmp = findDeviceByName("upstairLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开卧室灯

}

else if(strstr(voiceHandler->command, "gwsd") != NULL)

{

deviceTmp = findDeviceByName("upstairLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关卧室灯

}

else if(strstr(voiceHandler->command, "kysd") != NULL)

{

deviceTmp = findDeviceByName("bathroomLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开浴室灯

}

else if(strstr(voiceHandler->command, "gysd") != NULL)

{

deviceTmp = findDeviceByName("bathroomLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关浴室灯

}

else if(strstr(voiceHandler->command, "kcfd") != NULL)

{

deviceTmp = findDeviceByName("restauranLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开厨房灯

}

else if(strstr(voiceHandler->command, "gcfd") != NULL)

{

deviceTmp = findDeviceByName("restauranLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关厨房灯

}

else if(strstr(voiceHandler->command, "kfs") != NULL) //开风扇

{

deviceTmp = findDeviceByName("fan",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);

}

else if(strstr(voiceHandler->command, "gfs") != NULL) //关风扇

{

deviceTmp = findDeviceByName("fan",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);

}

else if(strstr(voiceHandler->command, "quankai") != NULL)

{

deviceTmp = findDeviceByName("livingRoomLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开泳池灯

deviceTmp = findDeviceByName("upstairLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开卧室灯

deviceTmp = findDeviceByName("bathroomLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开浴室灯

deviceTmp = findDeviceByName("restauranLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开厨房灯

deviceTmp = findDeviceByName("fan",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开风扇

}

else if(strstr(voiceHandler->command, "quanguan") != NULL) //如果收到数据

{

deviceTmp = findDeviceByName("livingRoomLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关泳池灯

deviceTmp = findDeviceByName("upstairLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关卧室灯

deviceTmp = findDeviceByName("bathroomLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关浴室灯

deviceTmp = findDeviceByName("restauranLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关厨房灯

deviceTmp = findDeviceByName("fan",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关风扇

}

}

}

}

void *read_thread(void *datas)

{

int n_read;

struct Devices *deviceTmp = NULL;

while(1)

{

memset(socketHandler->command, '\0', sizeof(socketHandler->command));

n_read = read(c_fd, socketHandler->command, sizeof(socketHandler->command));//客户端发来的数据存到 socketHandler->command

if(n_read == -1){

perror("read");

}

else if(n_read > 0){

printf("\nget: %d,%s\n",n_read,socketHandler->command);//打印客户端发来的数据

//if (strstr(socketHandler->command, "kwsd") != NULL)

if(strstr(socketHandler->command, "kycd") != NULL) //1如果收到数据

{

deviceTmp = findDeviceByName("livingRoomLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开泳池灯

}

else if(strstr(socketHandler->command, "gycd") != NULL)

{

deviceTmp = findDeviceByName("livingRoomLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关泳池灯

}

else if(strstr(socketHandler->command, "kwsd") != NULL) //

{

deviceTmp = findDeviceByName("upstairLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开卧室灯

}

else if(strstr(socketHandler->command, "gwsd") != NULL)

{

deviceTmp = findDeviceByName("upstairLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关卧室灯

}

else if(strstr(socketHandler->command, "kysd") != NULL)

{

deviceTmp = findDeviceByName("bathroomLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开浴室灯

}

else if(strstr(socketHandler->command, "gysd") != NULL)

{

deviceTmp = findDeviceByName("bathroomLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关浴室灯

}

else if(strstr(socketHandler->command, "kcfd") != NULL)

{

deviceTmp = findDeviceByName("restauranLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开厨房灯

}

else if(strstr(socketHandler->command, "gcfd") != NULL)

{

deviceTmp = findDeviceByName("restauranLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关厨房灯

}

else if(strstr(socketHandler->command, "kfs") != NULL) //开风扇

{

deviceTmp = findDeviceByName("fan",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);

}

else if(strstr(socketHandler->command, "gfs") != NULL) //关风扇

{

deviceTmp = findDeviceByName("fan",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);

}

else if(strstr(socketHandler->command, "quankai") != NULL)

{

deviceTmp = findDeviceByName("livingRoomLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开泳池灯

deviceTmp = findDeviceByName("upstairLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开卧室灯

deviceTmp = findDeviceByName("bathroomLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开浴室灯

deviceTmp = findDeviceByName("restauranLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开厨房灯

deviceTmp = findDeviceByName("fan",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->open(deviceTmp->pinNum);//开风扇

}

else if(strstr(socketHandler->command, "quanguan") != NULL) //如果收到数据

{

deviceTmp = findDeviceByName("livingRoomLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关泳池灯

deviceTmp = findDeviceByName("upstairLight",pdeviceHead);//通过名子找到节点

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关卧室灯

deviceTmp = findDeviceByName("bathroomLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关浴室灯

deviceTmp = findDeviceByName("restauranLight",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关厨房灯

deviceTmp = findDeviceByName("fan",pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);//初始化

deviceTmp->close(deviceTmp->pinNum);//关风扇

}

}

else{

printf("client quit\n");

write_flag = 0;

pthread_cancel(writeThread);

pthread_exit(NULL);

}

}

}

void *write_thread(void *datas) //实时向客户端发送消息

{

while (1)

{

delay(1000);

write(c_fd, Message, 400);

}

}

void *socket_thread(void* datas)

{

int n_read = 0;

struct sockaddr_in c_addr;

memset(&c_addr, 0, sizeof(struct sockaddr_in));

int clen = sizeof(struct sockaddr_in);

socketHandler = findCommandByName("socketServer", pCommandHead);//找socket节点

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);//读客户端发来的数据

if (write_flag == 0){

write_flag = 1;

pthread_create(&writeThread, NULL, write_thread, NULL);//往客户端发数据 比如温湿度

}

}

}

void *DHT11_thread(void* datas)

{

struct Devices *DHT11DeviceTmp = NULL;

DHT11DeviceTmp = findDeviceByName("DHT11", pdeviceHead); //在设备工厂找到温湿度模块

DHT11DeviceTmp->deviceInit(DHT11DeviceTmp->pinNum); //温湿度模块初始化

while (1)

{

//pinMode(7, OUTPUT); // set mode to output

// digitalWrite(7, 1); // output a high level

delay(3000);

if (DHT11DeviceTmp->deviceInit(DHT11DeviceTmp->pinNum))

{

// printf("Sensor data read ok!\n");

memset(Message[0], 0, sizeof Message[0]); //清空数组

memset(Message[1], 0, sizeof Message[1]);

sprintf(Message[0], "湿度:%d.%d ", (databuf >> 24) & 0xff, (databuf >> 16) & 0xff);

sprintf(Message[1], "温度:%d.%d ", (databuf >> 8) & 0xff, databuf & 0xff);

//printf("shidu = %d.%d\n", (databuf >> 24) & 0xff, (databuf >> 16) & 0xff);

//printf("wendu = %d.%d\n", (databuf >> 8) & 0xff, databuf & 0xff);

databuf = 0;

}

else

{

printf("Sensor dosent ans!\n");

databuf = 0;

}

}

}

void *remote_thread(void *datas)//433m线程

{

int val0 = 0, val1 = 0, val2 = 0, val3 = 0;

int temp0 = 0, temp1 = 0,temp2 = 0,temp3 = 0;

int count0 = 0, count1 = 0, count2 = 0, count3 = 0;

struct Devices *deviceTmp = NULL;

wiringPiSetup();

pinMode(12, INPUT);

pinMode(13, INPUT);

pinMode(14, INPUT);

pinMode(30, INPUT);

digitalWrite(12, LOW);

digitalWrite(13, LOW);

digitalWrite(14, LOW);

digitalWrite(30, LOW);

while(1)

{

val0 = digitalRead(12);

val1 = digitalRead(13);

val2 = digitalRead(14);

val3 = digitalRead(30);

if (val0 == 1) //电风扇遥控信号

{

if(count0 == 0)

{

delay(500);

if (temp0 == 0) //打开厨房灯

{

printf("433M:open restauranLight\n");

temp0 = 1;

deviceTmp = findDeviceByName("restauranLight", pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);

deviceTmp->open(deviceTmp->pinNum);

while(val0 == 0);

}

else if (temp0 == 1) //关闭厨房灯

{

printf("433M:close restauranLight\n");

temp0 = 0;

deviceTmp = findDeviceByName("restauranLight", pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);

deviceTmp->close(deviceTmp->pinNum);

}

count0 = 1;

}

}

else if (val0 == 0)

{

count0 = 0;

}

if (val1 == 1) //泳池灯遥控信号

{

if(count1 == 0)

{

delay(500);

if (temp1 == 0) //打开泳池灯

{

printf("433M:open livingRoomLight\n");

temp1 = 1;

deviceTmp = findDeviceByName("livingRoomLight", pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);

deviceTmp->open(deviceTmp->pinNum);

while(val1 == 0);

}

else if (temp1 == 1) //关闭泳池灯

{

printf("433M:close livingRoomLight\n");

temp1 = 0;

deviceTmp = findDeviceByName("livingRoomLight", pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);

deviceTmp->close(deviceTmp->pinNum);

}

count1 = 1;

}

}

else if (val1 == 0)

{

count1 = 0;

}

if (val2 == 1) //卧室灯遥控信号

{

if(count2 == 0)

{

delay(500);

if (temp2 == 0) //打开卧室灯

{

printf("433M:open upstairLight\n");

temp2 = 1;

deviceTmp = findDeviceByName("upstairLight", pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);

deviceTmp->open(deviceTmp->pinNum);

while(val2 == 0);

}

else if (temp2 == 1) //关闭卧室灯

{

printf("433M:close upstairLight\n");

temp2 = 0;

deviceTmp = findDeviceByName("upstairLight", pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);

deviceTmp->close(deviceTmp->pinNum);

}

count2 = 1;

}

}

else if (val2 == 0)

{

count2 = 0;

}

if (val3 == 1) //浴室灯遥控信号

{

if(count3 == 0)

{

delay(500);

if (temp3 == 0) //打开浴室灯

{

printf("433M:open bathroomLight\n");

temp3 = 1;

deviceTmp = findDeviceByName("bathroomLight", pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);

deviceTmp->open(deviceTmp->pinNum);

while(val3 == 0);

}

else if (temp3 == 1) //关闭浴室灯

{

printf("433M:close bathroomLight\n");

temp3 = 0;

deviceTmp = findDeviceByName("bathroomLight", pdeviceHead);

deviceTmp->deviceInit(deviceTmp->pinNum);

deviceTmp->close(deviceTmp->pinNum);

}

count3 = 1;

}

}

else if (val3 == 0)

{

count3 = 0;

}

}

}

void *cameraThread_func(void *data) //起线程的函数有格式要求

{

struct Devices *cameraTemp;

cameraTemp = findDeviceByName("camera", pdeviceHead); //找到摄像头节点

if (cameraTemp == NULL)

{

printf("find camera error\n");

pthread_exit(NULL); //在线程中不用return

}

cameraTemp->justDoOnce(); //调用postUrl函数

}

void *key_thread()

{

// pinMode(door_Lock, OUTPUT); //将门锁端口置为输出

int val;

while (1)

{

val = digitalRead(key);

// printf("key = %d\n", val);

if (val == 0) //防止重复检测

{

delay(500);

val = digitalRead(key);

// printf("key = %d\n", val);

if (val == 1) //按键按下,启动人脸识别线程

{

pthread_create(&cameraThread, NULL, cameraThread_func, NULL);

}

}

}

}

int main()

{

char name[128];

struct Devices *tmp = NULL;

if(-1 == wiringPiSetup()){

return -1;

}

//1.指令工厂初始化

pCommandHead = addvoiceContrlToInputCommandLink(pCommandHead);//语音

pCommandHead = addSocketContrlToInputCommandLink(pCommandHead);//socket

//2.设备控制工厂初始化

pdeviceHead = addBathroomLightToDeviceLink(pdeviceHead);

pdeviceHead = addUpstairLightToDeviceLink(pdeviceHead);

pdeviceHead = addRestauranLightToDeviceLink(pdeviceHead);

pdeviceHead = addLivingRoomLightToDeviceLink(pdeviceHead);

pdeviceHead = addfireToDeviceLink(pdeviceHead);//火灾模块

pdeviceHead = addbuzzerToDeviceLink(pdeviceHead);//火灾蜂鸣器

pdeviceHead = addshakebuzzerToDeviceLink(pdeviceHead);//震动蜂鸣器

pdeviceHead = addfanToDeviceLink(pdeviceHead);

pdeviceHead = addDHT11ToDeviceLink(pdeviceHead);

pdeviceHead = addcameraToDeviceLink(pdeviceHead);//摄像头

pdeviceHead = addShakeToDeviceLink(pdeviceHead);//震动模块

pdeviceHead = addwindowToDeviceLink(pdeviceHead);

//3.线程池建立

//int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)

//3.1 语音线程

pthread_create(&voiceThread, NULL, voice_thread, NULL);

//3.2 socket线程

pthread_create(&socketThread, NULL, socket_thread, NULL);

//3.3火灾线程

pthread_create(&fireThread, NULL, fire_thread, NULL);

//3.4 摄像头线程 这里把摄像头设为了开机自启

//3.5 温湿度线程

pthread_create(&DHT11Thread, NULL, DHT11_thread, NULL);

//3.6 震动线程

pthread_create(&shakeThread, NULL, shake_thread, NULL);

//3.7 窗户线程

pthread_create(&windowThread, NULL, window_thread, NULL);

//3.8 按钮线程

pthread_create(&keyThread, NULL, key_thread, NULL);

//3.9 433m线程

pthread_create(&remoteThread, NULL, remote_thread, NULL);

pthread_join(voiceThread, NULL);

pthread_join(socketThread, NULL);

pthread_join(fireThread, NULL);

pthread_join(DHT11Thread, NULL);

pthread_join(writeThread, NULL);

pthread_join(shakeThread, NULL);

pthread_join(windowThread, NULL);

pthread_join(keyThread, NULL);

pthread_join(cameraThread, NULL);

pthread_join(remoteThread, NULL);

return 0;

}

contrlDevices.h

#include

#include

#include

typedef unsigned int bool;

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);

//摄像头相关的

void (*justDoOnce)();

char* (*getFace)();

char* (*getPicFromOCRBase64)();

size_t (*readData)();

struct Devices *next;

};

struct Devices* addBathroomLightToDeviceLink(struct Devices *phead);

struct Devices* addUpstairLightToDeviceLink(struct Devices *phead);

struct Devices* addRestauranLightToDeviceLink(struct Devices *phead);

struct Devices* addLivingRoomLightToDeviceLink(struct Devices *phead);

struct Devices* addfireToDeviceLink(struct Devices *phead);

struct Devices* addfanToDeviceLink(struct Devices *phead);

struct Devices* addDHT11ToDeviceLink(struct Devices *phead);

struct Devices *addShakeToDeviceLink(struct Devices *phead);

struct Devices* addbuzzerToDeviceLink(struct Devices *phead);//火灾蜂鸣器

struct Devices* addshakebuzzerToDeviceLink(struct Devices *phead);//震动蜂鸣器

struct Devices* addwindowToDeviceLink(struct Devices *phead);

struct Devices *addcameraToDeviceLink(struct Devices *phead);//摄像头结点

InputCommand.h

#include

#include

struct InputCommander //

{

char commandName[128];//名字

char deviceName[128];//设备名

char command[32]; //指令

int (*Init)(struct InputCommander *voicer, char *ipAdress, char *port);//操作函数 : 串口号 ip 端口号

int (*getCommand)(struct InputCommander *voicer);//

char log[1024]; //日志

int fd;

char port[12];//端口号

char ipAddress[32];//ip地址

int sfd;

struct InputCommander *next;

};

struct InputCommander* addvoiceContrlToInputCommandLink(struct InputCommander *phead);

struct InputCommander* addSocketContrlToInputCommandLink(struct InputCommander *phead);

bathroomLight.c(四个房间小灯,风扇代码基本相似,这里只展示其中一个)

#include"contrlDevices.h"

#include

#include

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;

}

}

 window.c

#include"contrlDevices.h"

#include

#include

int windowOpen(int pinNum)

{

digitalWrite(2,LOW);

digitalWrite(3,HIGH);

}

int windowClose(int pinNum)

{

digitalWrite(2,HIGH);

digitalWrite(3,LOW);

}

int windowCloseInit(int pinNum)//用的L9110电机实现正反转,所以要初始化两个引脚

{

pinMode(2,OUTPUT);

pinMode(3,OUTPUT);

digitalWrite(2,LOW);

digitalWrite(3,LOW);//2和3都配置为低电平 默认不转

pinMode(4,OUTPUT);

digitalWrite(4,HIGH);

pinMode(0,OUTPUT); //门锁初始化

digitalWrite(0,HIGH);

}

int windowCloseStatus(int status)

{

}

struct Devices window = {

.deviceName = "window",

.pinNum = 2,

.open = windowOpen,

.close = windowClose,

.deviceInit = windowCloseInit,

.changeStatus = windowCloseStatus

};

struct Devices* addwindowToDeviceLink(struct Devices *phead)

{

if(phead == NULL){

return &window;

}

else{

window.next = phead;

phead = &window;

return phead;

}

}

DHT11.c

#include"contrlDevices.h"

#include

#include

#include

#include

#include

#include

typedef unsigned char uint8;

typedef unsigned int uint16;

typedef unsigned long uint32;

#define HIGH_TIME 32

int pinNumber = 7;

uint32 databuf;

int DHT11CloseInit(int pinNum)

{

uint8 crc;

uint8 i;

pinMode(pinNumber, OUTPUT); // set mode to output

digitalWrite(pinNumber, 0); // output a high level

delay(25);

digitalWrite(pinNumber, 1); // output a low level

pinMode(pinNumber, INPUT); // set mode to input

pullUpDnControl(pinNumber, PUD_UP);

delayMicroseconds(27);

if (digitalRead(pinNumber) == 0) //SENSOR ANS

{

while (!digitalRead(pinNumber))

; //wait to high

for (i = 0; i < 32; i++)

{

while (digitalRead(pinNumber))

; //data clock start

while (!digitalRead(pinNumber))

; //data start

delayMicroseconds(HIGH_TIME);

databuf *= 2;

if (digitalRead(pinNumber) == 1) //1

{

databuf++;

}

}

for (i = 0; i < 8; i++)

{

while (digitalRead(pinNumber))

; //data clock start

while (!digitalRead(pinNumber))

; //data start

delayMicroseconds(HIGH_TIME);

crc *= 2;

if (digitalRead(pinNumber) == 1) //1

{

crc++;

}

}

return 1;

}

else

{

return 0;

}

}

int DHT11Open(int pinNum)

{

}

int DHT11Close(int pinNum)

{

}

int DHT11CloseStatus(int status)

{

}

struct Devices DHT11 = { //这里是在定义的同时赋值

.deviceName = "DHT11",

.pinNum = 7,

.open = DHT11Open,

.close = DHT11Close,

.deviceInit = DHT11CloseInit,

.changeStatus = DHT11CloseStatus

};

struct Devices* addDHT11ToDeviceLink(struct Devices *phead)

{

if(phead == NULL){

return &DHT11;

}

else{

DHT11.next = phead;

phead = &DHT11;

return phead;

}

}

voiceContrl.c

#include

#include

#include

#include

#include

#include

#include"InputCommand.h"

int voiceGetCommand(struct InputCommander *voicer)

{

int nread = 0;

memset(voicer->command, '\0', sizeof(voicer->command));

nread = read(voicer->fd, voicer->command, sizeof(voicer->command));

if(nread == 0){

printf("voice no datas\n");

}else{

return nread;

}

}

int voiceInit(struct InputCommander *voicer, char *ipAdress, char *port)

{

int fd;

if((fd = serialOpen("/dev/ttyAMA0",9600))==-1)//初始化串口,波特率9600

{

printf("voice init error\n");

exit(-1);

}

voicer->fd = fd;

return fd;

}

struct InputCommander voiceContrl = {

.commandName = "voice",

.deviceName = "/dev/ttyAMA0",//设备名

.command = {'\0'}, //指令

.Init = voiceInit,//串口初始化

.getCommand = voiceGetCommand,

.log = {'\0'},

.next = NULL

};

struct InputCommander* addvoiceContrlToInputCommandLink(struct InputCommander *phead)

{

if(phead == NULL){

return &voiceContrl;

}

else{

voiceContrl.next = phead;

phead = &voiceContrl;

return phead;

}

}

socketContrl.c

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include"InputCommand.h"

int socketGetCommand(struct InputCommander *socketMes)

{

int c_fd;

int n_read = 0;

struct sockaddr_in c_addr;

memset(&c_addr, 0, sizeof(struct sockaddr_in));

int clen = sizeof(struct sockaddr_in);

//4. accept

c_fd = accept(socketMes->sfd, (struct sockaddr *)&c_addr, &clen);

n_read = read(c_fd, socketMes->command, sizeof(socketMes->command));

if(n_read == -1){

perror("read");

}else if(n_read > 0){

printf("\nget: %d\n",n_read);

}else{

printf("client quit\n");

}

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("socket");

exit(-1);

}

s_addr.sin_family = AF_INET;

s_addr.sin_port = htons(atoi(socketMes->port)); //atoi()把ascii转成整形数

//htons()返回网络字节序的值(大段字节序)

inet_aton(socketMes->ipAddress, &(s_addr.sin_addr)); //aton()把字符串形式的IP转换成网络能识别的格式

//解决服务器程序结束后端口被占用的情况

int opt = 1;

setsockopt(s_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

//2.bind

bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));

//3.listen

listen(s_fd, 10);

printf("socket server listening...\n");

socketMes->sfd = s_fd;

return s_fd;

}

struct InputCommander socketContrl = {

.commandName = "socketServer",

.command = {'\0'}, //指令

.port = "8083",

.ipAddress = "192.168.101.223",

.Init = socketInit,//初始化

.getCommand = socketGetCommand,

.log = {'\0'},

.next = NULL

};

struct InputCommander* addSocketContrlToInputCommandLink(struct InputCommander *phead)

{

if(phead == NULL){

return &socketContrl;

}

else{

socketContrl.next = phead;

phead = &socketContrl;

return phead;

}

}

Camera.c

#include "contrlDevices.h"

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define door_lock 0 //门锁

void postUrl();

size_t readData1(void *ptr, size_t size, size_t nmemb, void *stream);

char* getFace1();

char* getPicFromOCRBase641(char *Filepath);

struct Devices* addcameraToDeviceLink(struct Devices *phead);

int cameraInit(int pinNum);

char ocrRetBuf[1024] = {'\0'};

size_t readData1(void *ptr, size_t size, size_t nmemb, void *stream)

//回调函数,把从后台的数据拷贝给ocrRetBuf

{

strncpy(ocrRetBuf,ptr,1024);//ocrRetBuf接收从OCR后台返回的数据,并打印

printf("%s\n",ocrRetBuf);

}

char* getFace1()

{

printf("pai zhao zhong\n");

//system("raspistill -q 5 -t 1 -o image.jpg");

system("wget http://192.168.101.223:8080/?action=snapshot -O ./image.jpg ");

while(access("./image.jpg",F_OK) != 0); //判断是否拍照完毕

printf("paizhao wanbi\n");

char* base64BufFaceRec = getPicFromOCRBase641("./image.jpg");

//system("rm image.jpg");

return base64BufFaceRec; //返回刚才拍照的base64

}

char *getPicFromOCRBase641(char *Filepath)

{

int fd;

int filelen;

char cmd[128]={'\0'};

sprintf(cmd,"base64 %s > tmpFile",Filepath);

system(cmd);

fd=open("./tmpFile",O_RDWR);

filelen=lseek(fd,0,SEEK_END);//计算文件大小

lseek(fd,0,SEEK_SET); //移动光标到头

char *bufpic=(char *)malloc(filelen+2);

memset(bufpic,'\0',filelen+2);

read(fd,bufpic,filelen+128); //把内容读到bufpic内

system("rm -rf tmpFile");//删除这个临时文件

close(fd);

return bufpic; //返回bufpic这个地址

}

void postUrl()

{

CURL *curl;

CURLcode res;

char* key = "5xxxsWxxxGfP2pmxxxchSJ"; //翔云平台购买人脸识别后的key

char* secret = "396xxxd33xxx487exxxf139axxx6d789"; //翔云平台购买人脸识别后的secret

int typeId = 21;

char* format = "xml";

char* base64BufPic1 = getFace1();

char* base64BufPic2 = getPicFromOCRBase641("lit1.jpg");

int len = strlen(key)+strlen(secret)+strlen(base64BufPic1)+strlen(base64BufPic2)+128;

char* postString = (char* )malloc(len);

memset(postString,'\0',len);

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_POSTFIELDS, postString); //指定post内容,传入参数

curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");// 指定url

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,readData1); //回调函数readDate读取返回值

res = curl_easy_perform(curl);

printf("OK:%d\n",res);

if(strstr(ocrRetBuf,"是") != NULL){ //判断翔云后台返回的字符串中有没有“是”

printf("the same person\n");

digitalWrite(door_lock, LOW); //打开门锁

delay(3000); //等待3s

digitalWrite(door_lock, HIGH); //关闭门锁

}

else{

printf("different person\n");

}

curl_easy_cleanup(curl);

}

}

int cameraInit(int pinNum)//该函数无用

{

pinMode(0,OUTPUT);

digitalWrite(0,HIGH);

}

struct Devices camera = {

.deviceName = "camera",

.deviceInit = cameraInit,

.pinNum = 0, //此引脚号无用

.justDoOnce = postUrl,

.getFace = getFace1,

.getPicFromOCRBase64 = getPicFromOCRBase641,

.readData = readData1

};

struct Devices* addcameraToDeviceLink(struct Devices *phead)

{

if(phead == NULL){

return &camera;

}

else{

camera.next = phead;

phead = &camera;

}

}

其余代码和上面展示的有些很类似,就不放出了。

四.项目总结

        1.做完后感觉不是很难,主要是要明白这个项目代码的设计结构和里面的一些逻辑。

        2.人脸识别功能的整合是这个项目相对复杂的地方,这里我也参考了其他博客。

        3.前面学到的编写树莓派驱动代码,各种库的使用是重点,以后也会复习。

        4.火焰和震动传感器可以同时只使用一个蜂鸣器,风扇有时会出现一些小bug,代码还有优化的地方。

查看原文