目 录
摘 要 I
Abstract II
前 言 1
- 开发工具和技术简介 1
1.1 硬件工具简介 1
1.1.1树莓派2代B板简介 1
1.1.2 其他硬件模块 1
1.2 软件工具介绍 3
1.2.1 Qt 3
1.2.2 Espeak TTS 3
1.2.3 WiringPi 3
1.2.4 PuTTY 5
1.2.5 Win32 Disk Imager 5
1.2.6 SDFormatter4exe 5
1.3 系统环境设置 5
1.3.1 系统的下载和烧写 5
1.3.2 系统的启动与连接 5
1.3.3 树莓派的基本配置 7
1.3.4 树莓派的网络配置 7
1.4 系统硬件连接图 8
2.系统可行性分析 9
2.1 市场可行性分析 9
2.2 技术可行性分析 10
2.3 经济可行性分析 10 - 系统的概要设计 11
3.1 系统总体设计 11
3.1.1 总体设计要求 11
3.1.2 系统的构成与功能 11
3.2 客户端设计 11
3.3 服务器设计 12 - 系统功能模块的实现 14
4.1客户端控制器模块 14
4.1.1用户主控界面设计 14
4.1.2主控界面主要代码 14
4.1.3登录界面设计 18
4.1.4登录模块主要代码 18
4.2服务器总控模块设计 21
4.2.1 总控线程模块 21
4.2.2 温度检测模块 27
4.2.3 入侵检测模块 30
4.2.4 土壤湿度检测模块 31
4.2.5 降雨检测模块 34
4.2.6 光控开关模块 35
4.2.7 Makefile 文件的编写 36 - 系统整体环境的搭建 38
结束语 39
参考文献 40
致 谢 41
3.系统的概要设计
3.1 系统总体设计
3.1.1 总体设计要求
本系统采用的是传统的C/S结构,在个人PC上安装客户端,然后完成注册,每次输入密码登陆完成对树莓派服务器各个功能模块的开启/关闭。整个系统以家庭路由器作为网络传输点,在相同网段内实现TCP通信传输机制,然后在服务器根据客户端的不同指令,完成各个独立模块相应的线程控制,独立线程控制独立的模块,开关灵活方便,而且,还可以根据PC或者红外遥控等不同的信号机制作出灵活的控制端的变换。
3.1.2 系统的构成与功能
客户端:Qt编写的界面,用户名、密码登陆,利用QTCP的网络通信方式,根据按钮的事件对服务端发送相应的编码指令。
服务器:利用Linux下的TCP通信技术,接收客户端的指令,然后开启/关闭相应的功能线程函数完成相应的控制。还根据传感器采集的数据,对各个功能模块作出相应的反馈。完成比较有趣的功能。
3.2客户端设计
客户端在此处相当于一个网络遥控器,控制服务器的模块功能。
客户端的业务结构图:
/* 各个模块线程函数的接口 */
void *temperature_thread(){
voice_deal();
}
void *invade_thread(){
invade_deal();
}
void *soil_thread(){
soil_deal();
}
void *light_thread(){
light_deal();
}
void *rain_thread(){
rain_deal();
}
void process_info(int s)
{
int recv_num;
int send_num;
char recv_buf[5];
char send_buf[5];
/* 各个模块的线程ID */
pthread_t temperature_pid;
pthread_t soil_pid;
pthread_t invade_pid;
pthread_t light_pid;
pthread_t rain_pid;
int temperature_ret;
int soil_ret;
int invade_ret;
int light_ret;
int rain_ret;
int *thread_ret = NULL;
/* 主线程接收网络指令模块 */
while(1){
printf("begin recv:\n");
recv_num = recv(s,recv_buf,sizeof(recv_buf),0);
if(recv_num <0){
perror("recv");
exit(1);
} else {
recv_buf[recv_num] = '\0';
printf("recv sucessful:%s\n",recv_buf);
}
if(!strcmp(recv_buf, temperatureOn)){ //温度相关模块操作
temperature_ret = pthread_create(&temperature_pid,
NULL, (void*)temperature_thread, NULL);
if(temperature_ret != 0){
printf("tempetature create pthread error\n");
return ;
}
printf("temperature pthread success\n");
}else if(!strcmp(recv_buf, temperatureOff)){
printf("temperature end work!\n");
if(0 != pthread_cancel(temperature_pid)){
printf("temperature cancel failed!\n");
}
}else if(!strcmp(recv_buf, invadeOn)){ //入侵检测模块操作
printf("invade on!\n");
invade_ret = pthread_create(&invade_pid, NULL,
(void *)invade_thread, NULL);
if(invade_ret != 0){
printf("create invade pthread error\n");
return ;
}
printf("invade pthread success\n");
}else if(!strcmp(recv_buf, invadeOff)){
printf("invade off!\n");
if(0 != pthread_cancel(invade_pid)){
printf("invade cancel failed!\n");
}
printf("invade cancel success!\n");
}else if(!strcmp(recv_buf, soilOn)){ //土壤湿度检测模块操作
printf("soil on!\n");
soil_ret = pthread_create(&soil_pid, NULL, (void *)soil_thread, NULL);
if(soil_ret != 0){
printf("create soil pthread error!\n");
return ;
}
printf("soil pthread success!\n");
}else if(!strcmp(recv_buf, soilOff)){
printf("soil off!\n");
if(0 != pthread_cancel(soil_pid)){
printf("soil canael failed!");
}
printf("soil cancel success!\n");
}else if(!strcmp(recv_buf, rainOn)){ //降雨检测模块操作
printf("rain on!\n");
rain_ret = pthread_create(&rain_pid, NULL, (void *)rain_thread, NULL);
if(rain_ret != 0){
printf("create rain pthread error\n");
return ;
}
printf("rain pthread success\n");
}else if(!strcmp(recv_buf, rainOff)){
printf("rain off!\n");
if(0 != pthread_cancel(rain_pid)){
printf("rain cancel failed\n");
return ;
}
printf("rain cancel success\n");
}else if(!strcmp(recv_buf, lightVoiceOn)){ //光控开关模块操作
printf("light vodice on!\n");
light_ret = pthread_create(&light_pid, NULL,
(void *)light_thread, NULL);
if(light_ret != 0){
printf("create light pthread error\n");
return ;
}
printf("light pthread success\n");
}else if(!strcmp(recv_buf, lightVoiceOff)){
printf("light voice off!\n");
if(0 != pthread_cancel(light_pid)){
printf("light cancel failed\n");
return ;
}
printf("light cancel success\n");
}else{
continue;
}
}
}