资讯详情

基于树莓派的智能家居设计

文章目录

  • 前言
  • 一、整体系统框图
  • 二、代码部分
  • 二、APP客户端
    • 1.MainActivity.java
    • 2.NetUtils.java
  • 三、实物展示

前言

一个简单的小项目,以下是代码部分和实物效果显示。

一、整体系统框图

在这里插入图片描述

二、代码部分

  • main.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"   pthread_t voiceThread;  //注意:不使用指针定义线程,避免空指针异常 pthread_t socketThread; //注意:线程传参(链表头)不建议定为全局变量 pthread_t fireThread; pthread_t cameraThread; pthread_t clientWemosThread;   struct InputCommander *pCommandHead = NULL;   struct Devices    *pdeviceHead = NULL; struct InputCommander *socketHandler = NULL; 
struct InputCommander *clientHandler = NULL;


pthread_mutex_t mutex;  //定义互斥量()
//pthread_cond_t cond; //条件 
 
int c_fd;			    //注意:涉及到多线程不要轻易的去传参
 
//摄像头相关,改变返回值命名,因为C语言中没有这样的返回值
#define true 1
#define false 0
typedef unsigned int bool;
//char buf[1024] = {'\0'};

char* faceRes = NULL;
 
struct Devices *findEquipByName(char *name,struct Devices *phead)    //查询设备
{ 
        
	if(phead == NULL){ 
        
		return NULL;
	}
	while(phead != NULL){ 
        
		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 *camera_thread(void *datas)    //摄像头线程
{ 
        
	const char* openCamera = "/home/pi/mjpg-streamer/mjpg-streamer-experimental/start.sh";
	system(openCamera);	//调用start.sh可执行文件
}
//=======================================================/end/======================================================================
//=======================================================人脸识别开锁=================================================================

size_t handle(void *ptr, size_t size, size_t nmemb, void *stream){ 
        
	//拷贝返回来的结果字段
	int ssize = strlen(ptr) + 1;
	faceRes = (char*)malloc(ssize);
	memset(faceRes, '\0', ssize);
	strncpy(faceRes, ptr, ssize);
}
char* getBase64(char* photoPath){ 
        // 获取照片(jpg格式)的Base64的值
	char cmd[256] = { 
        '\0'};

	sprintf(cmd, "base64 %s > photoBase64File", photoPath);
	system(cmd);// 通过执行"base64"这个指令即可得到照片的Base64值,在这里将得到的Base64值存放在photoBase64File文件中

	int fd,size;
	fd = open("./photoBase64File", O_RDWR);
	size = lseek(fd, 0, SEEK_END) + 1;
	lseek(fd, 0, SEEK_SET);
	
	char* res = (char*)malloc(size);
	memset(res, '\0', size);
	read(fd, res, size);// 从photoBase64File文件中读取照片的Base64值
	close(fd);
	
	system("rm photoBase64File");

	return res;
}
bool cameraContrlPostUrl()
{ 
        
	CURL *curl;
	CURLcode res;
	struct Devices *linkHandler  = NULL;
	char* message = NULL;

	// 调用getBase64()自定的函数获取存放在当前文件夹下的两个进行识别的图片的Base64值
	char* img1 = getBase64("./host.jpg");

/*************************添加的代码**************************************/
	
	//openCamera为start.sh可执行文件的绝对地址,请根据自己的路径改
	//const char* openCamera = "/home/pi/mjpg-streamer/mjpg-streamer-experimental/start.sh";
	//system(openCamera); //调用start.sh可执行文件

	//获取访问者的照片
	system("wget http://192.168.137.104:8080/?action=snapshot -O ./visitor.jpg");

/************************************************************************/
	char* img2 = getBase64("./visitor.jpg");
	
	// key值和secret值是在翔云官网->个人中心的OCR Key和OCR secret两个的值
	char* key = "QYRbM22W52hMrHaUWkdKEN";
	char* secret = "30e80f34e0b04a2f863ff4ff615c2661";
	int typeId = 21;
	char* format = "xml";

	int size = strlen(img1)+strlen(img2)+strlen(key)+strlen(secret)+strlen(format)+3;
	message = (char*)malloc(size);
	memset(message, '\0', size);

	sprintf(message, "&img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s",
		img1, img2, key, secret, typeId, format);

	curl = curl_easy_init(); // 初始化
	if (curl)
	{ 
        
		curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");// 指定url
		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, message);// 指定post内容
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle);// 当拿到结果后,指定调用handle()该自定的函数进行处理
		res = curl_easy_perform(curl);// 进行访问官网、进行人脸识别的操作
		curl_easy_cleanup(curl);// 执行完后,对curl_easy_init()进行清理
		



		printf("%s\n",faceRes);// 打印出人脸识别后返回来的结果字段

		printf("shibiechenggong\n");
		
		if(strstr(faceRes, "是") != NULL){ 
        // 如果返回来的结果字段中有“是”这个字眼,代表是同一个人
			
			printf("tongyigeren\n");
			linkHandler = findEquipByName("lock",pdeviceHead);
			linkHandler->open(linkHandler->pinNum);
			sleep(3);
			linkHandler->close(linkHandler->pinNum);

		}
		
		else{ 
        

			printf("bushitongyigeren\n");
			
			
		
			}
	printf("shibiejieshu\n");
	}

	

	
	
