ZigBee+Linux+QT搭建自动喷淋系统

ZigBee+Linux+QT搭建自动喷淋系统


        本文提出了一种基于嵌入式Linux与ZigBee技术的花园自动喷淋系统,通过无线传感器网络技术和嵌入式系统编程、嵌入式网络技术的结合,构建一套针对自动灌溉领域应用的远程智能管理系统。
        该系统通过ZigBee技术实现远程数据的采集及控制命令的传输,采用CC2530模块作为控制装置的核心,外接温度传感器、土壤湿度传感器、光照强度传感器、烟雾气体浓度传感器、继电器模块分别实现数据的采集和灌溉控制;网关以A9系列的FS4412开发板作为主控模块,采用Linux操作系统作为软件系统,并在该操作系统上通过网络编程技术编写了登录注册服务器、摄像头服务器、串口服务器等网络管理代码,实现了网关服务器的搭建。网关数据最终传输到QT客户端进行进一步的分析及显示,QT客户端提供了良好的UI界面,方便用户进行人机交互。

系统设计方案

设计本系统总计框架如图所示,主要由数据采集终端模块,网关模块和PC客户端模块组成。该设计使用Linux操作系统网络编程技术,程序实现TCP服务器,Linux操作系统移植到FS4412开发板,完成对QT客户端的远程接入,数据终端环境数据通过ZigBee协议栈自主网络,传输信息数据到协调器节点,协调器与ARM框架A9系列的FS4412开发板之间使用UART传输数据,实现硬件模块的通信和控制。
在这里插入图片描述

数据采集终端模块

由环境信息采集传感器、CC2530主控芯片,喷淋装置,电源管理模块构成。传感器部件包括温度传感器、土壤湿度传感器、光照传感器,以获取当前植物生长的土壤湿度,环境温度,光照强度。喷淋装置通过继电器控制,连接电源,水泵开始正常工作,通过喷头进行喷淋灌溉。数据采集终端硬件硬件设计图(包含传感器硬件选型)如下所示

在这里插入图片描述

开发环境

Ubuntu20.04:VMware Workstation Pro搭载的Linux操作系统,用来搭建串口通信和数据处理,登录注册,视频监控 的服务器。
QT4.6.2:QT版本,用来搭建UI界面,方便人机交互。
IAR EW:zigbee系列,CC2530开发板软件开发环境。

软件设计

在系统设计方案和硬件选型已经完成的基础上,我们开始进行软件部分的设计。为更好区分各功能模块,软件设计部分分别搭建三个独立运行的功能服务器端,最后在QT客户端实现完整的功能。
Ubuntu20.04环境下程序设计
登录注册
login.c


#include <stdio.h>  
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <stdlib.h>


