基于树莓派的智能家居控制系统设计
下载完整的文件
基于树莓派的智能家居控制系统设计 https://download.csdn.net/download/G1842965496/85802405
一、功能介绍
1.通过手机APP、语音识别等控制家用电器,控制门锁、照明、电风扇等设备,开发家居模式、睡眠模式等应用场景。 2.通过视频监控、火灾报警、振动报警和人体感应报警,确保家庭安全。 3.将温湿度检测数据与家庭安全状况实时同步到用户的手机上APP进行显示。 4.遥控可以保证家庭在没有网络的情况下得到控制。 5.人脸识别解锁通过翔云平台提供的人脸对比服务完成
二、实物展示
1.实物家居模型 2.部分功能显示 手机APP
火灾测试 火灾报警 视频监控 温湿度检测 人脸识别按钮 人脸识别解锁
程序(手机)APP程序过多不展示)
1.主程序mainPro.c
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include "contrlDevices.h" #include "inputCommand.h" #define HIGH_TIME 32 // 433m端口 #define D0 4 #define D1 3 #define D2 2 #define D3 0 #define key 28 //拍照按键 // #define door_Lock 29 //门锁 //注意:定义线程不使用指针以免空指针异常 //注意:不建议线程传参(链表头)所以定为全局变量 pthread_t voiceThread; //语音识别线程 pthread_t socketThread; //服务器线程 pthread_t writeThread; //通知线程:向客服端发送消息 pthread_t fireThread; //火灾检测线程 pthread_t shakeThread; //震动检测线程 pthread_t humanThread; //人体红外检测线程 pthread_t remoteThread; //遥控线程 pthread_t keyThread; //按键检测线程 pthread_t cameraThread; //人脸识别线程 pthread_t monitoringThread; //视频监控线程 pthread_t clientWemosThread; //客服端线程 pthread_t dht11Thread; //温湿度线程 struct InputCommander *pCommandHead = NULL; struct Devices *pdeviceHead = NULL; struct InputCommander *socketHandler = NULL; // struct InputCommander *clientHandler = NULL; pthread_mutex_t mutex; //定义互斥量(锁) // pthread_cond_t cond; //条件 unsigned long databuf; int c_fd; //注意:涉及到多线程不要轻易的去传参 int beep = 0; //
蜂鸣器标志位 0:未被使用 1:被火灾传感器使用 2:被震动传感器使用 //摄像头相关,改变返回值命名,因为C语言中没有这样的返回值 #define true 1 #define false 0 typedef unsigned int bool; char buf[1024] = { '\0'}; /*通知app [0]:温度 [1]:湿度 [2]:火灾监控 [3]:震动监控 [4]:人体红外监控*/ char Message[5][100] = { "未启用!", "未启用!", "未启用!", "未启用!", "未启用!"}; int write_flag = 0; //标记位,标记通知线程是否打开 1:打开 0:关闭 int human_flag = 0; //红外检测标志位 1:打开 0:关闭 struct Devices *findDeviceByName(char *name, struct Devices *phead) //查询设备 { if (phead == NULL) { return NULL; } while (phead != NULL) { // printf("phead:%s name:%s\n", phead->deviceName, name); if (strstr(phead->deviceName, name) != NULL) { return phead; } phead = phead->next; } return NULL; } struct InputCommander *findCommandByName(char *name, struct InputCommander *phead) //查询控制 { if (phead == NULL) { return NULL; } while (phead != NULL) { if (strcmp(phead->commandName, name) == 0) { return phead; } phead = phead->next; } return NULL; } //查找设备 void *cameraThread_func(void *data) //起线程的函数有格式要求 { struct Devices *cameraTemp; cameraTemp = findDeviceByName("camera", pdeviceHead); //设备都要从工厂里面取出来 if (cameraTemp == NULL) { //防止段错误的必需判断,当给指针赋值是,一定要考虑NULL的情况,否则后续操作都是空谈 printf("find camera error\n"); pthread_exit(NULL); //在线程中不用return } cameraTemp->justDoOnce(); //调用postUrl函数 } unsigned char readSensorData(void) //温湿度初始化 { char crc; char i; pinMode(6, OUTPUT); // 将模式设置为输出 digitalWrite(6, LOW); // 输出高电平 delay(25); digitalWrite(6, HIGH); // 输出低电平 pinMode(6, INPUT); // 将模式设置为输入 pullUpDnControl(6, PUD_UP); delayMicroseconds(27); if (digitalRead(6) == 0) // SENSOR ANS { while (!digitalRead(6)) ; // wait to high for (i = 0; i < 32; i++) { while (digitalRead(6)) ; // 数据时钟启动 while (!digitalRead(6)) ; //数据开始 delayMicroseconds(HIGH_TIME); databuf *= 2; if (digitalRead(6) == 1) // 1 { databuf++; } } for (i = 0; i < 8; i++) { while (digitalRead(6)) ; // 数据时钟启动 while (!digitalRead(6)) ; // 数据开始 delayMicroseconds(HIGH_TIME); crc *= 2; if (digitalRead(6) == 1) // 1 { crc++; } } return 1; } else { return 0; } } void *dht11_thread(void *datas) //温湿度线程 { int W = 0, w = 0; int S = 0, s = 0; // int count = 0; int temp = 0; printf("Use GPIO4 to read data!\n"); if (-1 == wiringPiSetup()) { printf("Setup wiringPi failed!"); // return 1; } pinMode(6, OUTPUT); // set mode to output digitalWrite(6, HIGH); // output a high level printf("Enter OS-------\n"); while (1) { pinMode(6, OUTPUT); // set mode to output digitalWrite(6, HIGH); // output a high level delay(3000); if (readSensorData()) { W = (databuf >> 8) & 0xff; w = databuf & 0xff; S = (databuf >> 24) & 0xff; s = (databuf >> 16) & 0xff; // printf("传感器数据读取正常!\n"); if (temp == 0) { w++; s++; temp++; } else if (temp == 1) { if (w >= 1) { w--; } if (s >= 1) { w--; } temp--; } if ((W >= 15) && (W <= 35) && (S <= 95)) { memset(Message[0], 0, sizeof Message[0]); //清空数组 memset(Message[1], 0, sizeof Message[1]); // printf("温度:%d.%d 湿度:%d.%d\n", W, w, S, s); //清空数组 sprintf(Message[0], "%d.%d C", W, w); //温度 sprintf(Message[1], "%d.%d", S, s); //湿度 // printf("温度:%d.%d C", (databuf >> 8) & 0xff, databuf & 0xff); //温度 } // printf(" 湿度:%d.%d %\n", (databuf >> 24) & 0xff, (databuf >> 16) & 0xff); //湿度 databuf = 0; } else { // count++; // memset(Message[0], 0, sizeof Message[0]); //清空数组 // memset(Message[1], 0, sizeof Message[1]); //清空数组 // sprintf(Message[0], "监测错误!"); //温度 // sprintf(Message[1], "监测错误!"); //湿度 printf("Sorry! Sensor dosent ans!\n"); databuf = 0; } // if (count >= 3) // { // pthread_create(&dht11Thread, NULL, dht11_thread, NULL); // } } } void *fire_thread(void *datas) //火灾线程 { char msg[100]; int status; struct Devices *fireDeviceTmp = NULL; struct Devices *buzzerDeviceTmp = NULL; fireDeviceTmp = findDeviceByName("fire", pdeviceHead); //在设备工厂找到火灾模块 buzzerDeviceTmp = findDeviceByName("buzzser", pdeviceHead); fireDeviceTmp->deviceInit(fireDeviceTmp->pinNum); //火灾模块初始化 buzzerDeviceTmp->deviceInit(buzzerDeviceTmp->pinNum); printf("火灾线程初始化成功\n"); while (1) { delay(10); status = fireDeviceTmp->readStatus(fireDeviceTmp->pinNum); //读取火灾模块实时数据 if (status == 0) { beep = 1; //火灾传感器使用蜂鸣器 buzzerDeviceTmp->open(buzzerDeviceTmp->pinNum); //蜂鸣器报警 memset(Message[2], 0, sizeof Message[2]); //清空数组 sprintf(Message[2], "警报:发生火灾 !"); //更新火灾信息 delay(200); //蜂鸣器报警延时 } else if ((beep != 2) && (beep != 3)) //未被震动传感器和人体红外传感器使用 { buzzerDeviceTmp->close(buzzerDeviceTmp->pinNum); //关闭蜂鸣器 memset(Message[2], 0, sizeof Message[2]); //清空数组 sprintf(Message[2], "正常"); //更新火灾信息 beep = 0; //蜂鸣器未被使用 } } } void *shake_thread(void *datas) //震动线程 { char msg[100]; int status; struct Devices *shakeDeviceTmp = NULL; struct Devices *buzzerDeviceTmp = NULL; shakeDeviceTmp = findDeviceByName("shake", pdeviceHead); //在设备工厂找到火灾模块 buzzerDeviceTmp = findDeviceByName("buzzser", pdeviceHead); shakeDeviceTmp->deviceInit(shakeDeviceTmp->pinNum); //震动模块初始化 buzzerDeviceTmp->deviceInit(buzzerDeviceTmp->pinNum); printf("震动线程初始化成功\n"); while (1) { delay(5); status = shakeDeviceTmp->readStatus(shakeDeviceTmp->pinNum); //读取震动模块实时数据 if (status == 0) { beep = 2; //震动传感器使用蜂鸣器 buzzerDeviceTmp->open(buzzerDeviceTmp->pinNum); memset(Message[3], 0, sizeof Message[3]); //清空数组 sprintf(Message[3], "警报:发生震动 !"); delay(300); } else if ((beep != 1) && (beep != 3)) //蜂鸣器未被火焰传感器和人体红外传感器使用 { memset(Message[3], 0, sizeof Message[3]); //清空数组 sprintf(Message[3], "正常"); buzzerDeviceTmp->close(buzzerDeviceTmp->pinNum); beep = 0; //蜂鸣器未被使用 } } } void *human_thread(void *datas) // 人体红外检测线程 { char msg[100]; int status; struct Devices *humanDeviceTmp = NULL; struct Devices *buzzerDeviceTmp = NULL; humanDeviceTmp = findDeviceByName("human", pdeviceHead); //在设备工厂找到火灾模块 buzzerDeviceTmp = findDeviceByName("buzzser", pdeviceHead); humanDeviceTmp->deviceInit(humanDeviceTmp->pinNum); //红外模块初始化 buzzerDeviceTmp->deviceInit(buzzerDeviceTmp->pinNum); printf("人体红外检测初始化\n"); while (1) { delay(10); status = humanDeviceTmp->readStatus(humanDeviceTmp->pinNum); //读取人体感应模块实时数据 if (status == 1) { beep = 3; //人体红外使用蜂鸣器 memset(Message[4], 0, sizeof Message[4]); //清空数组 sprintf(Message[4], "警报:有人进入 !"); buzzerDeviceTmp->open(buzzerDeviceTmp->pinNum); delay(200); buzzerDeviceTmp->close(buzzerDeviceTmp->pinNum); delay(100); } else if ((beep != 1) && (beep != 2)) //未被火焰传感器和震动传感器使用 { memset(Message[4], 0, sizeof Message[4]); //清空数组