智能家居系统

智能家居系统

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=0if (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	1024

int 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 6
extern 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;
}
  • 2
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值