//搭建tcp服务器
int main(void) 
{
	int sockfd,connfd;
	int ret;

	sockfd = socket(AF_INET,SOCK_STREAM , 0);  //买手机 
	//如果成功就返回生成的SOCKET,如果失败就返回INVALID_SOCKET(-1)
	if(sockfd == -1)  
	{  
		perror("socket error");  
		return 1;  
	}   

	//卡  addr

	struct sockaddr_in addr;

	addr.sin_family = AF_INET;
	addr.sin_port = htons(5555);
	addr.sin_addr.s_addr = inet_addr("0");

	ret = bind(sockfd,(struct sockaddr *)&addr,sizeof(addr));   //插卡 

	//listen函数的第一个参数即为要监听的socket描述字,第二个参数为相应socket可以排队的最大连接个数。

	listen(sockfd,5); //开机
	if(listen(sockfd,5) == -1)  
	{  
		perror("listen error");  
		return 1;  
	}
	while(1)
	{
		connfd = accept(sockfd,NULL,NULL);  //接听

		if(connfd<0)
		{
			perror("accpet() failed");
			return 1; 
		}
		printf("链接成功\n");

		while(1) 
		{

		char buf[256];
		char str1[32]; //注册账号
		char str2[32]; //注册密码
		char str3[32]; //登陆账号
		char str4[32];  //登陆密码
		//超级用户
		char root[255] = "root";
		char  m[255] = "abc";


			bzero(buf,sizeof(buf));  //清空数组
			ret = recv(connfd,buf,sizeof(buf),0);


			if(ret<=0){ 
				printf("client quit\n");
				break;
			}


			
			if(strcmp(buf,"1") == 0) {

				
				bzero(str1,sizeof(str1));
				bzero(str2,sizeof(str2)); 
				recv(connfd,str1,sizeof(str1),0);

				recv(connfd,str2,sizeof(str2),0);

				printf("\n注册\n帐号/密码\n%s\n%s\n",str1,str2);
				bzero(buf,sizeof(buf));

				send(connfd,"s",sizeof("s"),0);
				//break;

			} else if(strcmp(buf,"2") == 0) {

				bzero(str3,sizeof(str3));
				bzero(str4,sizeof(str4)); 
				recv(connfd,str3,sizeof(str3),0);

				recv(connfd,str4,sizeof(str4),0);
				bzero(buf,sizeof(buf));
				if(( strcmp(str1,str3) == 0) && (strcmp(str2,str4) == 0) || (strcmp(root,str3) == 0) && (strcmp(m,str4) == 0) ) 
				{
					
					printf("\n登陆成功\n");

					send(connfd,"l",sizeof("l"),0);
					
				} else {
					
					printf("\n登陆失败\n");
					printf("\n帐号/密码\n%s\n%s\n",str3,str4);
					
					send(connfd,"x",sizeof("x"),0);
				}

			}
			else if(strcmp(buf,"3") == 0){
				
			
				printf("\n退出\n");
		         }
		}
	}
	return 0;
}





串口控制数据服务器
main.c

#include "serial.h"

int main()
{	
	int fd=open("/dev/ttyUSB0",O_RDWR|O_NOCTTY);
	if(fd<0)
	{
		printf("fd=%d:open error\n",fd);
		perror("open:");
		return -1;
	}
	printf("%d\n",fd);

	int ret=set_serial(fd,115200,8,'N',1);
	if(ret<0)
	{
		perror("set_serial:");
		return -1;
	}

	server_init(fd);

}

serial.c

#include "serial.h"

int set_serial(int fd,int nspeed,int nbits,char nevent,int nstop)
{
	struct termios newttys1,oldttys1;
	//保存原有的串口配置
	if(tcgetattr(fd,&oldttys1)!=0)
	{
		perror("setserial 1\n");
		return -1;
	}
	//恢复串口为阻塞状态
	if(fcntl(fd,F_SETFL,0)<0)
	{
		printf("fcntl failed!\n");
		return -1;
	}
	else
	{
		printf("fcntl=%d\n",fcntl(fd,F_SETFL,0));
	}

	bzero(&newttys1,sizeof(newttys1));
	//CREAD开启串行数据接收,CLOCAL打开本地连接模式
	newttys1.c_cflag|=(CLOCAL|CREAD);
	newttys1.c_cflag&=~CSIZE;//设置数据位
	//数据位选择
	switch(nbits)
	{
		case 7:
			newttys1.c_cflag|=CS7;
			break;
		case 8:
			newttys1.c_cflag|=CS8;
			break;
	}
	//设置奇偶校验位
	switch(nevent)
	{
		case 'O'://奇校验
			newttys1.c_cflag |= PARENB;//开启奇偶校验
			//INPCK打开输入奇偶校验,ISTRIP去除字符的第八个比特
			newttys1.c_iflag |= (INPCK|ISTRIP);
			newttys1.c_cflag |= PARODD;//启动奇校验(默认偶校验)
			break;
		case 'E'://偶校验
			newttys1.c_cflag |= PARENB;
			newttys1.c_cflag |=(INPCK|ISTRIP);
			newttys1.c_cflag &=~PARODD;
			break;
		case 'N':
			newttys1.c_cflag&=~PARENB;
			break;
	}
	//设置波特率
	switch(nspeed)
	{
		case 2400:
			cfsetispeed(&newttys1,B2400);
			cfsetospeed(&newttys1,B2400);
			break;
		case 4800:
			cfsetispeed(&newttys1,B4800);
			cfsetospeed(&newttys1,B4800);
			break;
		case 9600:
			cfsetispeed(&newttys1,B9600);
			cfsetospeed(&newttys1,B9600);
			break;
		case 115200:
			cfsetispeed(&newttys1,B115200);
			cfsetospeed(&newttys1,B115200);
			break;
		default:
			cfsetispeed(&newttys1,B9600);
			cfsetospeed(&newttys1,B9600);
			break;
	}
	//设置停止位,若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB
	if(nstop==1)
	{
		newttys1.c_cflag&=~CSTOPB;
	}
	else if(nstop==2)
	{
		newttys1.c_cflag|=CSTOPB;	
	}
	//设置最少字符和等待时间,对于接收字符和等待时间没有特别要求时
	newttys1.c_cc[VTIME]=0;//非规范模式读取时的超时时间
	newttys1.c_cc[VMIN]=0;//非规范模式读取时的最小字符数
	//tcflush清空终端未完成的输入/输出请求及数据;
	//TCIFLUSH表示清空正收到的数据,且不读去出来
	tcflush(fd,TCIFLUSH);
	//激活配置使其生效
	if((tcsetattr(fd,TCSANOW,&newttys1))!=0)
	{
		perror("com set error");
		return -1;
		
	}
	return 0;
}

