您的位置:首页 > 其它

暑期实训第三课(数据采集终端的制作)

2014-08-03 10:21 253 查看
环境数据采集终端2

上一篇介绍了终端制作所需的各种传感器及其一些材料,那么现在开始正式数据采集终端的制作。

紫外线传感器

在制作过程中,紫外线传感器由于非常简单,所以是做得最快的一个,主要麻烦的是在编程方面,紫外线传感器会根据外界紫外线的强度输出一个电压值,通过arduino板子读取其引脚所输出的电压,在经过一定的换算即可得到想要的紫外线强度的值。我们用analogRead()函数读取其引脚的电压值。在这里需要注意的是,紫外线的级数,从紫外线传感器读取的电压值,还需要经过转换才能得到紫外线强度。

光照传感器

光照传感器较紫外线来说比较复杂,其有5个接口,在编程的时候还需要引入库文件才能正确的读出数据。

首先,在open jumper上下载光照传感器所需的库文件,解压后将其移动到arduino安装目录下的libraries文件夹下,这样,我们在编辑光照传感器时才能够调用到所需的库函数。

一切准备就绪,将传感器连接到Arduino UNO上。

光照的单位是“lux”,所以需要定义一个名为“lux”的整形变量来表示光照强度。

其所需头文件有两个,分别为“Wire.h”和“BH1750FVI.h”,使用时将其用

#include<Wire.h>

#include<BH1750FVI.h>

预处理命令引入函数即可。

引入库之后,我们需要创建一个对象如下

BH1750FVI LightSensor;

然后再setup()函数里面,初始化,相关程序如下:

LightSensor.SetAddress(Device_Address_H);//Address0x5C

LightSensor.SetMode(Continuous_H_resolution_Mode);

初始化完毕后,在loop()函数里面即可得出光照强度,相关语句如下:

lux = LightSensor.GetLightIntensity();

然后再编程将其所得数据写入到lcd显示器中即可。

3.DHT22温湿度传感器

与光照感应器相同,DHT22程序同样需要头文件,这些文件均可以从open jumper上下载到,将其放入安装目录的libraries文件夹下就可以了,首先引用DHT22文件:

#include <DHT22.h>

#include <stdio.h>

然后再为其定义引脚,这里我们定义为7引脚,语句如下:

#define DHT22_PIN 7

创建一个DHT22的对象,命名为myDHT22:

DHT22 myDHT22(DHT22_PIN);

然后我们用类DHT22的成员函数

myDHT22.getTemperatureC();

myDHT22.getHumidity();

来读取所检测到的温度和湿度。

除此之外,DHT22温湿度传感器还需要有一个脉冲宽度测量函数pulseIn()

pulseIn();

功能:监测指定引脚上的脉冲信号宽度。

例如,当要监测的高电平脉冲时,pulseIn()函数会等待引脚的电平变高,在变高后开始计时,直到电平变低时,计时停止。pulseIn()函数会返回此脉冲信号持续的时间,即该脉冲的宽度。

pulseIn()函数还能设定超时时间,如果超过设定时间仍未监测到脉冲,则会退出,pulseIn()函数并返回0,当没有设定超时时间时,pulseIn()会默认1秒钟的超时时间。

语法:

pulseIn(pin,value);

pulseIn(pin,value,timeout);

参数:

pin,需要读取脉冲的引脚;

value,需要读取的脉冲类型,为HIGH或者LOW;

timeout,超时时间,单位为毫秒,数据类型为无符号长整形;

返回值,换行返回脉冲宽度,单位为毫秒,数据类型为无符号长整形,如果在指定时间没有监测到脉冲,则返回0。

4.粉尘传感器

粉尘传感器共有五个接线口,由于我们一开始没有找到相关的技术资料,因此对这个东西束手无策,连接线的方式也不懂,在请教了一些大牛之后,终于搞懂了,其实五根数据导线,我们真正用到的只有三跟,在前面已经提到了。

其工作原理就是通过内部的红外探测仪,将经过内部空间的颗粒数转化为脉冲电流输出,并在程序内部经过一些转换公式统计得到空气中的粉尘数据。

首先定义粉尘传感器的引脚:

int pin = 6;

定义变量:

unsigned long duration;

unsigned long starttime;

unsigned long sampletime_ms = 30000;

unsigned long lowpulseoccupancy = 0;

float ratio = 0;

float concentration = 0;

该传感器需要预热30秒,才能接受正确的数据,所以我们可以用

millis();

函数获取系统运行的时间,再

if ((millis()-starttime) > sampletime_ms)

{

…………

}

就可以完成预热的过程了,最后将其搜集的数据显示到lcd显示器上。

5.土壤温湿度传感器

土壤传感器同样需要引入库函数名为“Sensirion.h”。
#include<Sensirion.h>
定义数据引脚和时钟引脚
const uint8_t dataPin =
2;
const uint8_t clockPin = 3;

定义变量
float temperature;
float humidity;

float dewpoint;

6.MINI12864LCD显示器

我们做lcd用到u8glib的类库,说来真的很糗,我们几个二货当初竟然浪费了近两天时间来研究名为“lcd12864”的类库,这个库通过字模来显示数据,输出数据的时候需要将数据转化为字模数组,这样很麻烦又很费时,于是我们果断放弃“”lcd12864的类库,转向”u8glib”的阵营。

