课程设计
基于物联网的远程环境监测系统的设计
摘要
针对当前监控系统在室内环境监控中存在的弊端,为实现室内环境参数监测的自动化和实时性,设计了一种基于物联网技术的室内环境参数远程监测系统。该系统综合运用无线传感器网络技术、 嵌入式计算技术、GPRS 无线通信技术。重点介绍了监控中心和终端节点的设计思路和软硬件实施方案。实验表明: 该系统成本低、 功耗小,使用简单,工作稳定,测量精度较高,具有较高的实用价值。
关键词: 物联网; 室内环境远程监测; 无线传感网络; 通用分组无线业务
目录
摘要............................................................... 1
1.1 引言........................................................ 1
1.2 总体结构与工作原理.......................................... 1
第二章 系统硬件设计................................................ 2
2.1 终端节点的硬件设计.......................................... 3
2.2 监控中心硬件设计............................................ 4
第三章 系统软件设计................................................ 5
3.1 终端节点软件设计............................................ 5
3.2 监控中心软件设计............................................ 6
3.3 GPRS 模块软件设计........................................... 6
第四章 系统测试.................................................... 7
第五章 结论........................................................ 7
参考文献........................................................... 8
第一章 绪论
1.1 引言
物联网是新一代的信息技术,是物与物互联的网络,英文名是“The Internet of things”。通过各种信息传感设备,实时采集任何需要监控、连接、互动的物体或过程,采集各种需要的信息,与互联网结合形成的一个巨大网络。其目的是实现物与物、物与人,所有的物品与网络的连接,方便识别、管理和控制。GSM是全球移动通信系统,技术成熟,资费低,已广泛应用。我国经济的高速发展导致了一系列问题,自然环境急剧恶化,矿山爆炸,森林火灾等事故不断, 家庭失火、 煤气中毒更是是现实生活中经常出现的家庭灾害,随着经济的发展和人民生活水平的提高,各种原料制成建筑装饰材料已走入家庭,造成室内空气污染,公认具有代表性的化学物质是甲醛,甲醛是现在被各界普遍认为是室内第一杀手,如果甲醛含量超标对人体伤害甚为严重,这些都严重威胁人民的生命和财产安全,造成巨大的经济损失和人员安全。于是,这加强了对智能、实时、高效的环境监测系统的需求。目前,室内环境参数监测系统多数为有线方式,这种方式需要大量布线,影响室内美观,而且对系统的维护和管理也很不方便,一个节点出现问题时,会影响其他节点的工作。现在应用比较普遍的无线传感器网络主要针对户外环境恶劣、 条件复杂的区域,这些系统需要考虑数据采集、 数据融合、 数据转发及数据管理等关键问题。然而,对于特定的室内环境监测,这些系统则显得过于复杂和实用性低。本文利用物联网技术和无线通信技术,设计了一种室内环境监测系统,克服了传统方式的局域性和区域性,具有移动性强、 简单、 可靠、 经济等优点。
1.2 总体结构与工作原理
基于物联网的室内环境监测系统网络结构包括监控中心、 路由节点和终端节点三层体系结构,系统框架结构如图1所示。监控中心与终端节点之间通过层次型设计构建信息传输网络。终端节点将实时采集的室内信息通过层次性网络传输到监控中心。路由节点是整个监测系统中局部监测群体的核心节点,负责转发通信和维护网内路径; 终端节点是带有传感器的子节点,负责对室内环境参数( 煤气、甲醛、 烟雾、 温度等) 的实时监测,把监测的数据采用无线方式经路由节点传给监控中心; 监控中心显示、 存储终端节点的信息,如果有危险情况发生,蜂鸣器会发出报警声,并通过通用分组无线业务( GPRS) 模块以短信的形式把报警信息发送到住宅主人手机中。实现住宅主人对室内环境情况的远程监测功能。
图1-1 系统框架
第二章 系统硬件设计
在节点的设计过程中,考虑到低功耗的要求,硬件方面处理核心决定选择低功耗片上系统芯片CC2530。CC2530是符合Zig Bee 标准的2. 4 GHz 片上系统( system on chip,SoC) ,适用于各种Zig Bee 和Zig Bee PRO 的无线传感网络节点,包括协调器、 路由器和终端节点。CC2530 在CC2430 的基础上,根据CC2430 实际应用存在的问题进行一些改进。CC2530 是集IEEE 802. 15. 4,ZigBee 和RF4CE 应用的一个真正的片上系统( SoC) 解决方案。它能够以非常低的总材料成本建立强大的网络节点。而且CC2530 具有不同的运行模式,当无信号时,可以进入睡眠状态; 当有信号时,可以快速转换到工作模式,使得它尤其适用于超低功耗要求的系统。CC2530 加大了缓存,最大存储容量可达256 kbyte,使用时不用再为存储容量小而对代码进行限制; CC2530 的通信距离可达400 m,不再需要像CC2430 那样外加功放扩展传输距离。 代码从CC2430 移植到CC2530 只需少量修改,并且CC2530 支持最新的2007 /PRO( Professional) 协议栈,且价格较便宜。
2.1 终端节点的硬件设计
终端节点作为系统最底层的设备,起着至关重要的作用。终端节点是带传感器的网络子节点,以CC2530 作为核心。信息终端节点的硬件结构框图如图2 所示。终端节点的功能模块包括: 传感器模块、 电源管理模块、 报警模块和继电器模块。
图2-1 终端节点硬件结构图
传感器模块是监测节点重要组成部分负责完成室内相关数据的采集。信息终端节点根据它所安放的位置和监测数据类型的不同,一般安装不同的传感器。为了减少对CPU 资源的占用,一般采用数字化传感器,数字化传感器可方便传感器模块接口的设计。报警模块用于当监测数据出现异常时给予报警提醒。终端节点将采集到的甲醛浓度信号、 烟雾信号、 煤气信号和温度信号等经过微控制器处理后,经路由节点传送到监控中心。继电器模块通过CC2530 输出的高低电平作为驱动电路的控制信号,通过驱动电路控制继电器中电磁线圈吸合与断开,从而控制风扇、 空调和窗户等设备外电路的闭合与开路。其驱动电路如图3 所示。
图2-2 继电器驱动电路
2.2 监控中心硬件设计
监控中心由中央处理单元、 液晶显示模块、 协调器模块、 报警模块、GPRS 模块组成,硬件结构框图如图4 所示。中央处理单元采用三星公司推出的微处理器S3C2440A,S3C2440A 核心处理器( CPU) 是ARM920T 的RISC 处理器,具有低价格、 低功耗、 高性能的特点,并且提供一种完整的通用系统外设,减少整体系统成本。GPRS 无线模块采用西门子公司最新推出的MC37i,MC37i 性能稳定、 体积小、 重量轻、 功耗低,具备快速GPRS 技术,参数设置严谨,并提供了2 个独立串口,支持GPRS 数据通讯与AT 指令并行操作; 并且永久在线连接、 快速数据存储和更快的数据下载速度。协调器节点采用与终端节点相同的芯片CC2530。协调器节点其实就是一个功能更强的信息终端节点,它的处理能力和通信能力更强,信息存储量大等,主要作用是启动控制命令的发送、 接纳终端节点加入、 转发信息终端节点数据至监控中心等。
图2-3 监控中心硬件结构框图
第三章 系统软件设计
基于通用性和便于开发的考虑,节点的软件设计移植了TI 公司的Z-Stack 协议栈,Z-Stack 协议栈符台Zig Bee2006 规范,功能强大,它包含了Zig Bee 标准描述的各层次的功能组件模块,向开发人员提供了一系列的API 接口,通过调用API 可实现Zig Bee 标准中各层次的相应功能。
3.1 终端节点软件设计
因为节点在不同的工作模式下的功耗差别非常大,将体眠、 唤醒、 工作等这些不同的工作模式有机的组合起来,使其既能有效地完成任务,又能最大限度地减少能耗。所以,在这里采用了周期性监测工作方式,其工作过程为:先设定一个监测周期,监测周期之外的时间,各个节点进入睡眠状态; 到达检测周期后,各个节点被唤醒,等待协调器节点收集数据; 当协调器发出数据采集命令后,各个终端节点进行数据采集,并将数据信息传送给协调器节点。另外,终端节点本身带有报警模块,可以脱离监控中心,作为一个独立功能设备使用。终端节点的程序流程图如图5 所示。
图3-1 终端节点程序流程图
3.2 监控中心软件设计
控制中心软件设计主要包括两方面内容: 一方面负责组建网络; 另一方面将协调器节点采集的数据传送到S3C2440A。当S3C2440A 接收到数据后进行处理,并且判断数据是否超过警戒线,如果超过警戒线蜂鸣器就报警,同时把报警信息通过GPRS 模块以短信的形式发送到住宅的主人手机中,以便及时处理,并将各个房间的监测信息在液晶显示器上进行循环显示。监控中心程序流程图如图6 所示
图3-2 监控中心控制流程图
3.3 GPRS 模块软件设计
本设计采用SMS 短信方式实现室内出现火灾和煤气泄漏灾害的及时报警。S3C2440A 接收CC2530 外部采集的数据,然后通过串口发送给GPRS 模块,最终,
GPRS 模块把数据转发到主人手机中。GPRS 模块建立无线通道进行数据传输主要是靠AT 命令控制完成的。
第四章 系统测试
在卧室和厨房内分别布置3 个终端节点,对房间的温度、 烟雾监测,路由节点布置在卧室和厨房的门口,将监控中心布置在客厅,对监测的数据进行分析和处理。温度传感器采用防水型DS18B20、 烟雾传感器采用NIS-09C。将6 个终端节点的温度传感器放入0~ 50 ℃ 水中进行模拟,将该系统的测量值与标准温度计测得的温度值进行对比,测试结果如表1 所示。传感器所测的温度值与温度计所测的温度值并不完全相等,存在一定的误差,相差约为0. 3 ℃ ,但误差范围比较小,可以接受。测试烟雾浓度是通过在一个敞口的铁桶中燃烧一些东西,然后把烟雾传感器放到桶口,当烟雾的浓度较大时,蜂鸣器会报警,同时主人的手机中收到报警信息。
表4-1 室内温度测试结果
第五章 结论
本文采用物联网技术和GPRS 无线远程传输技术,构造了一种家居室内环境参数远程监测系统。实现了对室内的甲醛、CO、 烟雾和温度等数据实时采集和处理,如有异常情况出现时,蜂鸣器会报警,并将报警信息发送到主人手机中,以便及时采取措施。实验测试表明: 该系统灵敏度高、 运行稳定、 实时性强,而且成本低、 功耗小和易于扩展。通过本次课程设计,我进一步深入的学习了物联网技术和无线远程传输技术,并且掌握了如何将物联网技术应用到我们的实际生活当中,同时也意识到物联网技术的强大以及对我们现代生活和未来世界的无可取代的作用。
参考文献
[1]王春雷,黄玉,柴乔林,等. 基于无线传感器网络的火灾监控系统设计与实现[J]. 计算机工程与设计,2007,28 ( 7) :2320 - 2322.
[2]李忠成. 基于无线传感器网络的环境监测系统研究与设计[J]. 计算机测量与控制,2008,16( 7) : 929 - 931.
[3]晏均,周群彪,谢晓阳. 基于无线传感器网络的室内火灾系统[J]. 中国民航飞行学院学报,2009,20( 2) : 45 - 47.
[4]李宗醒,闰超,丁建宁,等. 基于Super-Zig Bee 的高大建筑物台风监测系统[J]. 仪表技术与传感器,2011( 10) : 44 - 45.
[5]张登宏. 煤矿安全检测系统的物联网技术研究[J]. 煤炭技术,2011,30( 12) : 95 - 97.
[6]鲜晓东,常超,胡颖,等. 基于WSNs 和GSM 的室内环境监测预警系统设计[J]. 传感器与微系统,2011,30( 6) : 141 -144.
第二篇:物联网课程设计—基于温湿度传感器物联网应用实时数据处理系统开发
网络工程(物联网技术)
课程设计报告
题 目:基于温湿度传感器物联网应用实时数据处理系统开发
院(系) 别: 数学与信息工程学院
专业: 网络工程(物联网技术) 班级 1 班
学 号: 2006099914
姓 名: 小明
指导教师: 职称 博士
填表日期: 2012 年 5 月 11 日
前 言
一、选题的依据及意义
1. 依据
物联网是一种新概念和新技术,它使新一代IT技术更加充分地应用于各行各业之中。它的问世打破了过去将基础设施与IT设施分开的传统观念,将建筑物、公路、铁路和网站、网络、数据中心合为一体,是信息化和工业化融合的重要切入点。温湿度与人们的生活关系密切,所以物联网在温湿度实时数据处理系统的开发将有很大的前景。
2. 意义
在我们的日常生活中无处不在,控制好温湿度可以使我们生活、生产的更好。温湿度传感器物联网应用实时数据处理系统开发可以帮我们实现对温湿度以实时数据让我们明了的知道。从而更好的控制温湿度、达到我们所需的标准。
二、本课程设计内容简介
1. 通过ubuntu连接传感器实验箱收集由传感器测得的实时数据存入sqlite3数据库。
2. 然后通过ubuntu发送到linux、接收并用动态网页显示代表数据变化的曲线。
三、要达到的目标
1.可以在ubuntu上实现自动接收由传感器取得、传来的实时数据。
2. 并ubuntu上能边接收边连续往linux发送从传感器取得的实时数据。
3.还要确保发送过的数据不会再次发送。
4. Linux能接收到ubuntu发过来的实时数据并通过动态网页曲线图实时显示接收过来的数据。
实现方案
一、开发环境
1.硬件(详细介绍所涉及硬件的详细内容)
Pc机、温湿度传感器、传感器实验箱、连接所需的各种线。
2.软件(详细介绍所涉及软件的详细内容)
MDK414(arm平台编译烧录代码软件)、KeilC51v750a_Full(C51平台编译软件)、STC手动下载(C51烧录代码软件)、R340(串口线连接USB驱动)、ubuntu操作系统、linux操作系统。
3.其它
二、开发内容
1.项目开发详细内容(包括传感器的配置、传感器烧录、数据的实时收集、实时数据的存储、实时数据的传输、实时数据在服务器端的接受及存储-TCPServer及MySql、数据库及Web服务器安装、利用JSP曲线动态显示实时数据)
首先烧录整合好的温湿度传感器的代码。接着连接传感器取得数据。然后在ubuntu中编译并运行Com_Sensor程序获取传感器实验箱的数据。
在Ubuntu11编译并运行senddata.c把数据发送到linux.Linux通过TCPServer服务器接收数据并存入MySQL数据库。
最后将接收到的数据通过Linuxweb服务器以jsp曲线动态显示实时数据。
2.网络拓扑图(包括传感器、网关、传输网络、TCPServer服务器、数据库服务器、静态及动态Web服务器、Web服务器客户端;并详细标注设备名称及IP地址等详细信息;并详细叙述网络拓扑图流程)
三、技术路线
1. 传感器数据处理(给出详细的传感器烧录代码 )
代码如下:
/*********************************************************/
//中软吉大信息技术有限公司
//物联网传感技术教学实验系统
/*********************************************************/
#include <intrins.h> //Keil library (is used for _nop()_ operation)
#include <math.h> //Keil library
#include"Lcmdisplay.h"
#define FOSC 11059200
#define BAUD 14400
typedef union
{ unsigned int i;
float f;
} value;
//----------------------------------------------------------------------------------
// modul-var
//----------------------------------------------------------------------------------
enum {TEMP,HUMI};
#define noACK 0
#define ACK 1
//adr command r/w
#define STATUS_REG_W 0x06 //000 0011 0
#define STATUS_REG_R 0x07 //000 0011 1
#define MEASURE_TEMP 0x03 //000 0001 1
#define MEASURE_HUMI 0x05 //000 0010 1
#define RESET 0x1e //000 1111 0
sbit DATA=P2^2;
sbit SCK=P2^1;
sbit POWER=P2^5;
sbit flag1=P0^7;
sbit flag2=P4^6;
sbit flag3=P2^7;
sbit flag4=P2^6;
void delay(unsigned int nTimeDelay)
{
unsigned int i;
while (nTimeDelay--)
for (i=0;i<125;i++);
}
void Serial_Init()
{
TMOD = 0x01;
TR0 = 1;
EA = 1;
ET0 = 0;
TF0 = 0;
S2CON = 0x50; //8位可变波特率 (无校验位)
BRT = -(FOSC/32/BAUD); //设置独立波特率发生器的重载初值
AUXR = 0x14; //独立波特率发生器工作在1T模式
//IE2 = 0x01; //使能串口2中断
}
void IO_Init(void)
{
P2M1=P2M1&0xdf;
P2M0=P2M0&0xdf;
P0M1=P0M1&0x7f;
P0M0=P0M0&0x7f;
P4M1=P4M1&0xbf;
P4M0=P4M0&0xbf;
P2M1=P2M1&0x3f;
P2M0=P2M0&0x3f;
P4SW=P4SW|0x40;
}
void Power_Identify(void)
{
while(1)
{
if(POWER==0)
{
delay(4000);
LcmPrintf("请给传感器模块上电!\n");
}
else break;
}
}
void Module_Identify(unsigned int xuhao)
{
unsigned int abc=0;
if(flag4==1)abc=abc+1;
abc=abc<<1;
if(flag3==1)abc=abc+1;
abc=abc<<1;
if(flag2==1)abc=abc+1;
abc=abc<<1;
if(flag1==1)abc=abc+1;
if(abc!=xuhao)
{
delay(3000);
LcmPrintf("提示:您插入的模块不正确!\n");
}
while(1)
{
if(abc!=xuhao);
else
{
delay(2000);
LcmPrintf("连接的模块是M%u\n",xuhao);
delay(5000);
break;
}
}
}
//----------------------------------------------------------------------------------
char s_write_byte(unsigned char value)
//----------------------------------------------------------------------------------
// writes a byte on the Sensibus and checks the acknowledge
{
unsigned char i,error=0;
for (i=0x80;i>0;i/=2) //shift bit for masking
{ if (i & value)
DATA=1; //masking value with i , write to SENSI-BUS
else DATA=0;
_nop_(); //observe setup time
SCK=1; //clk for SENSI-BUS
_nop_();_nop_();_nop_(); //pulswith approx. 5 us
SCK=0;
_nop_(); //observe hold time
}
DATA=1; //release DATA-line
_nop_(); //observe setup time
SCK=1; //clk #9 for ack
error=DATA; //check ack (DATA will be pulled down by SHT11)
SCK=0;
return error; //error=1 in case of no acknowledge
}
//----------------------------------------------------------------------------------
char s_read_byte(unsigned char ack)
//----------------------------------------------------------------------------------
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
unsigned char i,val=0;
DATA=1; //release DATA-line
for (i=0x80;i>0;i/=2) //shift bit for masking
{ SCK=1; //clk for SENSI-BUS
if (DATA) val=(val | i); //read bit
SCK=0;
}
DATA=!ack; //in case of "ack==1" pull down DATA-Line
_nop_(); //observe setup time
SCK=1; //clk #9 for ack
_nop_();_nop_();_nop_(); //pulswith approx. 5 us
SCK=0;
_nop_(); //observe hold time
DATA=1; //release DATA-line
return val;
}
//----------------------------------------------------------------------------------
void s_transstart(void)
//----------------------------------------------------------------------------------
// generates a transmission start
// _____ ________
// DATA: |_______|
// ___ ___
// SCK : ___| |___| |______
{
DATA=1; SCK=0; //Initial state
_nop_();
SCK=1;
_nop_();
DATA=0;
_nop_();
SCK=0;
_nop_();_nop_();_nop_();
SCK=1;
_nop_();
DATA=1;
_nop_();
SCK=0;
}
//----------------------------------------------------------------------------------
void s_connectionreset(void)
//----------------------------------------------------------------------------------
// communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
// _____________________________________________________ ________
// DATA: |_______|
// _ _ _ _ _ _ _ _ _ ___ ___
// SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
{
unsigned char i;
DATA=1; SCK=0; //Initial state
for(i=0;i<9;i++) //9 SCK cycles
{ SCK=1;
SCK=0;
}
s_transstart(); //transmission start
}
//----------------------------------------------------------------------------------
char s_softreset(void)
//----------------------------------------------------------------------------------
// resets the sensor by a softreset
{
unsigned char error=0;
s_connectionreset(); //reset communication
error+=s_write_byte(RESET); //send RESET-command to sensor
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
//----------------------------------------------------------------------------------
// reads the status register with checksum (8-bit)
{
unsigned char error=0;
s_transstart(); //transmission start
error=s_write_byte(STATUS_REG_R); //send command to sensor
*p_value=s_read_byte(ACK); //read status register (8-bit)
*p_checksum=s_read_byte(noACK); //read checksum (8-bit)
return error; //error=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_write_statusreg(unsigned char *p_value)
//----------------------------------------------------------------------------------
// writes the status register with checksum (8-bit)
{
unsigned char error=0;
s_transstart(); //transmission start
error+=s_write_byte(STATUS_REG_W);//send command to sensor
error+=s_write_byte(*p_value); //send value of status register
return error; //error>=1 in case of no response form the sensor
}
//----------------------------------------------------------------------------------
char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char
mode)
//----------------------------------------------------------------------------------
// makes a measurement (humidity/temperature) with checksum
{
unsigned char error=0;
unsigned int i;
s_transstart(); //transmission start
switch(mode){ //send command to sensor
case TEMP : error+=s_write_byte(MEASURE_TEMP); break;
case HUMI : error+=s_write_byte(MEASURE_HUMI); break;
default : break;
}
for (i=0;i<65535;i++) if(DATA==0) break; //wait until sensor has finished the measurement
if(DATA) error+=1; // or timeout (~2 sec.) is reached
*(p_value) =s_read_byte(ACK); //read the first byte (MSB)
*(p_value+1)=s_read_byte(ACK); //read the second byte (LSB)
*p_checksum =s_read_byte(noACK); //read checksum
return error;
}
//----------------------------------------------------------------------------------
void calc_sth11(float *p_humidity ,float *p_temperature)
//----------------------------------------------------------------------------------
// calculates temperature [°C] and humidity [%RH]
// input : humi [Ticks] (12 bit)
// temp [Ticks] (14 bit)
// output: humi [%RH]
// temp [°C]
{ const float C1=-2.0468; // for 12 Bit RH
const float C2=+0.0367; // for 12 Bit RH
const float C3=-0.0000015955; // for 12 Bit RH
const float T1=+0.01; // for 12 Bit RH
const float T2=+0.00008; // for 12 Bit RH
float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
float rh_lin; // rh_lin: Humidity linear
float rh_true; // rh_true: Temperature compensated humidity
float t_C; // t_C : Temperature [°C]
t_C=t*0.01 - 40.1; //calc. temperature[°C]from 14 bit temp.ticks @5V
rh_lin=C3*rh*rh + C2*rh + C1; //calc. humidity from ticks to [%RH]
rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. temperature compensated humidity [%RH]
if(rh_true>100)rh_true=100; //cut if the value is outside of
if(rh_true<0.1)rh_true=0.1; //the physical possible range
*p_temperature=t_C; //return temperature [°C]
*p_humidity=rh_true; //return humidity[%RH]
}
//--------------------------------------------------------------------
float calc_dewpoint(float h,float t)
//--------------------------------------------------------------------
// calculates dew point
// input: humidity [%RH], temperature [°C]
// output: dew point [°C]
{ float k,dew_point ;
k = (log10(h)-2)/0.4343 + (17.62*t)/(243.12+t);
dew_point = 243.12*k/(17.62-k);
return dew_point;
}
//----------------------------------------------------------------------------------
void main()
//----------------------------------------------------------------------------------
// sample program that shows how to use SHT11 functions
// 1. connection reset
// 2. measure humidity [ticks](12 bit) and temperature [ticks](14 bit)
// 3. calculate humidity [%RH] and temperature [°C]
// 4. calculate dew point [°C]
// 5. print temperature, humidity, dew point
{ value humi_val,temp_val;
float dew_point;
unsigned char error,checksum;
unsigned int i;
Serial_Init();
IO_Init();
Power_Identify();
Module_Identify(3);
s_connectionreset();
while(1)
{ error=0;
error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI); //measure humidity
error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP); //measure temperature
if(error!=0) s_connectionreset(); //in case of an error: connection reset
else
{ humi_val.f=(float)humi_val.i; //converts integer to float
temp_val.f=(float)temp_val.i; //converts integer to float
calc_sth11(&humi_val.f,&temp_val.f); //calculate humidity, temperature
dew_point=calc_dewpoint(humi_val.f,temp_val.f); //calculate dew point
Power_Identify();
LcmDisplaySHT10(humi_val.f,temp_val.f);
//LcmPrintf("温度:%5.1f℃ 湿度:%5.1f 露点:%3.1f\n", temp_val.f,humi_val.f,dew_point); //temp :温度
// for (i=0;i<40000;i++); //延迟
// LcmPrintf("", humi_val.f); //humi:湿度
// for (i=0;i<40000;i++); //延迟
// LcmPrintf("", dew_point); //dewpoint:露点(点在此温度时,空气饱和并产生露珠)
}
//----------wait approx. 0.8s to avoid heating up SHTxx-----------------------------
for (i=0;i<50000;i++); //(be sure that the compiler doesn't eliminate this line!)
//----------------------------------------------------------------------------------
}
}
Lcmdisplay.c:
#include "Lcmdisplay.h"
typedef enum {
LCMPRTF = 0, // 字符串打印
// 1 磁感应及环境光传感器模块
LCMHALL, // 霍尔接近开关
LCMREED, // 干簧管
LCMMETAL, // 金属接近开关
LCMLUX, // 环境光强度
LCMLDR, // 光敏电阻
// 2 震动及mems麦克传感器模块
LCMSHOCKDS, // 双珠单向
LCMSHOCKDD, // 双珠双向
LCMSHOCKSPRING, // 弹簧
LCMSHOCK, // 全向震动
LCMMIC, // MEMS麦克风
// 3 测距测障类及温湿度类传感器模块
LCMIR, // 红外对管测距
LCMIRSWITCH, // 红外接近开关
LCMULTR, // 超声波测距
LCMTEMP, // 温度// DS18b20
LCMSHT10, // 温湿度传感器SHT10
LCMHUMI, // 湿度//SHT10
LCMNTC, // 热敏电阻
// 4 操作控制类及加速传感器模块
LCMACC, // 三轴加速度
LCMJOYSTICK, // 摇杆电位器
LCMENCODER, // 编码开关
// 5 称重传感器模块
LCMWEIGHT, // 称重
// 6 粉尘传感器模块
LCMDUST, // 粉尘
// 7 红外测温及颜色传感器模块(增强型模块)
LCMBODYTEMP, // 红外测体温
LCMCOLOR, // 颜色
// 8 磁阻陀螺仪及气压传感器模块(增强型模块)
LCMRELUCTANCE, // 三轴磁阻
LCMANGRATE, // 三轴角速率陀螺仪
LCMPRESSURE, // 气压
// 9 二氧化碳传传感器模块(扩展型模块)
LCMCO2, // 二氧化碳
// 10 气体流量传感器模块(扩展型模块)
LCMFLOW, // 气体流量
LCMINIT // 初始值
} flag_t;
void swap(char *cp)
{
unsigned char temp;
temp=cp[3];
cp[3]=cp[0];
cp[0]=temp;
temp=cp[2];
cp[2]=cp[1];
cp[1]=temp;
}
void sendc (unsigned char chr)//发送一个字符
{
S2BUF = chr;
while(!(S2CON & 0x02));
S2CON &= ~0x02;
}
unsigned char recvc (void)
{
unsigned char chr;
while(!(S2CON & 0x01));
S2CON &= ~0x01;
chr = S2BUF;
return chr;
}
static void packetLcm(flag_t flag, char *data1, int length)
{
sendc(0x7e);
sendc(0xff);
sendc(0x06);//改成6
sendc(flag);
while(length--) {
switch (*data1) {
case 0x7e:
sendc(0x7d);
sendc(0x5e);
case 0x7d:
sendc(0x7d);
sendc(0x5e);
default:
sendc(*data1);
}
data1++;
}
sendc(0x00);
sendc(0x00);
sendc(0x7e);
// 等待显示完成
//recvc();
}
// 字符串打印到液晶
void LcmPrintf(char *fmt, ...)
{
va_list ap;
va_start(ap,fmt);
vsprintf(data1, fmt, ap);
va_end(ap);
packetLcm(LCMPRTF, data1, strlen(data1));
}
// 1 磁感应及环境光传感器模块
//LCMHALL, // 霍尔接近开关
// 霍尔传感器,有磁铁靠近TRUE,离开FALSE
void LcmDisplayHall(bool v)
{
conv_t conv;
conv.b = v;
swap(conv.c);
packetLcm(LCMHALL, conv.c, 4);
}
//LCMREED, // 干簧管
// 干簧管,有磁铁靠近TRUE,离开FALSE
void LcmDisplayReed(bool v)
{
conv_t conv;
conv.b = v;
swap(conv.c);
packetLcm(LCMREED, conv.c, 4);
}
//LCMMETAL, // 金属接近开关
// 金属传感器,有金属靠近TRUE,离开FALSE
void LcmDisplayMetal(bool v)
{
conv_t conv;
conv.b = v;
swap(conv.c);
packetLcm(LCMMETAL, conv.c, 4);
}
//LCMLUX, // 环境光强度
// 环境光强度,Lux
void LcmDisplayLux(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMLUX, conv.c, 4);
}
//LCMLDR, // 光敏电阻
// 光敏电阻,千欧
void LcmDisplayLDR(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMLDR, conv.c, 4);
}
// 2 震动及mems麦克传感器模块
//LCMSHOCKDS, // 双珠单向
void LcmDisplayShockDS(bool v)
{
conv_t conv;
conv.b = v;
packetLcm(LCMSHOCKDS, conv.c, sizeof(v));
}
//LCMSHOCKDD, // 双珠双向
void LcmDisplayShockDD(bool vl, bool vr)
{
conv_t conv;
if (vl && vr) {
conv.uc = 0xff;
} else if (vl && !vr) {
conv.uc = 0xf0;
} else if (!vl && vr) {
conv.uc = 0x0f;
} else {
conv.uc = 0x00;
}
packetLcm(LCMSHOCKDD, conv.c, sizeof(unsigned char));
}
//LCMSHOCKSPRING, // 弹簧
void LcmDisplayShockSpring(bool v)
{
conv_t conv;
conv.b = v;
packetLcm(LCMSHOCKSPRING, conv.c, sizeof(v));
}
//LCMSHOCK, // 全向震动
// 全向震动
void LcmDisplayShock(bool v)
{
conv_t conv;
conv.b = v;
packetLcm(LCMSHOCK, conv.c, sizeof(v));
}
//LCMMIC, // MEMS麦克风
void LcmDisplayMIC(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMMIC, conv.c, 4);
}
// 3 测距测障类及温湿度类传感器模块
//LCMIR, // 红外对管
// 红外对管电压,单位V
void LcmDisplayIR(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMIR, conv.c, 4);
}
//LCMIRSWITCH, // 红外接近开关
void LcmDisplayIRSwitch(bool v)
{
conv_t conv;
conv.b = v;
packetLcm(LCMIRSWITCH, conv.c, sizeof(v));
}
//LCMULTR, // 超声波测距
// 超声波测距,单位厘米
void LcmDisplayUltr(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMULTR, conv.c, 4);
}
//LCMTEMP, // 温度// DS18b20
// 温度,摄氏度
void LcmDisplayTemp(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMTEMP, conv.c, 4);
}
//LCMSHT10, // 温湿度传感器SHT10
// 温湿度传感器SHT10
// 参数 t:温度
// h:湿度
void LcmDisplaySHT10(float t, float h)
{
conv_t conv;
conv.f = t;
swap(conv.c);
memcpy(data1+0, conv.c, 4);
conv.f = h;
swap(conv.c);
memcpy(data1+4, conv.c, 4);
packetLcm(LCMSHT10, data1, 8);
}
//LCMHUMI, // 湿度//SHT10
// 相对湿度,百分比
void LcmDisplayHumi(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMHUMI, conv.c, 4);
}
//LCMNTC, // 热敏电阻
void LcmDisplayNTC(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMNTC, conv.c, 4);
}
// 4 操作控制类及加速传感器模块
//LCMACC, // 三轴加速度
// 三维加速度,单位g
void LcmDisplayAcc(float x, float y, float z)
{
conv_t conv;
conv.f = x;
swap(conv.c);
memcpy(data1+0, conv.c, 4);
conv.f = y;
swap(conv.c);
memcpy(data1+4, conv.c, 4);
conv.f = z;
swap(conv.c);
memcpy(data1+8, conv.c, 4);
packetLcm(LCMACC, data1, 12);
}
//LCMJOYSTICK, // 摇杆电位器
// 摇杆电位器,12位AD值
void LcmDisplayJoystick(unsigned int x, unsigned int y)
{
conv_t conv;
conv.ui = x;
swap(conv.c);
memcpy(data1+0, conv.c, 4);
conv.ui = y;
swap(conv.c);
memcpy(data1+4, conv.c, 4);
packetLcm(LCMJOYSTICK, data1, 8);
}
//LCMENCODER, // 编码开关
// 编码开关
void LcmDisplayEncoder(encd_t v)
{
conv_t conv;
conv.en = v;
swap(conv.c);
memcpy(data1+0, conv.c, 4);
packetLcm(LCMENCODER, data1, 4);
}
// 5 称重传感器模块
//LCMWEIGHT, // 称重
// 称重传感器,单位克
void LcmDisplayWeight(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMWEIGHT, conv.c, 4);
}
// 6 粉尘传感器模块
//LCMDUST, // 粉尘
// 粉尘,单位粒子数
void LcmDisplayDust(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMDUST, conv.c, 4);
}
// 7 红外测温及颜色传感器模块(增强型模块)
//LCMBODYTEMP, // 红外测体温
// 体温,摄氏度
void LcmDisplayBodyTemp(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMBODYTEMP, conv.c, 4);
}
//LCMCOLOR, // 颜色
// 颜色,RGB 各8位
void LcmDisplayColor(unsigned char r, unsigned char g, unsigned char b)
{
conv_t conv;
conv.uc = r;
memcpy(data1+0, conv.c, 1);
conv.uc = g;
memcpy(data1+1, conv.c, 1);
conv.uc = b;
memcpy(data1+2, conv.c, 1);
packetLcm(LCMCOLOR, data1, 3);
}
// 8 磁阻陀螺仪及气压传感器模块(增强型模块)
//LCMRELUCTANCE, // 三轴磁阻
// 磁阻
void LcmDisplayReluctance(float angle, float x, float y, float z)
{
conv_t conv;
conv.f = angle;
swap(conv.c);
memcpy(data1+0, conv.c, 4);
conv.f = x;
swap(conv.c);
memcpy(data1+4, conv.c, 4);
conv.f = y;
swap(conv.c);
memcpy(data1+8, conv.c, 4);
conv.f = z;
swap(conv.c);
memcpy(data1+12, conv.c, 4);
packetLcm(LCMRELUCTANCE, data1, 16);
}
//LCMANGRATE, // 三轴角速率陀螺仪
// 三轴角速率
void LcmDisplayAngRate(float x, float y, float z)
{
conv_t conv;
conv.f = x;
swap(conv.c);
memcpy(data1+0, conv.c, 4);
conv.f = y;
swap(conv.c);
memcpy(data1+4, conv.c, 4);
conv.f = z;
swap(conv.c);
memcpy(data1+8, conv.c, 4);
packetLcm(LCMANGRATE, data1, 12);
}
//LCMPRESSURE, // 气压
// 气压传感器MS5607
// 参数 P:温度
// t:气压
void LcmDisplayPressure(float p, float t)
{
conv_t conv;
conv.f = p;
swap(conv.c);
memcpy(data1+0, conv.c, 4);
conv.f = t;
swap(conv.c);
memcpy(data1+4, conv.c, 4);
packetLcm(LCMPRESSURE, data1, 8);
}
// 9 二氧化碳传传感器模块(扩展型模块)
//LCMCO2, // 二氧化碳
void LcmDisplayCO2(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMCO2, conv.c, 4);
}
// 10 气体流量传感器模块(扩展型模块)
//LCMFLOW, // 气体流量
// 气体流量,单位SLPM
void LcmDisplayFlow(float v)
{
conv_t conv;
conv.f = v;
swap(conv.c);
packetLcm(LCMFLOW, conv.c, 4);
}
2. 传感器烧录(给出传感器烧录代码的编译及烧录过程、是否遇到问题及如何解决)
(1)利用keil2软件,打开目录“D:\传感器实验箱资料\传感器实验箱程序资料\C51\完成部分程序\完成部分程序”中的SHT10.Uv2文件。
(2) 双击打开左侧的“wenshi.c”文件,根据提示完成部分程序。
(3) 按下F7键,即编译此程序,在工具软件下面的显示区域中,如果有“0 error(s)”字样,表示此程序编译已经成功。
(4) 把编译好的程序重新烧写到单片机中。
(5) 按下母板卡上的Sensors键并打开传感器电源。
(6) 观察效果。
(7) 依次关闭传感器电源、单片机电源、母板卡电源。
3. 实时数据收集环境(画出详细的传感器、C51或ARM板、传感器实验箱嵌入式电脑及Ubuntu网关间的连接示意图,并详细介绍各部分的主要功能)
温湿度传感器:检测环境的温湿度。
C51平台:通过平台里面烧录的代码对传感器取得的数据进行解析并转换为数值。
显示器:显示测的的温湿度的具体数值。
Sqlite3数据库:存储温湿度的数值。
4. 实时数据收集编程实现(给出从传感器实验箱获取实时数据的所有源代码,给出启动程序收集数据的步骤、遇到的问题及采取的措施)
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <stdlib.h>
#include <pthread.h>
//#include "Analysis_Net.h"
#include "Analysis_Sensor.h"
#include<sqlite3.h>
typedef struct
{
int fd;
} PAR;
void thread_com( void * param )
{
PAR * local = param;
char buff[1024];
//sqlite3
int retval;
sqlite3 *handle;
retval = sqlite3_open("Seninfo.db",&handle);
if(retval)
{
printf("Database connection failed\n");
return -1;
}
printf("Connection successful\n");
printf("Connection successful\n");
char *sql;
sql = "CREATE TABLE IF NOT EXISTS Sdata (id int,datetime datetime ,Temperature float,Humidity float,flag int default 0)";
sqlite3_exec(handle,sql,0,0,0);
//sqlite3
while ( 1 )
{
memset( buff, 0, sizeof( buff ) );
int nread = read( local->fd, buff, 1024 );
printf( "size of nread = %d\n", nread );
if ( nread != 0 )
{
// GetNWData( &buff );
GetSData( &buff,handle );
}
sleep( 2 );
}
sqlite3_close(handle);
}
int set_opt( int fd, int nSpeed, int nBits, char nEvent, int nStop ) //设置打开的端口
{
struct termios newtio;
struct termios oldtio;
if ( tcgetattr( fd, &oldtio ) != 0 )
{
perror( "Save Old Serial" );
return -1;
}
bzero( &newtio, sizeof( newtio ) );
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
switch ( nBits )
{
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
default:
break;
}
switch ( nEvent )
{
case 'O':
case 'o':
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARENB;
break;
case 'e':
case 'E':
newtio.c_iflag |= ( INPCK | ISTRIP );
newtio.c_cflag |= PARENB;
newtio.c_cflag &= ~PARODD;
break;
case 'n':
case 'N':
newtio.c_cflag &= ~PARENB;
break;
}
switch ( nSpeed )
{
case 2400:
cfsetispeed( &newtio, B2400 );
cfsetospeed( &newtio, B2400 );
break;
case 4800:
cfsetispeed( &newtio, B4800 );
cfsetospeed( &newtio, B4800 );
break;
case 9600:
cfsetispeed( &newtio, B9600 );
cfsetospeed( &newtio, B9600 );
break;
case 115200:
cfsetispeed( &newtio, B115200 );
cfsetospeed( &newtio, B115200 );
break;
default:
cfsetispeed( &newtio, B9600 );
cfsetospeed( &newtio, B9600 );
break;
}
if ( nStop == 1 )
{
newtio.c_cflag &= ~CSTOPB;
}
else if ( nStop == 2 )
{
newtio.c_cflag |= CSTOPB;
}
newtio.c_cc[VMIN] = 0;
newtio.c_cc[VTIME] = 0;
tcflush( fd, TCIFLUSH );
if ( tcsetattr( fd, TCSANOW, &newtio ) != 0 )
{
perror( "com set error" );
return -1;
}
printf( "set done\n" );
}
void open_port( int * fd ) //打开端口
{
char num[100];
char COMNum[100] = "/dev/tty";
printf( "please input COM num:" );
gets( num );
strcat( COMNum, num );
*fd = open( COMNum, O_RDWR | O_NOCTTY | O_NDELAY );
if ( *fd == -1 )
{
perror( "Can not Open Serial Port" );
return( -1 );
}
else
{
printf( "Open Success\n" );
}
if ( fcntl( *fd, F_SETFL, 0 ) < 0 )
{
printf( "fcntl failed!\n" );
}
else
{
printf( "fcntl = %d\n", fcntl( *fd, F_SETFL, 0 ) );
}
printf( "fd-open = %d\n", *fd );
}
int main()
{
int fd;
int i;
char buff[100];
int quit = 0;
int res;
pthread_t id;
PAR param;
count=0;
memset( buff, 0, sizeof( buff ) );
open_port( &fd );
if ( fd < 0 )
{
perror( "open com error" );
return -1;
}
i = set_opt( fd, 115200, 8, 'N', 1 );
if ( i < 0 )
{
perror( "set opt error" );
return -1;
}
param.fd = fd;
res = pthread_create( &id, NULL, thread_com, (void *)¶m );
while ( quit == 0 )
{
scanf( "%d", &quit );
fflush( stdin );
}
close( fd );
return 0;
}
1、输入指令"ls /dev/ | grep tty"。应该可以找到ttyUSB接口
2、./Com_Sensor出现please input COM num:接着输入USB接口号。
问题:对代码各个模块的具体用途不了解。
5. 实时数据存储(如何安装及使用Sqlite3,给出存储实时数据的Sqlite3数据表格的详细的数据列及数据类型)
安装步骤:
aptitude update
aptitude install libsqlite3-dev
aptitude install sqlite3
数据类型CREATE TABLE Sdata (id int,datetime datetime ,Temperature float,Humidity float,flag int default 0);
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id | int | NO | | | |
| dateTime | varchar(50) | NO | | | |
|Temperature | float | NO | | | |
| Humidity | float | NO | | | |
| flag | int(11) | YES | | 0 | |
+-------------+-------------+------+-----+---------+-------+
6. 实时数据发送(说明如何实现自动连续发送实时数据、说明如何保证已经成功发送的数据不能再次发送、给出实时数据发送的源代码;是否遇到问题及如何解决)
发送源代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include<sqlite3.h>
#define BUFSIZE 1024
/*
* error - wrapper for perror
*/
void error(char *msg) {
perror(msg);
exit(0);
}
char* MyStrcat(char *a,char *b)
{
int i=0;
char *p=a,*q=b,*c,*cc;
while(*p++)i++;
while(*q++)i++;
p=a;q=b;i++;
c=(char*)malloc(i*sizeof(char));
cc=c;
while(*p)*cc++=*p++;
while(*q)*cc++=*q++;
*cc=0;
return c;
}
int main(int argc, char **argv) {
int sockfd, portno, n;
struct sockaddr_in serveraddr;
struct hostent *server;
char *hostname;
char buf[BUFSIZE];
int retval,retval2;
int q_cnt = 5,q_size = 150,ind = 0;
char **queries = malloc(sizeof(char) * q_cnt * q_size);
sqlite3_stmt *stmt;
sqlite3 *handle;
char *d;
char sentstr[1024];
char whitespace[]="$";
char endofline[]="#";
char endofsentstr[]="\n";
char *sql;
if (argc != 3) {
fprintf(stderr,"usage: %s <hostname> <port>\n", argv[0]);
exit(0);
}
hostname = argv[1];
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(hostname);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host as %s\n", hostname);
exit(0);
}
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serveraddr.sin_addr.s_addr, server->h_length);
serveraddr.sin_port = htons(portno);
if (connect(sockfd, &serveraddr, sizeof(serveraddr)) < 0)
error("ERROR connecting");
retval = sqlite3_open("Seninfo.db",&handle);
if(retval)
{
printf("Database connection failed\n");
return -1;
}
printf("Connection successful\n");
queries[ind++] = "SELECT * from Sdata where flag ==0";
retval = sqlite3_prepare_v2(handle,queries[ind-1],-1,&stmt,0);
if(retval)
{
printf("Selecting data from DB Failed\n");
return -1;
}
int cols = sqlite3_column_count(stmt)-1;
printf("cols=%d\n",cols);
memset(sentstr,0,sizeof(sentstr));
while(1)
{
retval = sqlite3_step(stmt);
if(retval == SQLITE_ROW)
{
const char *val2 = (const char*)sqlite3_column_text(stmt,0);
sql = sqlite3_mprintf("update Sdata set flag=1 where id='%s'",val2);
sqlite3_exec(handle,sql,0,0,0);
for(int col=0 ; col<cols;col++)
{
const char *val = (const char*)sqlite3_column_text(stmt,col);
d=MyStrcat(sentstr,val);
strcpy(sentstr,d);
d=MyStrcat(sentstr,whitespace);
strcpy(sentstr,d);
printf("%s = %s\t",sqlite3_column_name(stmt,col),val);
}
d=MyStrcat(sentstr,endofline);
strcpy(sentstr,d);
printf("\n");
}
else if(retval == SQLITE_DONE)
{
printf("sentstr=%s",sentstr);
printf("All rows fetched\n");
}
else
{
printf("Some error encountered\n");
return -1;
}
d=MyStrcat(sentstr,endofsentstr);
strcpy(sentstr,d);
n = write(sockfd, sentstr, strlen(sentstr));
if (n < 0)
error("ERROR writing to socket");
printf("Waiting 5 seconds\n");
sleep(1);
bzero(sentstr, BUFSIZE);
n = read(sockfd, sentstr, BUFSIZE);
if (n < 0)
error("ERROR reading from socket");
printf("Echo from server: %s\n", sentstr);
memset(sentstr,0,sizeof(sentstr));
close(sockfd);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(hostname);
if (server == NULL)
{
fprintf(stderr,"ERROR, no such host as %s\n", hostname);
exit(0);
}
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serveraddr.sin_addr.s_addr, server->h_length);
serveraddr.sin_port = htons(portno);
if (connect(sockfd, &serveraddr, sizeof(serveraddr)) < 0)
error("ERROR connecting");
}
return 0;
}
将实时接收的数据标记为0,已经发送的数据标记为1,当数据检测到为1是时就拒绝发送。
这样就不会重复发送。
问题:对于如何保证已经成功发送的数据不能再次发送纠结了很久没有结果、后来请教了同学才解决了问题。
7. MySql服务器的安装(给出安装MySql数据库的详细步骤,是否遇到问题及如何解决)
cd /media
ls
cd RH 光驱
cd Server
rpm -ivh perl-DBI-1.52-1.fc6.i386.rpm
rpm -ivh perl-DBD-Pg-1.49-1.fc6.i386.rpm
rpm -ivh mysql-5.0.45-7.el5.i386.rpm
rpm -ivh perl-DBD-MySQL-3.0007-1.fc6.i386.rpm
rpm -ivh mysql-server-5.0.45-7.el5.i386.rpm
rpm -ivh libtool-ltdl-1.5.22-6.1.i386.rpm
rpm -ivh mysql-connector-odbc-3.51.12-2.2.i386.rpm
8. 静态及动态Web服务器的安装(给出安装及实现Apache2和Tomcat整合的详细步骤,是否遇到问题及如何解决)
步骤:
1、进入/tmp/目录下,解压tomcat-connectors-1.2.33-src.tar.gz
2、进入tomcat-connectors-1.2.33-src/native/目录下,执行命令buildconf.sh生成编译配置文件
3、执行命令./configure -with-apxs=/usr/local/apache2/bin/apxs
4、执行命令make,编译mod_jk模块
5、执行命令cp mod_jk.so /usr/local/apache2/modules/ 把模块文件复制到apache的modules目录下
6、打开http,conf配置文件添加如下内容
LoadModule jk_module modules/mod_jk.so
7、执行如下命令创建jsp和WEB-INFO目录
mkdir /usr/local/apache2/htdocs/jsp
mkdir /usr/local/apache2/htdocs/jsp/WEB-INFO
8、在 /usr/local/apache2/conf/目录下创建workers.properties,在文件添加以下内容
worker.list=worker1
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009
worker.worker1.lbfactor=50
worker.worker1.cache_timeout=600
worker.worker1.socket_keepalive=1
worker.worker1.socket_timeout=300
~9、在/usr/local/apache2/conf/目录下创建mod_jk.conf ,在这个文件添加以下内容
JkWorkersFile /usr/local/apache2/conf/workers.properties
JkLogFile /usr/local/apache2/logs/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkMount /servlet/* worker1
JkMount /*.jsp worker1
10、打开httpd.conf配置文件,对IfModule段修改如下内容
<IfModule dir_module>
DirectoryIndex index.html index.jsp
</IfModule>
在添加如下内容
<Directory "/usr/local/apache2/htdocs/jsp">
Options Indexes FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
# XBitHack on
</Directory>
<Directory "/usr/local/apache2/htdocs/jsp/WEB-INFO">
Order deny,allow
Deny from all
</Directory>
JkWorkersFile /usr/local/apache2/conf/workers.properties
JkLogFile /usr/local/apache2/logs/mod_jk.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkMount /servlet/* worker1
JkMount /*.jsp worker1
11、打开Tomcat的/usr/local/apache-tomcat-7.0.26/conf、server.xml在host段中加入如下内容
<Context path="" docBase="/usr/local/apache2/htdocs/jsp" debug="0"
reloadable="true" crossContext="true" />
12、重启Apache和Tomcat服务,同时创建文件index.jsp并放到/usr/local/apache2/htdocs/jsp目录下
Index.jsp的内容如下
<html>
<head>
<title> JSP 测试页面<title>
</head>
<body>
<%
String name=request.getParameter("name");
out.println("<h1> JSP 测试: Hello "+name+"!<br></h1>");
%>
</body>
问题:在整合Apache2和Tomcat时关键是文件的配置,有时会缺少文件代码打错而不能实现。
9. 数据服务中心TCP服务器接收实时数据(给出存储实时数据的MySql数据表格的详细的数据列及数据类型、给出接收及存储实时数据的TCPServer.java源代码;是否遇到问题及如何解决)
MySql数据表格的详细的数据列及数据类型:
+---------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+----------+------+-----+---------+-------+
| StId | int(11) | NO | | | |
| Stdatetime | char(50) | NO | | | |
| Sttemperature | char(50) | NO | | | |
| Sthumidity | char(50) | NO | | | |
+---------------+----------+------+-----+---------+-------+
TCPServer.java代码源:
import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.StringTokenizer;
class TCPServer
{
public static void main(String argv[]) throws Exception
{
int qq=-1,pp;
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket
(6789);
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://127.0.0.1:3306/test_db";
String user = "root";
String password = "123456";
while(true)
{
Socket connectionSocket = welcomeSocket.
accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(
connectionSocket.getInputStream()));
DataOutputStream outToClient =
new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
StringTokenizer st = new StringTokenizer(clientSentence,"#");
try {
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, user, password);
if(!conn.isClosed())
System.out.println("Succeeded connecting to the Database!");
Statement statement = conn.createStatement();
while (st.hasMoreTokens()) {
//System.out.println(st.nextToken());
StringTokenizer st1 = new StringTokenizer(st.nextToken(),"$");
while (st1.hasMoreTokens()) {
//System.out.println(st1.nextToken());
String StId=st1.nextToken();
String Stdatetime=st1.nextToken();
String Sttemperature=st1.nextToken();
String Sthumidity=st1.nextToken();
//String StSize=st1.nextToken();
// String StUsed=st1.nextToken();
System.out.println("StId="+StId);
System.out.println("Stdatetime="+Stdatetime);
System.out.println("Sttemperature="+Sttemperature);
System.out.println("Sthumidity="+Sthumidity);
//System.out.println("StSize="+StSize);
//System.out.println("StUsed="+StUsed);
pp=Integer.parseInt(StId);
if(qq<pp){
String sql = "INSERT INTO Sdata VALUES('"+StId+"','"+Stdatetime+"','"+Sttemperature+"','"+Sthumidity+"')";
qq=pp;
statement.executeUpdate(sql);
}
}
}
conn.close();
} catch(ClassNotFoundException e) {
System.out.println("Sorry,can`t find the Driver!");
e.printStackTrace();
} catch(SQLException e) {
e.printStackTrace();
} catch(Exception e) {
e.printStackTrace();
}
System.out.println(clientSentence);
capitalizedSentence =
clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}
10. 实时数据显示(给出实时以曲线形式显示MySql数据库中实时数据的JSP源代码及显示曲线截图)
JSP源代码:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page import = "java.sql.*" %>
<%@page import="java.util.Properties"%>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.awt.*" %>
<%@ page import="java.io.*" %>
<%@ page import="org.jfree.chart.*" %>
<%@ page import="org.jfree.chart.axis.*" %>
<%@ page import="org.jfree.chart.entity.*" %>
<%@ page import="org.jfree.chart.labels.*" %>
<%@ page import="org.jfree.chart.plot.*" %>
<%@ page import="org.jfree.chart.renderer.category.*" %>
<%@ page import="org.jfree.chart.urls.*" %>
<%@ page import="org.jfree.data.category.*" %>
<%@ page import="org.jfree.data.general.*" %>
<%@ page import="org.jfree.data.category.DefaultCategoryDataset" %>
<%@ page import="org.jfree.data.general.DefaultPieDataset" %>
<%@ page import="org.jfree.data.xy.*" %>
<%@ page import="org.jfree.data.*" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHHmmss");
XYSeries series = new XYSeries("Time Temperature");
try{
String databaseURL = "jdbc:mysql://localhost:3306/test_db";
Class.forName("com.mysql.jdbc.Driver");
Properties properties = new Properties();
properties.put("user", "root");
properties.put("password", "123456");
Connection conn = DriverManager.getConnection(databaseURL, properties);
Statement Stmt = conn.createStatement();
ResultSet RS = Stmt.executeQuery("SELECT * from Sdata");
while (RS.next()) {
//Date date = new Date(RS.getString(2););
String nowTime1 =RS.getString(2);
String nowTime2 = RS.getString(3);
try{
nowTime2 = sdf2.format(sdf1.parse(nowTime1));
}catch(Exception e){
e.printStackTrace();
}
//System.out.println(nowTime1);
String res;
res = nowTime2.substring(8, nowTime2.length());
series.add(Double.parseDouble(res), Double.parseDouble(RS.getString(3)));
}
RS.close();
}catch (ClassNotFoundException e) {
out.println("Couldn't load database driver: " + e.getMessage());
}catch (SQLException e) {}
XYDataset xyDataset = new XYSeriesCollection(series);
JFreeChart chart = ChartFactory.createXYLineChart
("XYLine Chart using JFreeChart", "Time/s", "Temperature/C",
xyDataset, PlotOrientation.VERTICAL, true, true, false);
try {
final ChartRenderingInfo info = new ChartRenderingInfo
(new StandardEntityCollection());
final File file1 = new File("/usr/local/apache2/htdocs/barchart.png");
ChartUtilities.saveChartAsPNG(file1, chart, 600, 400, info);
} catch (Exception e) {
out.println(e);
}
%>
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" >
<meta http-equiv="refresh" content="2">
<title>JSP Page</title>
</head>
<body>
<IMG SRC="barchart.png" WIDTH="600"
HEIGHT="400" BORDER="0" USEMAP="#chart">
</body>
</html>
课程设计小结
1. 阐述此课程设计过程的主要的难题及攻克难题的过程,以及整个开发过程给自己带来的收获。
在课程设计过程中主要问题是修改代码,特别是如何使发送过的数据不重复发送,能力有限只能请教同学,从而解决了代码问题。
通过开发过程中了解并接触了物联网开发的过程、简单的开发步骤。
2. 阐述此课程设计过程对自己动手实践能力的影响,对自己所学专业已有认识的影响,对自己将来学习、工作兴趣方向的影响。
通过开发过程我更加肯定了自己动手实践的重要性、了解并接触了物联网开发的过程、简单的开发步骤。
3. 阐述自己对此类课程设计的感想,包括课程设计的不足和改进之处。
课程设计不仅可以是我们进一步了解物联网的开发过程、增强和巩固了自己的专业知识、加强了自己的动手实践能力。在实践过程中发现自己的能力还远远不够,特别是修改代码方面比较吃力。
4. 其它有关课程、专业及课程设计的想法意见及建议。
可以让大家组队尝试实践开发较大、大家感兴趣的物联网项目。