serial.h

#ifndef _SERIAL_H_
#define _SERIAL_H_

#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>

int server_init(int fd);
int set_serial(int fd,int nspeed,int nbits,char nevent,int nstop);



#endif

server.c

#include "serial.h"

unsigned char envbuf[15]={0};


int server_init(int fd)
{
	int sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
	{
		perror("socket");
		return -1;
	}
	struct sockaddr_in seraddr;
	struct sockaddr_in cliaddr;
	socklen_t len=sizeof(cliaddr);
	bzero(&seraddr,sizeof(seraddr));
	bzero(&cliaddr,sizeof(cliaddr));
	seraddr.sin_family=AF_INET;
	seraddr.sin_port=htons(7777);
	seraddr.sin_addr.s_addr=inet_addr("0");

	if(bind(sockfd,(const struct sockaddr*)&seraddr,sizeof(seraddr))<0)
	{
		perror("bind");
		return -1;
	}


	if(listen(sockfd,5)<0)
	{
		perror("listen");
		return -1;
	}

	int connfd=accept(sockfd,(struct sockaddr*)&cliaddr,&len);
	if(connfd<0)
	{
		perror("accept");
		return -1;
	}
	printf("%s:%d connected!!\n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));
	
	
	char buf[32]={0};
	int ret;
	
	while(1)
	{

		if((ret=read(connfd,buf,sizeof(buf)))>0)
		{
			if(strncmp(buf,"env",3)==0)
			{
				bzero(envbuf,sizeof(envbuf));
				//send 环境
				if(read(fd,envbuf,sizeof(envbuf))==sizeof(envbuf));
				{
					
					printf("=====%s=====\n", envbuf);
					int ret = write(connfd,envbuf,sizeof(envbuf));
					if(ret<0)
					{


						perror("write");

						exit(-1);
					}
					printf("ret = %d\n", ret);
				}
			}
                

			else if(strncmp(buf,"auto_on",7)==0)
			{
				//发送命令,开启自动喷淋模式
				envbuf[0]=0xdd;
				envbuf[4]=0x00;
				if(write(fd,envbuf,5)<0)
				{

					perror("write");
					return -1;
				}

			}
			else if(strncmp(buf,"auto_off",8)==0)
			{
				//发送命,关闭自动喷淋模式
				envbuf[0]=0xdd;
				envbuf[4]=0x01;
				if(write(fd,envbuf,5)<0)
				{
					perror("write");
					return -1;
				}
			}
			else if(strncmp(buf,"hand_on",7)==0)
			{
				//发送命令,手动打开喷淋装置
				envbuf[0]=0xdd;
				envbuf[4]=0x02;
				if(write(fd,envbuf,5)<0)
				{
					perror("write");
					return -1;
				}
			}
			else if(strncmp(buf,"hand_off",8)==0)
			{
				//发送命,手动关闭喷淋装置
				envbuf[0]=0xdd;
				envbuf[4]=0x03;
				if(write(fd,envbuf,5)<0)
				{
					perror("write");
					return -1;
				}
			}

		}

		else if(ret<0)
		{
			perror("read");
			exit(-1);
		}

		else
		{
			printf("client quit!\n");
			break;
		}
	
		bzero(buf,sizeof(buf));

	}



}

串口数据控制服务器程序放在一个文件夹运行,运行方式可参考
1.编译:gcc *.c -o 新命名
2.运行:./新命名

图像视频服务器
camera.c


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <stdlib.h>
#include <linux/videodev2.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <arpa/inet.h>
typedef struct{
	int length;
	int offset;
	char *start;
}VideoBuffer;

VideoBuffer pic_buffers[3];
int fd=0;
int sockfd=0;
struct v4l2_buffer enqueue,dequeue;
//打开摄像头
int open_camera(char *path)
{
	fd=open(path,O_RDWR);
	if(fd<0)
	{
		printf("open /dev/video0 failed\n");
		return -1;
	}
	return 0;
}
//关闭摄像头
int close_camera()
{
	close(fd);
}
//获取摄像头相关信息
void get_camerainfo(void)
{
	struct v4l2_format fmt;
	fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	if(ioctl(fd,VIDIOC_G_FMT,&fmt)==-1)
	{
		perror("VIDIOC_G_FMT:");
		return ;
	}
	printf("current data format information:\n");
	printf("width=%d\n",fmt.fmt.pix.width);
	printf("height=%d\n",fmt.fmt.pix.height);
}
//设置摄像头具体格式
int set_format()
{
	struct v4l2_format fmt;
	fmt.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	fmt.fmt.pix.width=640;
	fmt.fmt.pix.height=480;
	fmt.fmt.pix.pixelformat=V4L2_PIX_FMT_MJPEG;
	fmt.fmt.pix.field=V4L2_FIELD_INTERLACED;
	int ret=ioctl(fd,VIDIOC_S_FMT,&fmt);
	if(ret<0)
	{
		perror("VIDIOC_S_FMT:");
		return -1;
	}
	printf("----------------VIDIOC_S_FMT------------------\n");
	printf("type:%d\n",fmt.type);
	printf("width:%d\n",fmt.fmt.pix.width);
	printf("heigt:%d\n",fmt.fmt.pix.height);
	return 0;
}
//获取摄像头图片采集的缓存buf
int get_buf(void)
{
	struct v4l2_requestbuffers req;
	memset(&req,0,sizeof(req));
	req.count=3;
	req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	req.memory=V4L2_MEMORY_MMAP;
	if(ioctl(fd,VIDIOC_REQBUFS,&req)<0)
	{
		perror("VIDIOC_REQBUFS:");
		return -1;
	}
	return 0;
}
//映射buf到用户空间
void bufmap(void)
{
	int numBufs=0;
	struct v4l2_buffer temp_buf;
	for(numBufs=0;numBufs<3;numBufs++)
	{
		memset(&temp_buf,0,sizeof(temp_buf));
		temp_buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
		temp_buf.memory=V4L2_MEMORY_MMAP;
		temp_buf.index=numBufs;
		//获取第一个缓存的地址到pic_buf
		if(ioctl(fd,VIDIOC_QUERYBUF,&temp_buf)<0)
		{
			printf("VIDIOC_QUERYBUF failed\n");
			return;
		}
		pic_buffers[numBufs].length=temp_buf.length;
		pic_buffers[numBufs].offset=(size_t)temp_buf.m.offset;
		pic_buffers[numBufs].start=mmap(NULL,temp_buf.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,temp_buf.m.offset);
		if(pic_buffers[numBufs].start==MAP_FAILED)
		{
			perror("pic_buffers error:\n");
			return ;
		}
		//将缓存取放入队列中
		if(ioctl(fd,VIDIOC_QBUF,&temp_buf)<0)
		{
			perror("VIDIOC_QBUF:");
			return ;
		}
	}
	enqueue.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	dequeue.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	enqueue.memory=V4L2_MEMORY_MMAP;
	dequeue.memory=V4L2_MEMORY_MMAP;

}
//开始采集
void start_on()
{
	enum v4l2_buf_type type;
	type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
	if(ioctl(fd,VIDIOC_STREAMON,&type)<0)
	{
		perror("VIDIOC_STREAMON :");
		return ;
	}
}
int get_picture(char *buffer,int *length)
{
	int ret;
	ret=ioctl(fd,VIDIOC_DQBUF,&dequeue);
	if(ret!=0)
	{
		perror("VIDIOC_DQBUF:");
		return -1;
	}
	//获取图片数据
	memcpy(buffer,pic_buffers[dequeue.index].start,pic_buffers[dequeue.index].length);
	*length=pic_buffers[dequeue.index].length;
	//把数据取出后,重新入队
	enqueue.index=dequeue.index;
	ret=ioctl(fd,VIDIOC_QBUF,&enqueue);
	if(ret!=0)
	{
		perror("enqueue fail");
		return -1;
	}
	return 0;

}
//停止摄像头
int stop_camera()
{
	int ret;
	int off=1;
	ret=ioctl(fd,VIDIOC_STREAMOFF,&off);
	if(ret!=0)
	{
		perror("stop camera fail");
		return -1;
	}
	return 0;
}
int bufunmap()
{
	int i;
	for(i=0;i<3;i++)
	{
		munmap(pic_buffers[i].start,pic_buffers[i].length);
	}
	return 0;
}
int server_init()
{
	sockfd=socket(AF_INET,SOCK_STREAM,0);
	if(sockfd<0)
	{
		perror("socket:");
		return -1;
	}

	struct sockaddr_in seraddr;
	memset(&seraddr,0,sizeof(seraddr));
	seraddr.sin_family=AF_INET;
	seraddr.sin_port=htons(8888);
	seraddr.sin_addr.s_addr=inet_addr("0.0.0.0");
	if(bind (sockfd,(const struct sockaddr*)&seraddr,sizeof(seraddr))<0)
	{
		perror("bind");
		return -1;
	}

	int ret=listen(sockfd,7);

	if(ret<0)
	{
		perror("listen:");
		return -1;
	}
	int connfd=accept(sockfd,NULL,NULL);
	if(connfd>0)
	{
		printf("client has connectd!\n");
	}
	else
	{
		printf("connect failed\n");
		return -1;
	}
	return connfd;
}
char pic[1024*768*3]={0};
int main()
{
	int length=0;
	int connfd=0;
	open_camera("/dev/video0");
	get_camerainfo();
	set_format();
	get_buf();
	bufmap();
	connfd=server_init();
	start_on();
	char piclen[20]={0};
	while(1)
	{
		get_picture(pic,&length);
		printf("pic length=%d\n",length);
		sprintf(piclen,"%d",length);
		if(write(connfd,piclen,20)<0)
		{
			perror("write:");
			return -1;
		}
		if(write(connfd,pic,length)<0)
		{
			perror("write:");
			return -1;
		}
	}
//	stop_camera();
//	bufunmap();

//	close_camera();

}


QT客户端设计
Headers模块源码(头文件)
login.h

#ifndef LOGIN_H
#define LOGIN_H

#include <QWidget>
#include <QMainWindow>
#include <QTcpSocket>
#include <QDebug>

namespace Ui {
class login;
}

class login : public QWidget
{
    Q_OBJECT

public:
    explicit login(QWidget *parent = 0);
    ~login();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void tcp_recv();

    void on_pushButton_3_pressed();

private:
    Ui::login *ui;
    QTcpSocket *socket;
};

#endif // LOGIN_H

camera.h

#ifndef CAMERA_H
#define CAMERA_H
#include <QPainter>
#include <QWidget>
#include <QTcpSocket>
#include <QMainWindow>
#include <QDebug>

namespace Ui {
class camera;
}

class camera : public QWidget
{
    Q_OBJECT

public:
    explicit camera(QWidget *parent = 0);
    ~camera();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void picshow();

private:
    Ui::camera *ui;
    QTcpSocket *socket;
    int flag = 0;
    char piclength[20]={0};
    int piclen = 0;
    char picbuf[1024*768*3];
};

#endif // CAMERA_H

mainwindows.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
#include <QTimer>
#include <camera.h>
#include <login.h>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

    void on_pushButton_3_clicked();

    void on_pushButton_4_clicked();

    void show_connect();
    void senddata();
    void recvdata();


    void on_pushButton_connect_clicked();

private:
    Ui::MainWindow *ui;
    QTcpSocket *tcpsocket;
    QTimer *timer;
};