	free(faceRes);
	free(img1);
	free(img2);

}
 

//=======================================================/end人脸识别/================================================================

//=======================================================语音模块=====================================================================

void *voice_thread(void *arg)    //语音线程
{ 
        
	int i = 0;
	int nread;
	struct InputCommander *voiceHandler = NULL;
	struct Devices *linkHandler = NULL;
	
	voiceHandler = findCommandByName("voice",pCommandHead);    //在控制工厂找到语音模块
	if(voiceHandler == NULL){ 
        
		printf("find voiceHandler error\n");
		pthread_exit(NULL);		
	}else{ 
        
			if(voiceHandler->Init(voiceHandler) < 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);	    //读取来自语音模块的串口数据
			if(nread == 0){ 
        
				printf("noData from voice,please say again\n");
				
			}

				else{ 
        													//获取到指令
					printf("Get voice command:%s\n",voiceHandler->command);

					//以下为根据不用指令执行相应操作

					//语音模块串口传出来的后面带\r\n,不加对比不出来
						if(strcmp("kycd\r\n",voiceHandler->command) == 0){ 
        //开泳池灯
							linkHandler = findEquipByName("yongchilight",pdeviceHead);
							linkHandler->open(linkHandler->pinNum);
							printf("open bathroomlight\n");
						}

						if(strcmp("gycd\r\n",voiceHandler->command) == 0){ 
        //关泳池灯
							linkHandler = findEquipByName("yongchilight",pdeviceHead);
							linkHandler->close(linkHandler->pinNum);
							printf("已关闭浴室灯\n");
						}

						if(strcmp("kwsd\r\n",voiceHandler->command) == 0){ 
        //开卧室灯
							linkHandler = findEquipByName("bedroomlight",pdeviceHead);
							linkHandler->open(linkHandler->pinNum);
						}

						if(strcmp("gwsd\r\n",voiceHandler->command) == 0){ 
        //关卧室灯
							linkHandler = findEquipByName("bedroomlight",pdeviceHead);
							linkHandler->close(linkHandler->pinNum);
						}

						if(strcmp("kktd\r\n",voiceHandler->command) == 0){ 
        //开客厅灯
							linkHandler = findEquipByName("livingroomLight",pdeviceHead);
							linkHandler->open(linkHandler->pinNum);
						}

						if(strcmp("gktd\r\n",voiceHandler->command) == 0){ 
        //关客厅灯
							linkHandler = findEquipByName("livingroomLight",pdeviceHead);
							linkHandler->close(linkHandler->pinNum);
						}

						if(strcmp("kfs\r\n",voiceHandler->command) == 0){ 
        //开风扇
							linkHandler = findEquipByName("fan",pdeviceHead);
							linkHandler->open(linkHandler->pinNum);
						}

						if(strcmp("gfs\r\n",voiceHandler->command) == 0){ 
        //关风扇
							linkHandler = findEquipByName("fan",pdeviceHead);
							linkHandler->close(linkHandler->pinNum);
						}
						if(strcmp("km\r\n",voiceHandler->command) == 0){ 
        //开门
						
							cameraContrlPostUrl();   //调用人脸识别
							//linkHandler = findEquipByName("lock",pdeviceHead);
							//linkHandler->open(linkHandler->pinNum);
						}

						if(strcmp("gm\r\n",voiceHandler->command) == 0){ 
        //关门
							linkHandler = findEquipByName("lock",pdeviceHead);
							linkHandler->close(linkHandler->pinNum);
						}

						if(strcmp("kqbd\r\n",voiceHandler->command) == 0){ 
        //打开全部灯
							linkHandler = findEquipByName("yongchilight",pdeviceHead);
							linkHandler->open(linkHandler->pinNum);

							linkHandler = findEquipByName("bedroomlight",pdeviceHead);
							linkHandler->open(linkHandler->pinNum);

							linkHandler = findEquipByName("livingroomLight",pdeviceHead);
							linkHandler->open(linkHandler->pinNum);

							}
							if(strcmp("face",voiceHandler->command) == 0){ 
            //进行人脸识别
								//deviceTmp = findDeviceByName("face",pdeviceHead);
								//deviceTmp->cameraInit(deviceTmp);
								cameraContrlPostUrl();   //调用人脸识别

			
							}
/* //以下指令发送到wemos服务端 if(strcmp("dkds\r\n",voiceHandler->command) == 0){//打开电视 memset(clientHandler,'\0',sizeof(clientHandler)); strcpy(clientHandler->command,"1"); write(clientHandler->sfd,clientHandler->command,strlen(clientHandler->command)); } if(strcmp("gbds\r\n",voiceHandler->command) == 0){//关闭电视 memset(clientHandler,'\0',sizeof(clientHandler)); strcpy(clientHandler->command,"2"); write(clientHandler->sfd,clientHandler->command,strlen(clientHandler->command)); } if(strcmp("dkkt\r\n",voiceHandler->command) == 0){//打开空调 memset(clientHandler,'\0',sizeof(clientHandler)); strcpy(clientHandler->command,"3"); write(clientHandler->sfd,clientHandler->command,strlen(clientHandler->command)); } if(strcmp("gbkt\r\n",voiceHandler->command) == 0){//关闭空调 memset(clientHandler,'\0',sizeof(clientHandler)); strcpy(clientHandler->command,"4"); write(clientHandler->sfd,clientHandler->command,strlen(clientHandler->command)); }*/
				}
			}


//pthread_mutex_unlock(&mutex); //解锁
 
	}
}


