基于ZigBee与Arduino的无线测温装置

温度是我们生活中接触的较多的物理量之一,例如气温、人体温度,但很多时候却不能实地测量,例如在室内想实时知道室外的气温,这时候就需要使用无线传输来实现了。Arduino控制器外围实现ZigBee无线传输功能的主要有XBee模块和Zigduino控制器,XBee模块是串口操作,使用Arduino控制器与XBee模块即可实现ZigBee无线传输,但是XBee模块价格较高,而且需要转接板或连接线,不利于集成化;Zigduino是带有ZigBee无线传输功能的Arduino兼容控制器,具有集成化程度高、体积小、性价比高的优点。从性价比的角度出发,本文最终采用Zigduino控制器来实现温度数据的ZigBee无线传输。 本文利用Zigduino内部集成的无线模块实现数据的无线传输,温度测量部分采用单总线数字式温度传感器DS18B20实现温度测量,时钟和显示部分使用DS3231实时时钟模块和LCD1602液晶显示模块实现时钟和温度的显示功能。一、IDE的设置

Zigduino是一款兼容Arduino的开源硬件控制器,不仅与Arduino控制器保持兼容,而且内部集成了802.15.4协议无线模块,支持任何基于802.15.4协议的无线模块,包括ZigBee,MAC/6LoWPAN和 RF4CE。虽然Zigduino的核心单片机Atmega128RFA1的工作电压为3.3V,但是Zigduino控制器的引脚兼容5V,并且可以与Arduino扩展板保持兼容。除此之外,Zigduino控制器还内置了锂电管理模块,并且具有128KB FLASH和16KBSRAM,可以满足较复杂的应用需求。Zigduino实物图如图1所示。

image001.jpg

2013-12-17 13:43 上传
(119.06 KB)

图1 Zigduino实物图 Zigduino的开发环境是基于Aduino的开发环境开发而来,可以使用Ziduino完整版或Arduino IDE扩展包来实现Zigduino的开发。IDE完整版下载地址:http://pan.baidu.com/share/link?uk=3643299&shareid=387242,IDE扩展包下载地址:http://pan.baidu.com/share/link?shareid=419678&uk=3643299

完整版的使用方法:直接解压缩后运行arduino.exe,在板卡里选择OCROBOTHoneyBee即可正常使用。

扩展包的使用方法:将扩展包内2个文件夹复制到原IDE的根目录下,替换掉提示重复的文件后,再次运行arduino.exe即可正常使用。 二、温度测量部分 温度测量部分采用Zigduino控制器和温度传感器DS18B20来实现,将DS18B20的VDD和GND分别接至Zigduino 控制器的5V和GND,数据引脚DQ接至Zigduino控制器的数字端口D2,并且在数据引脚DQ与+5V之间连接阻值为4.7kΩ的上拉电阻,以保证温度传感器DS18B20能够正常工作,Zigduino控制器与DS18B20的连接示意图如图2所示。


image002.png

2013-12-17 13:44 上传
(89.64 KB)

图2 温度测量部分硬件连接图 温度测量部分采用Zigduino控制器与DS18B20来实现温度的测量,即可使用第三方函数库DallasTemperature来实现,只是将带有两位小数的温度数据先放大100倍,以去除小数点,再提取出温度数据的整数部分和小数部分,具体代码如下所示。

ARDUINO 代码复制打印

#include <ZigduinoRadio.h>   //加载无线库#include <OneWire.h>   //加载单总线总线库#include <DallasTemperature.h> //加载单总线温度传感器库#define ONE_WIRE_BUS 2   //定义单总线所连接的引脚OneWire oneWire(ONE_WIRE_BUS);DallasTemperature sensors(&oneWire);char i,j;   //定义变量,用于存放温度数据的整数和小数部分int a;   //定义变量,用于存放温度数据void setup(){ZigduinoRadio.begin(11);//设置通道为11,可设置为11-26sensors.begin(); //初始化传感器}void loop(){sensors.requestTemperatures(); // 从DS18B20传感器获取温度数据a=sensors.getTempCByIndex(



三、时钟和显示部分 时钟和显示部分采用Zigduino控制器和DS3231实时时钟模块、LCD1602液晶显示屏模块来实现,将DS3231的5V和GND分别接至Zigduino 控制器的5V和GND,信号引脚SCL、SDA分别接至Zigduino控制器的端口SCL、SDA;将LCD1602液晶显示屏模块的VCC、GND、R/W分别接至Zigduino 控制器的5V、GND和GND,对比度调节引脚VEE通过10kΩ的电位器来调节分压值,从而实现对比度的调节,信号控制引脚RS、E分别直接至Zigduino 控制器数字端口D7和D6,数据输入引脚D4、D5、D6、D7分别接至Zigduino 控制器数字端口D5、D4、D3、D2。具体的连接示意图如图3所示。