#endif // MAINWINDOW_H

Sources模块源码
login.cpp

#include "login.h"
#include "ui_login.h"
#include "mainwindow.h"
#include <QLabel>
#include <QMovie>
login::login(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::login)
{
    ui->setupUi(this);
    socket = new QTcpSocket;
//设置背景图
    QPixmap pixmap = QPixmap(":/picture/6.jpg").scaled(this->size());
    QPalette palette(this->palette());
    palette.setBrush(QPalette::Background, QBrush(pixmap));
    this->setPalette(palette);

    //设置label窗口部件动态图
//    ui->label->setScaledContents(true);
//    QMovie *iconShow = new QMovie(":5.gif");
//    ui->label->setMovie(iconShow);
//    iconShow->start();


    //this->close();

    connect(socket,&QTcpSocket::readyRead,this,&login::tcp_recv);
}

login::~login()
{
    delete ui;
}

void login::on_pushButton_3_pressed()
{
    socket->abort();
    socket->connectToHost("192.168.1.30", 5555);


}


void login :: tcp_recv()
{
    QByteArray data = socket->readAll();

    qDebug()<<"recv:"<<QString(data);
    if(0==strcmp(data,"l")){
        //this->close();
        //MainWindow *fa = new MainWindow();
        //this->close();
        //fa->show();
    }
}

