文章目录
- 前言
- 一、整体系统框图
- 二、代码部分
- 二、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