宜昌老张

DHT11和LCD4884组成的温湿度测量计

0
阅读(5139)

     

    盛夏来了,又热又潮,不知道家里的气候如何,想着买个温湿度计,但是物价飞涨,工资不涨,没钱买啊!不如自己做个,应该不难,于是开始动手制作。

     这个作品的两个主角是数字温湿度传感器 DHT11和LCD4884 Shield 点阵液晶显示器,好像很简单,就是把DHT11的温湿度值采样到Arduino控制器里,然后对采样值进行处理,按照格式发送到LCD4884显示器中显示出来。我也就花了1天半的时间搞出来的。

    LCD4884显示器板子直接插在Arduino UNO控制板的母槽引脚上,它与Arduino板子形成层叠关系,但是并未把Arduino可用的端口挡住,因为LCD4884板子上把Arduino的5个模拟端口和6个数字端口引出来了,并布局到LCD4884板子上,以便使用。 于是DHT11温湿度传感器用并排的三根杜邦线插在了模拟端口5上。

     把Arduino控制板和DHT11传感器用双面胶带粘在电池盒背面,再把电池盒的电源插头插到Arduino UNO的电源插座,于是我家的温湿度测量计硬件系统就这样快速搭建完成。至于软件系统的编制,我下面慢慢谈。先介绍LCD4884显示器。

      LCD4884 shield的一款48x84点阵液晶显示器,Arduino叠层设计,可直接插接到大部分Arduino控制器上使用,可显示中文、英文、图片等。模块具有5个模拟扩展端口和6个数字扩展端口,可连接DFRobot公司大部分的模拟或数字传感器,还具有一个小型的手机摇杆,可实现5个按键操作。LCD4884 shield是制作互动作品不可多得的显示器。

    Arduino系统之所以好用,不仅是单片微机本身编程容易,而且给它的外设编程时,只要程序稍复杂些,大都可以从网络上或者厂家得到相应的库文件,LCD4884自然也有好用的库文件,针对Arduino UNO,LCD4884的库文件请下载:8925503293234.zip 。
      LCD4884库文件请放在Arduino IDE软件文件夹里的libraries文件夹里,这个库文件就可用了,如下图。

 

    在Arduino IDE编程环境里,打开库文件里自带的LCD4884样例程序,哇塞,蛮长的,还有些复杂,都是LCD4884板子上的小型手机摇杆“惹得祸”!我这个作品不需要那个摇杆,只需要LCD显示即可,所以我删去了一些“没用的”程序段。

     先做做实验,让屏幕显示:“温度:34'C”和”湿度:52 %“。程序如下(有详细注释):

(注意:程序中itoa()函数作用是,把整数数值转换为字符串,不能转换带小数点的浮点数。)

#include "LCD4884.h" //声明LCD4884库函数

#include "Word1_cn.h" //内含汉字“温度:”的点阵数组的头文件
 
#include "Word2_cn.h" //内含汉字“湿度:”的点阵数组的头文件

int num1;
int num2;
char string1[10];//温度值字符串变量
char string2[10];//湿度值字符串变量

void setup()
{
   lcd.LCD_init( );//初始化LCD4884
   lcd.LCD_clear( ); //清屏 
   //把温度值整数部分转换为字符串
   num1=34;
   itoa(num1,string1,10);
   //把湿度值整数部分转换为字符串
   num2=52; 
   itoa(num2,string2,10);
}
 
//主程序
void loop()
{
    //LCD第6列第1行,显示汉字“温度:”,字体12,显示三个汉字
    lcd.LCD_write_chinese(6,1, Word1_cn,12,3,0,0);
    //LCD第42列第1行,显示温度值整数部分字符,普通显示
    lcd.LCD_write_string(42, 1,string1,MENU_NORMAL);
    //显示温度单位
     lcd.LCD_write_string(54, 1,"'C",MENU_NORMAL);
    //LCD第6列第4行,显示汉字“湿度:”,字体12,显示三个汉字 
    lcd.LCD_write_chinese(6,4, Word2_cn,12,3,0,0);
    //LCD第42列第4行,显示湿度值整数部分字符,普通显示
    lcd.LCD_write_string(42,4, string2,MENU_NORMAL);
    //显示湿度单位
    lcd.LCD_write_string(54,4," %",MENU_NORMAL);
    delay(500);//延时0.5s
}
 
   看看上面程序,LCD4884可以显示汉字,是通过字模软件提取每个汉字的字模点阵数组来实现的。程序中“温度:”和”湿度:“的字模点阵数组,分别放在红色字体标注的”Word1_cn“和”Word2_cn“头文件里,头文件可以用windows操作系统自带的“记事本”编辑和保存,只不过要记住,文件扩展名为”*.h“。现在问题是用什么字模软件,如何使用它,如何提取它生成的字模点阵字节数据。
LCD汉字字模软件请下载:8955342397725.zip
    这个字模软件是绿色软件,无需安装,解压后,点击字模软件文件夹里的启动图标,运行软件。请按照图示的步骤顺序操作,然后可以看到,字体为12的”温度:“的点阵数组是什么!
     按照步骤操作,1、2、3、4、5,OK,然后出现下图。
 
    把生成的三个汉字字符,包括”:“,点阵数组中的数据(图用方框标注的)拷贝到记事本里,编辑在”Word1_cn“数组里(图用方框标注的)。然后以头文件Word1_cn.h形式保存在‘’这个任务的Arduino程序所在的同一个文件夹‘’。这一点一定注意!当然您想换其他可读性好的名字也可以,但必须头文件中的数组名与Arduino程序的引用要一致,什么是“引用”,看上面Arduino程序用红色字体标注的数组名。
     会了汉字如何在LCD4884里如何显示,字符串显示就用常规的方法即可,所以再看看前面的LCD4884显示测试程序,结合程序注释,应该可以看懂程序。学习了LCD4884,下面该学DHT11传感器的编程了。
        DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。