void login::on_pushButton_clicked()
{
    //登录功能模块

    MainWindow *fa = new MainWindow();
    this->close();
    fa->show();
    QString name =  ui->lineEdit->text();
    QString pawd = ui->lineEdit_2->text();
    char buf[256]="2";
    socket->write(buf,sizeof(buf));  //发送注册请求
    char data[32];
    strcpy(data, name.toLatin1().data());
    socket->write(data,32);         //发送名字
    strcpy(data,pawd.toLatin1().data());
    socket->write(data,32);         //发送密码

}

void login::on_pushButton_2_clicked()
{
    //注册功能模块

    QString name =  ui->lineEdit->text();//获取用户名
    QString pawd = ui->lineEdit_2->text();//获取密码
    char buf[256]="1";
    socket->write(buf,sizeof(buf)); //发送注册请求
    char data[32];
    strcpy(data, name.toLatin1().data());
    socket->write(data,32);         //发送名字
    strcpy(data, pawd.toLatin1().data());
    socket->write(data,32);         //发送密码
    socket->read(data,32);

}




camera.cpp

#include "camera.h"
#include "ui_camera.h"
#include "mainwindow.h"
camera::camera(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::camera)
{
    ui->setupUi(this);
    socket = new QTcpSocket;

    //设置背景图片
    QPixmap pixmap = QPixmap(":/picture/10.jpg").scaled(this->size());
    QPalette palette(this->palette());
    palette.setBrush(QPalette::Background, QBrush(pixmap));
    this->setPalette(palette);

    connect(socket,&QTcpSocket::readyRead,this,&camera::picshow);
}