//========================================================/end语音/====================================================================


//========================================================火焰警报=====================================================================
void *fire_thread(void *datas)    //火灾线程
{ 
        
	int status;
	struct Devices *fireDeviceTmp = NULL;
	struct Devices *buzzerDeviceTmp = NULL;
 
	fireDeviceTmp = findEquipByName("fire",pdeviceHead);    //在设备工厂找到火灾模块
	buzzerDeviceTmp = findEquipByName("buzzser",pdeviceHead);
	    
	fireDeviceTmp->deviceInit(fireDeviceTmp->pinNum);        //火灾模块初始化
	buzzerDeviceTmp->deviceInit(buzzerDeviceTmp->pinNum);
	printf("fire_thread init\n");
 
   	while(1){ 
        
		delay(2000);
		status = fireDeviceTmp->readStatus(fireDeviceTmp->pinNum);    //读取火灾模块实时数据
		//printf("fire get data = %d\n",status);
 
		if(status == 0){ 
        
			buzzerDeviceTmp->open(buzzerDeviceTmp->pinNum);
		}else{ 
        
			buzzerDeviceTmp->close(buzzerDeviceTmp->pinNum);
		}
    }
}


//========================================================/end火焰/====================================================================


//========================================================socket网络控制===============================================================
void *read_thread(void *datas)    //通过socket读取客户端发来的数据
{ 
        
	int n_read;
	struct Devices *linkHandler  = NULL;
	
	while(1){ 
        
		memset(socketHandler->command,'\0',sizeof(socketHandler->command));
 
		n_read = read(c_fd,socketHandler->command,sizeof(socketHandler->command));    //读取客户端发来的数据
		if(n_read == -1){ 
        
			perror("read_thread");
		}else if(n_read > 0){ 
        
			printf("getCommand:%s\n",socketHandler->command);
		
			//处理客户端读到的命令
			if(strcmp("kycd",socketHandler->command) == 0){ 
        
				linkHandler = findEquipByName("yongchilight",pdeviceHead);
				linkHandler->open(linkHandler->pinNum);
				
			
			}

			if(strcmp 

标签: 80f薄膜电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台