传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。

       单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品连接方便,可直接插接到Arduino传感器扩展板上。

    由于DHT11传感器是采用单线制串行通讯的方法,进行采样数据的,要配合时序,一位位从单条通讯线传过来,再合成8位字节,然后还要进行校验和,判断数据传送是否正确,所以看厂家自带程序,又是蛮长,看起来头疼!,实际上有时候,我们琢磨一个东西,可以大刀阔斧,没必要专牛角尖。所以从程序找到你需要的温度值和湿度值,就行了,dht11_dat[2]为温度值整数部分,dht11_dat[0]为湿度值整数部分。我将在下面程序用红色字体标注出读取温度值和湿度值程序段,并且用绿色字体标注出LCD4884显示部分

    厂家的DHT11测试程序请下载:9108788405880.zip(厂家程序中,温度、湿度值是通过上传PC机的Arduino的串口窗口来显示的)

      我把厂家测试程序中,串口显示程序和数据校验和部分去掉,加上了LCD4884显示部分,编写了下面完整的温湿度测量计的程序。

#define DHT11_PIN 5      //DHT11  连接UNO 模拟端口PIN 5
#include "LCD4884.h"//声明LCD4884库函数
#include "Word1_cn.h"//内含汉字“温度:”的点阵数组的头文件
#include "Word2_cn.h"//内含汉字“湿度:”的点阵数组的头文件
char string1[10];//温度值字符串变量
char string2[10];//湿度值字符串变量
byte read_dht11_dat()//读取DHT11的温湿度值
{
byte i = 0;
byte result=0;
for(i=0; i< 8; i++){
while(!(PINC & _BV(DHT11_PIN)));  // wait for 50us
delayMicroseconds(30);
if(PINC & _BV(DHT11_PIN)) 
result |=(1<<(7-i));
              while((PINC & _BV(DHT11_PIN)));  // wait '1' finish    
}
return result;
}

void setup()
{
DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN);
lcd.LCD_init();//初始化LCD4884
lcd.LCD_clear(); //清屏       
}

void loop()
{
byte dht11_dat[5];//存储从DHT11传感器采样的温湿度值的数组
byte dht11_in;
byte i;
// start condition
// 1. pull-down i/o pin from 18ms
//启动采样
        PORTC &= ~_BV(DHT11_PIN);
delay(18);
PORTC |= _BV(DHT11_PIN);
delayMicroseconds(40);

DDRC &= ~_BV(DHT11_PIN);
delayMicroseconds(40);

dht11_in = PINC & _BV(DHT11_PIN);
delayMicroseconds(80);

dht11_in = PINC & _BV(DHT11_PIN);
delayMicroseconds(80);
       // 接受来自DHT11传感器传送的5个字节温湿度值
        //第一个字节是湿度值整数部分
        //第二个字节是湿度值小数部分
        //第三个字节是温度值整数部分
        //第四个字节是温度值小数部分
        //第五个字节是校验值,可以判断数据传送是否正确
for (i=0; i<5; i++)
dht11_dat[i] = read_dht11_dat();

DDRC |= _BV(DHT11_PIN);
PORTC |= _BV(DHT11_PIN);
byte dht11_check_sum = dht11_dat[0]+dht11_dat[1]+dht11_dat[2]+dht11_dat[3];
//检测校验值,判断是否采样出错
/*if(dht11_dat[4]!= dht11_check_sum)
{
Serial.println("DHT11 checksum error");
}*/
       itoa(dht11_dat[2],string1,10);//把温度值整数部分转换为字符串
       itoa(dht11_dat[0],string2,10);//把湿度值整数部分转换为字符串
       //LCD第6列第1行,显示汉字“温度:”,字体12,显示三个汉字
        lcd.LCD_write_chinese(6,1, Word1_cn,12,3,0,0);
        //LCD第42列第1行,显示温度值整数部分字符,普通显示
        lcd.LCD_write_string(42, 1,string1,MENU_NORMAL);
        //显示温度单位
         lcd.LCD_write_string(54, 1,"'C",MENU_NORMAL);
        //LCD第6列第4行,显示汉字“湿度:”,字体12,显示三个汉字 
        lcd.LCD_write_chinese(6,4, Word2_cn,12,3,0,0);
        //LCD第42列第4行,显示湿度值整数部分字符,普通显示
        lcd.LCD_write_string(42,4, string2,MENU_NORMAL);
        //显示湿度单位
        lcd.LCD_write_string(54,4," %",MENU_NORMAL);
        delay(500);//延时0.5s
}
    以上程序,并加上“温度:”和“湿度:”汉字点阵数组头文件,打包成zip文件,请下载:9119844501710.zip 。
    晚上我又给刚制作出来的温湿度测量计拍了个照,夜晚,幽蓝的LCD背景灯照亮着屏幕上的温湿度值,显示出一种静谧和科技味道,感觉有点惬意。