void camera::picshow()
{
    if(flag == 0)
    {
        socket->read(piclength, 20);
        qDebug()<<"piclength="<<piclength;
        piclen=atoi(piclength);
        flag=1;
    }
    else
    {
        if(socket->bytesAvailable()<piclen)
            return ;
        socket->read(picbuf,piclen);
        QPixmap pixmap;
        qDebug()<<piclen;
        pixmap.loadFromData((uchar*)picbuf,piclen,"JPEG");
        ui->label->setPixmap(pixmap);
        flag=0;
    }
}

camera::~camera()
{
    delete ui;
}

void camera::on_pushButton_clicked()
{
    // socket->connectToHost("10.67.27.12", 8888);
     socket->connectToHost("192.168.1.30", 8888);
}

void camera::on_pushButton_2_clicked()
{
    socket->abort();
    this->close();
//    MainWindow *mainW = new MainWindow();
//    mainW->show();

}

mainwindows.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QPixmap pixmap = QPixmap(":/picture/8.jpg").scaled(this->size());
    QPalette palette(this->palette());
    palette.setBrush(QPalette::Background, QBrush(pixmap));
    this->setPalette(palette);


    tcpsocket = new QTcpSocket(this);
    timer = new QTimer(this);

    ui->lcdSoil->display(0);
    ui->lcdTemp->display(0);
    ui->lcdLight->display(0);
    ui->lcdGas->display(0);

    connect(tcpsocket, SIGNAL(connected()), this, SLOT(show_connect()));
    connect(tcpsocket, SIGNAL(readyRead()), this, SLOT(recvdata()));
    connect(timer, SIGNAL(timeout()), this, SLOT(senddata()));
}

