博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
智能家居系统
阅读量:2051 次
发布时间:2019-04-28

本文共 14596 字,大约阅读时间需要 48 分钟。

智能家居系统

1.项目背景

本项目所完成的是一个智能家居系统,使用Linux操作系统搭建的远程网络视频监控系统的解决方案。着重于实现一个易搭建,易配置,通用性好,能用于临时性监控的网络视频服务器,可以让客户机实时监控远程目标摄像头,实时共享摄像头控制空调、热水器、窗帘等家居智能设备。

智能家居系统让您轻松享受生活。出门在外,您可以通过电话、电脑来远程遥控您的家居各智能系统,例如在回家的路上提前打开家中的空调和热水器;到家开门时,借助门磁或红外传感器,系统会自动打开过道灯,同时打开电子门锁,安防撤防,开启家中的照明灯具和窗帘迎接您的归来;回到家里,使用遥控器您可以方便地控制房间内各种电器设备。

2.硬件说明

本系统采用ARM Cortex-A94-Core核心板和Ubuntu环境开发

开发语言为C语言
在这里插入图片描述

(1)温湿度传感器

温湿度传感器可以将采集到的温度实时转换成输出信号,并在终端上显示,当室内温度超过闹值或湿度不在设定范国内,会通过度异常信息。
(2)蜂鸣器
当室内的温度达到火灾值,或有人非法进入时,系统会自动发出报警声。
(3)USB摄像头
网络远程监控摄像头,进行监控并将监视画面录制下来,可实时将影像透过网络传给用户终端,使用户能够随时随地观察家里的情况。
(4)LED 显示电器是否处于工作中
(5)电位器(pm_2.5)
(6)远程终端
由Qt制作的用户界面,来显示实时监控画面、温度数据、PM_2.5数据以及空调、热水器、窗帘控制按键、并且具有异常警报按钮。

3.系统软件设计

(1)系统模块组织

在这里插入图片描述

在这里插入图片描述

(2)系统模块说明

1系统初始化

对整个系统进行配置及初始化。
2实时监控子系统
系统的实时监控和处理。
A)室内温度监控
B)室内PM_2.5指数监控
C)室内视频监控
3远程服务子系统
A)数据显示请求
B)远程控制

(3)终端软件系统模块设计

在这里插入图片描述

(4)软件模块设计说明

主界面

包含:实时温度显示、视频获取、远程家具控制和报警。
在这里插入图片描述

4.系统流程

(1)Liunx配置

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

(2)nfs配置

(网络文件系统,将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表示强制卸载)

(3)网络配置

虚拟机->设置->网络适配器->自定义->VMnet0->确定

编辑->虚拟网络编辑器->更改设置->VMnet0->桥接模式->Realetk PCLe GBE family
Controller

(4)Putty挂载

设置启动环境变量

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

5.前端设计

连接:连接到Putty,连通开发板

关闭:断开Putty
温度:连通后,实时显示温度
PM2.5:连通后,实时显示PM2.5值
紧急开关:报警器打开,颜色变红;报警器关闭,颜色变绿
空调:点击后,LED2亮,再次点击,LED2关闭
窗帘:点击后,LED3亮,再次点击,LED3关闭
热水器点击后,LED4亮,再次点击,LED4关闭
报警器:点击后,蜂鸣器响,再次点击,蜂鸣器停止响

6.代码

获取温湿度

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/

你可能感兴趣的文章
Ubuntu 18.04 swap分区扩展
查看>>
Sophus的编译与使用
查看>>
Python中切片的用法
查看>>
安装OpenCV时提示缺少boostdesc_bgm.i文件的问题解决方案(附带百度云资源)
查看>>
最简单的 kubernetes 高可用安装方式
查看>>
Contour 学习笔记(一):使用 Contour 接管 Kubernetes 的南北流量
查看>>
K8s 学习者绝对不能错过的最全知识图谱(内含 58个知识点链接)
查看>>
Contour 学习笔记(一):使用 Contour 接管 Kubernetes 的南北流量
查看>>
Contour 学习笔记(二):使用级联功能实现蓝绿部署和金丝雀发布
查看>>
Kubectl 的替代品:kubeman
查看>>
以后别人再问你什么是 Istio,就把这篇文章甩给他
查看>>
新书推荐 |《Prometheus监控实战》
查看>>
Tekton Pipeline 教程
查看>>
Istio 1.3 发布,HTTP 遥测不再需要 Mixer
查看>>
Kubernetes Dashboard 终结者:KubeSphere
查看>>
AdGuard Home 安装使用教程
查看>>
Porter:面向裸金属环境的 Kubernetes 开源负载均衡器
查看>>
Kubernetes Dashboard 终结者:KubeSphere
查看>>
手把手教你部署 Istio 1.3
查看>>
CentOS 8 都发布了,你还不会用 nftables?
查看>>