本文共 14596 字,大约阅读时间需要 48 分钟。
本项目所完成的是一个智能家居系统,使用Linux操作系统搭建的远程网络视频监控系统的解决方案。着重于实现一个易搭建,易配置,通用性好,能用于临时性监控的网络视频服务器,可以让客户机实时监控远程目标摄像头,实时共享摄像头控制空调、热水器、窗帘等家居智能设备。
智能家居系统让您轻松享受生活。出门在外,您可以通过电话、电脑来远程遥控您的家居各智能系统,例如在回家的路上提前打开家中的空调和热水器;到家开门时,借助门磁或红外传感器,系统会自动打开过道灯,同时打开电子门锁,安防撤防,开启家中的照明灯具和窗帘迎接您的归来;回到家里,使用遥控器您可以方便地控制房间内各种电器设备。本系统采用ARM Cortex-A94-Core核心板和Ubuntu环境开发
开发语言为C语言(1)温湿度传感器
温湿度传感器可以将采集到的温度实时转换成输出信号,并在终端上显示,当室内温度超过闹值或湿度不在设定范国内,会通过度异常信息。 (2)蜂鸣器 当室内的温度达到火灾值,或有人非法进入时,系统会自动发出报警声。 (3)USB摄像头 网络远程监控摄像头,进行监控并将监视画面录制下来,可实时将影像透过网络传给用户终端,使用户能够随时随地观察家里的情况。 (4)LED 显示电器是否处于工作中 (5)电位器(pm_2.5) (6)远程终端 由Qt制作的用户界面,来显示实时监控画面、温度数据、PM_2.5数据以及空调、热水器、窗帘控制按键、并且具有异常警报按钮。1系统初始化
对整个系统进行配置及初始化。 2实时监控子系统 系统的实时监控和处理。 A)室内温度监控 B)室内PM_2.5指数监控 C)室内视频监控 3远程服务子系统 A)数据显示请求 B)远程控制主界面
包含:实时温度显示、视频获取、远程家具控制和报警。tftp配置 (文件服务器,传输文件)
$ sudo vi /etc/default/tftpd-hpa TFTP_USERNAME=“tftp” TFTP_DIRECTORY="/home/farsight/linux/tftpboot" //指定tftp的共享目录 TFTP_ADDRESS=“0.0.0.0:69” //任意主机都可以通信 TFTP_OPTIONS="-l -c -s" //-c表示可以创建文件,默认情况下tftp只允许覆盖原文件,不能创建新 文件;-s表示只能在tftp指定的共享目录进行上传和下载,增加安全性; TFTP_DIRECTORY修改tftpboot的服务器目录所在路径(可改) 在/home/farsight/linux目录下,创建文件夹tftpboot,修改文件夹权限为777 启动tftp服务器 sudo /etc/init.d/tftpd-hpa restart; sudo service tftp-hpa restart(网络文件系统,将PC机上的目录共享给开发板使用
安装nfs服务器端 安装nfs服务器端 sudo apt-get install nfs-kernel-server 步骤 创建一个目录作为nfs共享目录 $ sudo mkdir /home/nfs $ chmod 0777 /home/nfs 配置nfs资源 $ sudo vi /etc/exports 添加 /home/board/nfs/ *(rw,sync,no_root_squash,no_subtree_check) //rw表示读写;sync表示 同步;no_root_squash表示登录 NFS 主机使用分享目录的使用者,如果是 root 的话,那么对于这个分 享的目录来说,他就具有 root 的权限;no_subtree_check不检查子目录 启动/停止NFS服务器 $ sudo /etc/init.d/nfs-kernel-server restart 重启服务 $ sudo /etc/init.d/nfs-kernel-server stop 停止服务 查看NFS服务器的共享资源 $ showmount -e 192.168.1.10(虚拟机ip) 也可以使用localhost来替换ip地址 挂载共享目录 $ sudo mkdir /mnt/nfs $ sudo chmod /mnt/nfs 0777 // /mnt/nfs/表示挂载目录,权限改为777 $ sudo mount -t nfs 192.168.1.10:/home/board/nfs /mnt/nfs/ //-t指明类型 这时,在/mnt/nfs/下新建一个文件,abc.txt,在/home/board/nfs/下也可以看到这个文件 在/home/board/nfs/下新建一个文件,hello.c, 在/mnt/nfs下也可以看到这个文件 注意:挂载点必须是一个存在的目录 ,这个目录 以不为空,但,挂载后这个目录下以前的内容将不可用, umount以后会恢复正常。在linux中如果你要使用储存设备(如:U盘、硬盘、光驱),就得先将它挂载 (mount),然后才能把存储设备当作一个目录进行访问。 卸载共享资源 $ sudo umount -f /mnt/nfs/(-f表示强制卸载)虚拟机->设置->网络适配器->自定义->VMnet0->确定
编辑->虚拟网络编辑器->更改设置->VMnet0->桥接模式->Realetk PCLe GBE family Controller设置启动环境变量
ubuntu -> 192.168.0.116 ARM -> 192.168.0.120 setenv serverip 192.168.0.116; setenv ipaddr 192.168.0.120 setenv bootcmd tftp 41000000 uImage;tftp 42000000 exynos4412-fs4412.dtb;bootm 41000000 - 42000000 setenv bootargs root=/dev/nfs nfsroot=192.168.0.116:/home/farsight/Documents/board/nfs/rootfs rw console=ttySAC2,115200 init=/linuxrc ip=192.168.0.120连接:连接到Putty,连通开发板
关闭:断开Putty 温度:连通后,实时显示温度 PM2.5:连通后,实时显示PM2.5值 紧急开关:报警器打开,颜色变红;报警器关闭,颜色变绿 空调:点击后,LED2亮,再次点击,LED2关闭 窗帘:点击后,LED3亮,再次点击,LED3关闭 热水器点击后,LED4亮,再次点击,LED4关闭 报警器:点击后,蜂鸣器响,再次点击,蜂鸣器停止响获取温湿度
int tempProcess(){ char rbuf[6]=""; char chline=' '; int i=0; if (tempFd < 0) return 0; while(1) { //读取温度 lseek(tempFd,0,SEEK_SET); while(chline != '\n') { read(tempFd,&chline,1); i++; } while(chline != '=') { read(tempFd,&chline,1); i++; } read(tempFd,rbuf,sizeof(rbuf)); rbuf[5]='\0'; i=0; if (NULL == jpg) continue;pthread_mutex_lock(&jpg_mutex); while(rbuf[i]!= '\0') { jpg->tp[i]=rbuf[i]; i++; }pthread_mutex_unlock(&jpg_mutex); //printf("%s,%c\n",jpg->tp,jpg->btn); } return 0;}
蜂鸣器
int tempProcess(){ char rbuf[6]=""; char chline=' '; int i=0; if (tempFd < 0) return 0; while(1) { //读取温度 lseek(tempFd,0,SEEK_SET); while(chline != '\n') { read(tempFd,&chline,1); i++; } while(chline != '=') { read(tempFd,&chline,1); i++; } read(tempFd,rbuf,sizeof(rbuf)); rbuf[5]='\0'; i=0; if (NULL == jpg) continue;pthread_mutex_lock(&jpg_mutex); while(rbuf[i]!= '\0') { jpg->tp[i]=rbuf[i]; i++; }pthread_mutex_unlock(&jpg_mutex); //printf("%s,%c\n",jpg->tp,jpg->btn); } return 0;}
LED灯
int ledProcess(int ledNum, int cmd){ if (ledFd < 0 || ledNum > 3 || cmd > 1 || cmd < 0) return -1; if (AIRCONDITION == ledNum) { if (1 == cmd || !isAirConditionOn) { printf("open airCondition led0\r\n"); ioctl(ledFd, LED_ON, 0); isAirConditionOn = TRUE; } else { printf("close airCondition led0\r\n"); ioctl(ledFd, LED_OFF, 0); isAirConditionOn = FALSE; } } else if (CURTAIN == ledNum) { if (1 == cmd || !isCurtainOn) { printf("open Curtain led1\r\n"); ioctl(ledFd, LED_ON, 1); isCurtainOn = TRUE; } else { printf("close Curtain led1\r\n"); ioctl(ledFd, LED_OFF, 1); isCurtainOn = FALSE; } } else if (WATERHEATER == ledNum) { if (1 == cmd || !isCurtainOn) { printf("open Curtain led1\r\n"); ioctl(ledFd, LED_ON, 2); isCurtainOn = TRUE; } else { printf("close Curtain led1\r\n"); ioctl(ledFd, LED_OFF, 2); isCurtainOn = FALSE; } } else //if (WATERHEATER == ledNum) { if (1 == cmd || !isCurtainOn) { printf("open Curtain led1\r\n"); ioctl(ledFd, LED_ON, 3); isCurtainOn = TRUE; } else { printf("close Curtain led1\r\n"); ioctl(ledFd, LED_OFF, 3); isCurtainOn = FALSE; } } return 0;}
PM2.5
int adcProcess(){ if( 0 > adcFd) return -1; int adcValue = 0; while(1) { if (0 > ioctl(adcFd, ADC_CMD_GET, &adcValue)) printf("ioctl adc get failed\n"); //else //printf("the temp value is: %d\n", adcValue); //将adcValue转成0~500的数 adcValue = adcValue * 5 / 100; if (!jpg) continue; //将adcValue转成一个字符串pthread_mutex_lock(&jpg_mutex); sprintf(jpg->pm2_5, "%d", adcValue);pthread_mutex_unlock(&jpg_mutex); //printf("%s,%c\n",jpg->tp,jpg->btn); } return 0;}
按键处理
tatic void sig_handler(int signo){ if(signo==SIGIO) { read(btnFd, &keyID, sizeof(keyID)); printf("key%d pressed\n", keyID); if (WATERHEATER == keyID) { ledProcess(2, 0); } else if (3 == keyID) { ledProcess(3, 0); } else { pwmProcess(0); } }}int keyProcess(){ signal(SIGIO, sig_handler); fcntl(btnFd, F_SETOWN, getpid()); fcntl(btnFd, F_SETFL, fcntl(btnFd, F_GETFL) | FASYNC); while(1); return 0;}
客户端
#define MAX_BACKLOG 1024int tcp_server_init(const char *ip, const char *port){ int ret; int listenfd; int opt = 1; struct sockaddr_in srvaddr; memset(&srvaddr, 0, sizeof(struct sockaddr_in)); srvaddr.sin_family = AF_INET; if (ip != NULL) { ret = inet_pton(AF_INET, ip, &srvaddr.sin_addr); if (ret != 1) { fprintf(stderr, "server->ip: ip is error\n"); return -1; } } else srvaddr.sin_addr.s_addr = htonl(INADDR_ANY); if (port != NULL) srvaddr.sin_port = htons(atoi(port)); else { fprintf(stderr, "server->port: port must be assigned\n"); return -1; } listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd == -1) { perror("server->socket"); return -1; } setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); ret = bind(listenfd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr_in)); if (ret == -1) { perror("server->bind"); close(listenfd); return -1; } ret = listen(listenfd, MAX_BACKLOG); if (ret == -1) { perror("server->listen"); close(listenfd); return -1; } return listenfd;}int tcp_server_wait_connect(int listenfd){ int connfd; socklen_t addrlen; struct sockaddr_in cliaddr; addrlen = sizeof(struct sockaddr_in); memset(&cliaddr, 0, sizeof(struct sockaddr_in)); connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &addrlen); if (connfd == -1) { perror("server->accept"); return -1; } return connfd;}ssize_t tcp_server_recv(int connfd, void *buf, size_t count){ ssize_t ret; assert(buf != NULL); ret = read(connfd, buf, count); if (ret == -1) { perror("server->read"); return -1; } else if (ret == 0) { fprintf(stderr, "server->read: end-of-file\n"); return 0; } else return ret;}ssize_t tcp_server_send(int connfd, const void *buf, size_t count){ ssize_t ret; assert(buf != NULL); ret = write(connfd, buf, count); if (ret == -1) { perror("server->read"); return -1; } else return ret;}ssize_t tcp_server_recv_exact_nbytes(int connfd, void *buf, size_t count){ ssize_t ret; ssize_t total = 0; assert(buf != NULL); while (total != count) { ret = read(connfd, buf + total, count - total); if (ret == -1) { perror("server->read"); return -1; } else if (ret == 0) { fprintf(stderr, "server->read: end-of-file\n"); return total; } else total += ret; } return total;}ssize_t tcp_server_send_exact_nbytes(int connfd, const void *buf, size_t count){ ssize_t ret; ssize_t total = 0; assert(buf != NULL); while (total != count) { ret = write(connfd, buf + total, count - total); if (ret == -1) { perror("server->write"); return total; } else total += ret; } return total;}int tcp_server_disconnect(int connfd){ if (close(connfd)) { perror("server->close"); return -1; } return 0;}int tcp_server_exit(int listenfd){ if (close(listenfd)) { perror("server->close"); return -1; } return 0;}int tcp_client_init(void){ int sockfd; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd == -1) { perror("client->socket"); return -1; } return sockfd;}int tcp_client_connect(int sockfd, const char *ip, const char *port){ int ret; struct sockaddr_in srvaddr; memset(&srvaddr, 0, sizeof(struct sockaddr_in)); srvaddr.sin_family = AF_INET; if (ip != NULL) { ret = inet_pton(AF_INET, ip, &srvaddr.sin_addr); if (ret != 1) { fprintf(stderr, "client->ip: server ip is error\n"); return -1; } } else fprintf(stderr, "client->ip: server ip must be assigned\n"); if (port != NULL) srvaddr.sin_port = htons(atoi(port)); else { fprintf(stderr, "client->port: server port must be assigned\n"); return -1; } ret = connect(sockfd, (struct sockaddr *)&srvaddr, sizeof(struct sockaddr_in)); if (ret == -1) { perror("client->connect"); return -1; } return 0;}ssize_t tcp_client_recv(int sockfd, void *buf, size_t count){ ssize_t ret; assert(buf != NULL); ret = read(sockfd, buf, count); if (ret == -1) { perror("server->read"); return -1; } else if (ret == 0) { fprintf(stderr, "server->read: end-of-file\n"); return 0; } else return ret;}ssize_t tcp_client_send(int sockfd, const void *buf, size_t count){ ssize_t ret; assert(buf != NULL); ret = write(sockfd, buf, count); if (ret == -1) { perror("server->read"); return -1; } else return ret;}ssize_t tcp_client_recv_exact_nbytes(int sockfd, void *buf, size_t count){ ssize_t ret; ssize_t total = 0; assert(buf != NULL); while (total != count) { ret = read(sockfd, buf + total, count - total); if (ret == -1) { perror("server->read"); return -1; } else if (ret == 0) { fprintf(stderr, "server->read: end-of-file\n"); return total; } else total += ret; } return total;}ssize_t tcp_client_send_exact_nbytes(int sockfd, const void *buf, size_t count){ ssize_t ret; ssize_t total = 0; assert(buf != NULL); while (total != count) { ret = write(sockfd, buf + total, count - total); if (ret == -1) { perror("server->read"); return total; } else total += ret; } return total;}int tcp_client_exit(int sockfd){ if (close(sockfd)) { perror("client->close"); return -1; } return 0;}
服务器端
define REQ_DATA_SIZE 32#define HDR_DATA_SIZE 128//#define DEBUG#define CMDLEN 6extern pthread_mutex_t jpg_mutex;int processClientCmd(int connfd){ //¶ÁÈ¡¿Í»§¶Ë·¢ÀŽµÄÃüÁî int ret = 0; char cmd[CMDLEN] = { 0}; while (ret < CMDLEN - 1) { int tmp = recv(connfd, cmd+ret, CMDLEN - 1 - ret, 0); if (tmp < 0) { perror("recv cmd error"); return -1; } else if (0 == tmp) { break; } ret += tmp; //int i = 0; //for (i = 0; i < ret; i++) //printf("recv: %d ret=%d \r\n", cmd[i],tmp); } //printf("recv: %s\r\n", cmd); //ŽŠÀíÃüÁî if (cmd[1] < PWM_ID) { ledProcess(cmd[1], cmd[2]); } else if (cmd[1] == PWM_ID) { pwmProcess(cmd[2]); } return 0;}//int client_process(int connfd, struct jpg_buf_t *jpg)int client_process(int connfd){ /*int ret; char request[REQ_DATA_SIZE] = {0}; char response[HDR_ DATA_SIZE] = {0}; memset(request, 0, sizeof(request)); ret = tcp_server_recv(connfd, request, sizeof(request)); if (ret <= 0) return -1;#ifdef DEBUG fprintf(stdout, "server->read: the request is\n%s\n", request);#endif if (strstr(request, "pic") != NULL) { int ret; pthread_mutex_lock(&jpg_mutex); snprintf(response, sizeof(response), "%dlen", jpg->len);#ifdef DEBUG fprintf(stdout, "server->response: the response is: %s\n", response);#endif ret = tcp_server_send_exact_nbytes(connfd, response, sizeof(response)); if (ret != sizeof(response)) { fprintf(stderr, "server->write: send response failed\n"); return -1; } ret = tcp_server_send_exact_nbytes(connfd, jpg->buf, jpg->len); if (ret != jpg->len) { fprintf(stderr, "server->write: send response failed\n"); return -1; } pthread_mutex_unlock(&jpg_mutex); } return 0;*/ unsigned int piclen = 0; unsigned char * buf ; char response[20] = ""; char msg[3] = { 0}; int total = 0; int ret1 = 0; if (NULL == jpg) { printf("jpg has no memory alloc\r\n"); jpg = (struct jpg_buf_t *)malloc(sizeof(struct jpg_buf_t)); if (!jpg) { perror("malloc"); exit(EXIT_FAILURE); } memset(jpg, 0, sizeof(struct jpg_buf_t)); } ret1 = read(connfd,msg,3); printf("msg : %s\n",msg);//ÕâÀïœÓÊÕµœµÄÊÇpic£¬²»ÐèÒª×öÑéÖ€ if (strcmp(msg, "cmd") == 0) { return processClientCmd(connfd); } pthread_mutex_lock(&jpg_mutex); piclen = jpg->len; snprintf(response, sizeof(response), "%d#", piclen);//add length into response strcat(response,jpg->tp);// add tp to response strcat(response,"#"); if ('A' == jpg->btn){ //add btn to response strcat(response,"A"); } else{ strcat(response,"B"); } strcat(response, "#"); strcat(response, jpg->pm2_5); buf = (unsigned char *)malloc(piclen); memset(buf,0,piclen); memcpy(buf,jpg->buf,piclen); pthread_mutex_unlock(&jpg_mutex); ret1 = write(connfd,response,20); printf("ret = %d response = %s\n",ret1,response); while(piclen>total) { ret1 = write(connfd,buf+total,piclen-total); if(ret1 < 0) { break; } total += ret1; //printf("total = %d\n",total); } return 0;}
转载地址:http://goklf.baihongyu.com/