image003.png

2013-12-17 13:44 上传
(121.96 KB)

图3 时钟和显示部分硬件连接图 温度测量部分采用Zigduino控制器与DS18B20来实现温度的测量,即可使用第三方函数库DallasTemperature来实现,只是将带有两位小数的温度数据先放大100倍,以去除小数点,再提取出温度数据的整数部分和小数部分,具体代码如下所示。

ARDUINO 代码复制打印

/***** 包含库文件*******/#include <LiquidCrystal.h>//加载液晶显示库#include <Wire.h>   //加载I2C总线库#include <ZigduinoRadio.h> //加载无线库#include "DS3231.h"   //加载DS3231时钟库DS3231 RTC; //创建时钟类LiquidCrystal lcd(7, 6, 5, 4, 3, 2);//依次为液晶RS、E、D4、D5、D6、D7所连接的引脚char i,j;void setup(){   ZigduinoRadio.begin(11); //设置通道为11,可设置为11-26   lcd.begin(16, 2);  //初始化1602液晶显示屏   Wire.begin();   //初始化I2C总线   RTC.begin();   //启动DS3231实时时钟模块   lcd.clear();    //清除液晶显示屏上的内容} void loop(){  lcd.setCursor(0, 0);  DateTime now = RTC.now();//获取当前时间  lcd.print(now.year(), DEC); //显示年份  lcd.print('/');  lcd.print(now.month(), DEC);//显示月份  lcd.print('/');  lcd.print(now.date(), DEC); //显示日期  lcd.setCursor(0, 1);  lcd.print(now.hour(), DEC); //显示小时  lcd.print(':');  if(now.minute()>9){   //判断是否分钟的十位部分是否为零,若十位部分为零,则在十位处显示0,,例如为5分钟,则显示为05。下同。    lcd.print(now.minute(), DEC);//显示分钟  }  else{    lcd.print("



四、时钟校准部分 或许当你完成以上的工作之后,却发现时间不正确,这是因为时钟芯片或模块在出厂之后没有能够保证一直供电,或者其他原因的影响,导致时钟模块的时间与当前时间有所差值,这时候就需要对时钟模块进行校准。在时钟校准代码中将时间改为当前时间,最好略微超前30秒左右,因为编译和下载需要浪费一会儿时间,然后将校准代码下载至连接有DS3231实时时钟模块的Zigduino或Arduino 控制器,时钟校准代码如下所示。
ARDUINO 代码复制打印
#include <Wire.h>#include "DS3231.h"DS3231 RTC; //Create the DS3231 objectchar weekDay[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };//year, month, date, hour, min, sec and week-day(starts from 0 and goes to 6)//writing any non-existent time-data may interfere with normal operation of the RTC.//Take care of week-day also.DateTime dt(2011, 11, 10, 15, 18, 0, 5); //需要校准的时间,最好void setup (){  Serial.begin(57600);  Wire.begin();  RTC.begin();  RTC.adjust(dt); //Adjust date-time as defined 'dt' above}void loop (){  DateTime now = RTC.now(); //获取时间  Serial.print(now.year(), DEC);  Serial.print('/');  Serial.print(now.month(), DEC);  Serial.print('/');  Serial.print(now.date(), DEC);  Serial.print(' ');  Serial.print(now.hour(), DEC);  Serial.print(':');  Serial.print(now.minute(), DEC);  Serial.print(':');  Serial.print(now.second(), DEC);  Serial.println();  Serial.print(weekDay[now.dayOfWeek()]);  Serial.println();  delay(1000);}
#include <Wire.h>
#include "DS3231.h"
DS3231 RTC; //Create the DS3231 object
char weekDay[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
//year, month, date, hour, min, sec and week-day(starts from 0 and goes to 6)
//writing any non-existent time-data may interfere with normal operation of the RTC.
//Take care of week-day also.
DateTime dt(2011, 11, 10, 15, 18, 0, 5); //需要校准的时间,最好
void setup ()
{
Serial.begin(57600);
Wire.begin();
RTC.begin();
RTC.adjust(dt); //Adjust date-time as defined 'dt' above
}
void loop ()
{
DateTime now = RTC.now(); //获取时间
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.date(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
Serial.print(weekDay[now.dayOfWeek()]);
Serial.println();
delay(1000);
}


五、实验演示 实物演示图如图4所示,上方为时钟和显示部分,下方为温度测量部分。为了更好的证明两者是通过无线传输数据,温度测量部分采用外接电源端口供电,时钟和显示部分采用USB端口供电。

image005.jpg

2013-12-17 13:44 上传
(205.84 KB)

图4 实物演示图

我的博客地址:更多Arduino与LabVIEW、Proteus方向的文章。
via - 极客工坊

标签: Arduino教程