将lcd显示器成功连接之后,在程序中包含u8glib的头文件,并创建一个对象:

#include<u8glib.h>
U8GLIB_MINI12864 u8g(10,9,8);
这样便成功建立了一个名为u8g,代表mini12864的对象
U8g的程序结构:

要想让lcd显示内容,还需要一个比较特殊的程序结构,称为图片循环,将其放在loop()循环中,代码如下:
void loop()
{
u8g.firstPage();
do{
draw();
}while(u8g.nextPage);
delay(1000);
}
以下是u8glib类库的一些常用函数:

setFont(font)

在显示文字时,需要使用setFont()函数设置显示字体,其中font即为要设定的字体

drawStr(x,y,string) 指定好字体后,便可以使用drawStr()函数输出字符了,其中的参数x,y表示显示的坐标,参数string即为显示的字符;在图形显示器上,左上角为原点,x,y所制定的位置为字符左下角点的位置,
U8g.drawStr(0,10,”hello Arduino”);

3)print(data)
Print()函数用于输出任意类型的数据,但是在使用print函数之前,仍需要设置字体,而且print()函数的显示位置还需要 setPrintPos()函数来确定。

setPrintPos(x,y)

setPrintPos()函数的参数x,y用于指定字符的位置。

在最终的程序中,需要显示的数据非常多,一个屏幕根本显示出来,所以我们的解决方法是将数据分成几个屏幕上显示出来,使用delay函数来设置显示的时间,这样就不用担心屏幕不够用了。

问题总结:

1、第一个遇到的问题就是粉尘传感器的问题,因为刚开始没有详细的手册,资料没找好、没彻底弄清传感器的原理和规格,不知道除了VCC和GND外的三根线哪些是数据输出,应该使用哪一根作为信号传输线,后来通过请教了解了线的问题。测试出的数据又过大,粉尘数过多,而且起伏很大,与一般实测数据差别过大,最后通过滤波和更改公式等方式解决。

2、LCD:lcd是让我们花费时间最多的一个部件。最开始根据教程资料我只知道lcd12864函数库,只是使用lcd12864函数库,全部转换成点阵输出,无法输出数据,让我半筹莫展。后来又下载了u8g函数库,但也只知道部分函数,输出函数只知道drawStr(x,y,string)函数。其中参数x,y用于指定字符的显示位置。由于只能输出字符串,所以我就像办法将数据转换成字符串,所以我用到了C语言的函数库stdilib函数库,以及fcvt()函数将浮点型值转换为字符串、itoa()将整型值转换为字符串。fcvt()函数有4个参数:第一个参数是要转换的浮点型值;第二个参数是转换结果中十进制小数点右侧的位数;第三个参数是指向一个整数的指针,该整数用来返回转换结果中十进制小数点的位置;第四个参数也是指向一个整数的指针,该整数用来返回转换结果的符号(0对应于正值,1对应于负值)。ecvt()将双精度浮点型值转换为字符串,转换结果中不包含十进制小数点。 gcvt()将双精度浮点型值转换为字符串,转换结果中包含十进制小数点。花费了大量时间转换后,后来也算是勉强将数据显示出来,不过在使用上还是有很大局限,使用非常不方便。后来在无意的翻书中发现u8g还有另一个数据输出函数print(),这个函数及可以输出字符串,可以输出整形浮点型数据。使用这个函数后使用非常方便,这也算是一次小小的插曲吧。

3、采集终端调试问题:我打算将各个数据采集感应器集中到一个控制器上,我把各个传感器程序编写完成以后一一进行了测试,所有的程序也没发现问题。接下来我就把所有的程序融合在一起,最后一步就是各个感应器的组装。由于风速风向感应器需要外界电源,但是外接电源接口还没有弄好,所以我前一天只测试了不要外接电源的粉尘、温湿度,紫外线等数据传感器,将它们组装在一起。第二天我在将剩下的风速风向传感器集中到一起,由于前一天已经将其余的传感器组装到控制器上,所以第二天我只是将传感器信号引脚添加到控制器之上,风速风向的外接电源则接在扩展版之上,而扩展版却没有接在控制器上。我测试出来的风速风向数据始终不正确,以为是程序问题,又不断修改程序,后来发现毫无斩获,又将程序分开来测试运行,将风速风向的程序单独写在加了扩展版的控制器上,发现数据又毫无问题。最后我用测试传感器电压的方法测试传感器电压,发现传感器发出的脉冲信号又无问题。

最后通过请教导师才发现原来是因为扩展版没有插在主控制器上,导致传感器只接通了电源的负极而没有接通控制器的GND,在主控器上没有形成电流回路,所以无法正确接收到传感器发出的脉冲电流信号。同过导师的点播让我明白了控制器接收脉冲信号的原理,只有在控制器上形成回路,脉冲才在控制器固定的电路上流动,控制器电路上用于读取脉冲信号的电子原件才能读到信号,也才能采集到数据,也算是吃一堑长一智有些收获吧。

4、点亮Lcd控制器背光灯:突然在一次小测试里发现lcd的背光引脚只是在setup()里设置了引脚为输出模式,在loop里却没有写输出高低电压或是模拟电压的输出语句,但是lcd却神奇的亮了,重复写入程序防止误差也是同样的结果还是一样,到现在也还没有找到原因。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: