基于树莓派开发的智能家居控制系统

news/2025/2/23 0:09:00/

 一.功能介绍

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

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

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

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

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

二.实物展示

   

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

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

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

 三.程序

 编译运行:

 1.mainPro.c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdint.h>
#include <curl/curl.h>#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 32pthread_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->commandif(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<stdlib.h>
#include<wiringPi.h>
#include <curl/curl.h>
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<stdlib.h>
#include<wiringPi.h>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<stdlib.h>
#include<fcntl.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;}
}

 window.c

#include"contrlDevices.h"
#include<stdlib.h>
#include<fcntl.h>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<stdlib.h>
#include<fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>typedef unsigned char uint8;
typedef unsigned int  uint16;
typedef unsigned long uint32;#define HIGH_TIME 32int pinNumber = 7;
uint32 databuf;int DHT11CloseInit(int pinNum)
{uint8 crc; uint8 i;pinMode(pinNumber, OUTPUT); // set mode to outputdigitalWrite(pinNumber, 0); // output a high level delay(25);digitalWrite(pinNumber, 1); // output a low level pinMode(pinNumber, INPUT); // set mode to inputpullUpDnControl(pinNumber, PUD_UP);delayMicroseconds(27);if (digitalRead(pinNumber) == 0) //SENSOR ANS{while (!digitalRead(pinNumber)); //wait to highfor (i = 0; i < 32; i++){while (digitalRead(pinNumber)); //data clock startwhile (!digitalRead(pinNumber)); //data startdelayMicroseconds(HIGH_TIME);databuf *= 2;if (digitalRead(pinNumber) == 1) //1{databuf++;}}for (i = 0; i < 8; i++){while (digitalRead(pinNumber)); //data clock startwhile (!digitalRead(pinNumber)); //data startdelayMicroseconds(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<unistd.h>
#include<wiringPi.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>#include<wiringSerial.h>
#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<unistd.h>
#include<wiringPi.h>
#include<stdlib.h>
#include<stdio.h>
#include<wiringSerial.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>#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. acceptc_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.sockets_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.bindbind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));//3.listenlisten(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 <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>#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";	//翔云平台购买人脸识别后的keychar* secret = "396xxxd33xxx487exxxf139axxx6d789";	//翔云平台购买人脸识别后的secretint   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");// 指定urlcurl_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);                   //等待3sdigitalWrite(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,代码还有优化的地方。


http://www.ppmy.cn/news/288827.html

相关文章

智能家居的几种控制协议

对于普通使用智能家居的用户来说&#xff0c;智能家居是如何控制的不需要了解太多&#xff0c;需要知道的就是这个家电是否可以控制、那个家电是否可以控制。但是对于做智能家居产品的人来说&#xff0c;不得不面对这个问题。 简单而言&#xff0c;控制其实就是由控制端&#x…

实现智能家居控制系统

本文将讲述如何用STM32嵌入式实现智能家居控制系统&#xff0c;所谓智能就是实时监测自主控制一些因素&#xff0c;如&#xff0c;温度、湿度、光照强度等&#xff0c;当室内光线较暗时自动打开灯&#xff0c;根据光线亮度的不同开灯数量也不同&#xff0c;当室内温度过高时红灯…

智能家居语音控制系统的设计与实现

1 项目概况 1.1 背景和基础 通过人工智能&#xff0c;大数据&#xff0c;云计算&#xff0c;5G等多项技术驱动下&#xff0c;智能家居开始进入快速发展的阶段&#xff0c;逐渐代替了传统家居。在2019年的政府工作报告中&#xff0c;明确政策导向已经证明了“智能”在我国的前…

语音识别智能家居控制设计

目录 一、方案流程及技术规格书设计 二、系统硬件电路设计 三、软件编写及调试 四、系统调试测试与分析 前言 随着科学技术的快速发展&#xff0c;人们对生活品质的要求也不断提高&#xff0c;开始追求更好更方便的生活方式。因此&#xff0c;智能家居系统应运而生。智能家…

WiFi语音智能家居控制系统(一)

LU-ASR01语音识别 文章目录 LU-ASR01语音识别前言一、语音识别技术二、语音识别1.天问Block软件介绍2.模块介绍3.实现 总结 前言 这款离线语音识别模块可以说是挺好用的&#xff0c;适合新手使用&#xff0c;模块化编程。 一、语音识别技术 语音识别技术&#xff0c;也被称为…

用树莓派构建家庭智能家居控制中心

一直以来对手机上安装的10来个智能家居控制APP耿耿于怀&#xff0c;虽然后来尽量在米家购买终端设备&#xff0c;但还是有不少设备不能纳管&#xff0c;特别是自己平常用Raspberry、Arduino、ESP8266等DIY的设备&#xff0c;更需要一个集成环境进行控制&#xff0c;于是趁元旦假…

全面布局AIoT生态,OPPO小布助手打造多智能终端核心中枢

万物互融时代&#xff0c;人与不同终端的碎片化场景交互愈发频繁&#xff0c;语音作为人与多终端交互最自然的方式&#xff0c;推动智能助手成为了AIoT场景下人机交互的关键入口。自2019年发布万物互融战略以来&#xff0c;OPPO便着力于建立互融式技术体系&#xff0c;打造个人…

如何让带AV接口的复古老彩电活在当下

复合视频接口&#xff08;AV接口或Video接口&#xff09;&#xff0c;曾是最普遍的一种视频接口&#xff0c;几乎所有电视机、影碟机都有这个接口。它是音频、视频分离的视频接口&#xff0c;一般由三个独立RCA插头&#xff08;又叫梅花接口、RCA接口&#xff09;组成&#xff…