MainWindow::~MainWindow()
{
    delete ui;

}

void MainWindow::on_pushButton_connect_clicked()
{
    //tcpsocket->connectToHost(ui->lineEdit->text(),ui->lineEdit_2->text().toInt());
   // timer->start(2000);
    tcpsocket->abort();
    tcpsocket->connectToHost("192.168.1.30",7777);
    timer->start(2000);

}

void MainWindow::show_connect()
{
    ui->lineEdit_3->setText("connected!");
}

//发送命令请求环境数据
void MainWindow::senddata()
{
    char cmd[] = "env";
    tcpsocket->write(cmd, sizeof(cmd));
}


//环境数据接收
void MainWindow::recvdata()
{
    char buf[16] = {0};
    tcpsocket->read(buf,15);
    qDebug()<<buf;

    int soilHum, dstemp, GasData,LightData;

    soilHum = QString(buf).split(' ')[0].toInt();
    dstemp = QString(buf).split(' ')[1].toInt();
    GasData = QString(buf).split(' ')[2].toInt();
    LightData = QString(buf).split(' ')[3].toInt();
    //传输到界面显示
    ui->lcdSoil->display(soilHum);
    ui->lcdTemp->display(dstemp);
    ui->lcdLight->display(LightData);
    ui->lcdGas->display(GasData);
}

void MainWindow::on_pushButton_2_clicked()
{
    //自动喷淋选择
    static int flag = 0;
    if(flag == 0)
    {
        tcpsocket->write("auto_on");
        ui->pushButton_2->setText("关闭自动喷淋");
        flag = 1;
    }
    else{
        tcpsocket->write("auto_off");
        ui->pushButton_2->setText("开启自动喷淋");
        flag = 0;
    }

}

void MainWindow::on_pushButton_3_clicked()
{
    //手动打开喷淋
    static int flag = 0;
    if(flag == 0)
    {
        tcpsocket->write("hand_on");
        ui->pushButton_3->setText("关闭手动喷淋");
        flag = 1;
    }
    else{
        tcpsocket->write("hand_off");
        ui->pushButton_3->setText("开启手动喷淋");
        flag = 0;
    }

}

void MainWindow::on_pushButton_4_clicked()
{

    camera *cam = new camera();
    cam->show();

}

main.cpp

#include "mainwindow.h"
#include <QApplication>
#include "login.h"
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//    MainWindow w;
//    w.show();
    login t;
    t.show();

    return a.exec();
}

界面设计展示
登录注册界面
在这里插入图片描述
数据显示及其控制界面
在这里插入图片描述
视频监控界面
在这里插入图片描述
注:需要CC2530底层设计代码可私信,传感器引脚定义如下
在这里插入图片描述
在完成系统间的连通测测试,简单录了一个视频,介绍本系统使用流程,以及基本实现的功能。

视频展示

以上就是自动喷淋系统设计过程,本系统中,各部分功能代码是分开的,所以有着很强的可操作性,可根据喷淋范围将zigbee+路由的形式,扩大环境监测范围,把CC2530开发板替换成STM32或其它开发板均可实现功能,cortex-A9开发板主要提供一个无线网关功能,将Linux服务器移植到开发板,只用网线连接电脑,实现远程监控,也可直接将CC2530开发板的协调器端接入USB接口到电脑,均可实现自动喷淋功能。觉得麻烦的话,可以使用esp8266开发板,连接one-net云平台,该平台。

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值