极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 55635|回复: 23

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

[复制链接]
发表于 2013-12-17 13:45:12 | 显示全部楼层 |阅读模式
本帖最后由 nust_奔跑 于 2013-12-19 19:56 编辑

       温度是我们生活中接触的较多的物理量之一,例如气温、人体温度,但很多时候却不能实地测量,例如在室内想实时知道室外的气温,这时候就需要使用无线传输来实现了。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所示。

图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所示。

图2 温度测量部分硬件连接图
       温度测量部分采用Zigduino控制器与DS18B20来实现温度的测量,即可使用第三方函数库DallasTemperature来实现,只是将带有两位小数的温度数据先放大100倍,以去除小数点,再提取出温度数据的整数部分和小数部分,具体代码如下所示。
  1. #include <ZigduinoRadio.h>       //加载无线库
  2. #include <OneWire.h>           //加载单总线总线库
  3. #include <DallasTemperature.h>   //加载单总线温度传感器库
  4. #define ONE_WIRE_BUS 2       //定义单总线所连接的引脚
  5. OneWire oneWire(ONE_WIRE_BUS);
  6. DallasTemperature sensors(&oneWire);
  7. char i,j;       //定义变量,用于存放温度数据的整数和小数部分
  8. int a;         //定义变量,用于存放温度数据
  9. void setup()
  10. {
  11.   ZigduinoRadio.begin(11);//设置通道为11,可设置为11-26
  12.   sensors.begin();   //初始化传感器
  13. }
  14. void loop(){
  15.   sensors.requestTemperatures(); // 从DS18B20传感器获取温度数据
  16.   a=sensors.getTempCByIndex(0)*100; //将温度数据放大100倍,以去除小数点
  17.   i=a/100;    //取出温度数据的整数部分
  18.   j=a%100;   //取出温度数据的小数部分
  19.   ZigduinoRadio.beginTransmission();//无线开始通信标志
  20.   ZigduinoRadio.write(i);//无线发送温度数据的整数部分
  21.   ZigduinoRadio.write(j);//无线发送温度数据的小数部分
  22.   ZigduinoRadio.endTransmission();//无线结束通信标志
  23.   delay(1000);   //更新速率为1次/秒
  24. }
复制代码


三、时钟和显示部分
       时钟和显示部分采用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所示。

图3 时钟和显示部分硬件连接图
       温度测量部分采用Zigduino控制器与DS18B20来实现温度的测量,即可使用第三方函数库DallasTemperature来实现,只是将带有两位小数的温度数据先放大100倍,以去除小数点,再提取出温度数据的整数部分和小数部分,具体代码如下所示。
  1. /***** 包含库文件*******/
  2. #include <LiquidCrystal.h>  //加载液晶显示库
  3. #include <Wire.h>         //加载I2C总线库
  4. #include <ZigduinoRadio.h> //加载无线库
  5. #include "DS3231.h"       //加载DS3231时钟库

  6. DS3231 RTC; //创建时钟类
  7. LiquidCrystal lcd(7, 6, 5, 4, 3, 2);  //依次为液晶RS、E、D4、D5、D6、D7所连接的引脚
  8. char i,j;

  9. void setup()
  10. {
  11.          ZigduinoRadio.begin(11); //设置通道为11,可设置为11-26
  12.          lcd.begin(16, 2);        //初始化1602液晶显示屏
  13.          Wire.begin();           //初始化I2C总线
  14.          RTC.begin();           //启动DS3231实时时钟模块
  15.          lcd.clear();            //清除液晶显示屏上的内容
  16. }
  17. void loop()
  18. {
  19.         lcd.setCursor(0, 0);
  20.         DateTime now = RTC.now();  //获取当前时间
  21.         lcd.print(now.year(), DEC);   //显示年份
  22.         lcd.print('/');
  23.         lcd.print(now.month(), DEC);  //显示月份
  24.         lcd.print('/');
  25.         lcd.print(now.date(), DEC);   //显示日期
  26.         lcd.setCursor(0, 1);
  27.         lcd.print(now.hour(), DEC);   //显示小时
  28.         lcd.print(':');
  29.         if(now.minute()>9){       //判断是否分钟的十位部分是否为零,若十位部分为零,则在十位处显示0,,例如为5分钟,则显示为05。下同。
  30.           lcd.print(now.minute(), DEC);  //显示分钟
  31.         }
  32.         else{
  33.           lcd.print("0");
  34.           lcd.print(now.minute(), DEC);
  35.         }
  36.         lcd.print(':');      
  37.         if(now.second()>9){
  38.            lcd.print(now.second(), DEC);   //显示秒钟
  39.         }
  40.         else{
  41.           lcd.print("0");
  42.           lcd.print(now.second(), DEC);
  43.         }
  44.         lcd.print(" ");
  45.         if (ZigduinoRadio.available())//判断无线是否接受到数据
  46.         {
  47.           i=(char)ZigduinoRadio.read();//将接收到的数据赋给变量i,因为我们在发射端发送的数据为char型变量,故要接收char型可以直接在接收变量前面加(char),这样既可使接收到的数据变为char型。
  48.           j=(char)ZigduinoRadio.read();
  49.         }
  50.          lcd.print(i,DEC);     //显示温度数据的整数部分
  51.          lcd.print(".");
  52.          if(j>9){
  53.             lcd.print(j,DEC);   //显示温度数据的小数部分
  54.         }
  55.         else{
  56.           lcd.print("0");
  57.           lcd.print(j,DEC);
  58.         }
  59.          lcd.write(0xdf);   //显示摄氏温度单位℃
  60.          lcd.write('C');  
  61. }
复制代码


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


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

我的博客地址:更多Arduino与LabVIEW、Proteus方向的文章

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2013-12-17 15:49:17 | 显示全部楼层
特别说明一下,HoneyBee管脚仅支持到3.3V电压,切勿接入5V电平
回复 支持 反对

使用道具 举报

发表于 2013-12-17 17:37:12 | 显示全部楼层
大神 我的 APC220有通信库吗???
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-17 18:33:44 | 显示全部楼层
学慧放弃 发表于 2013-12-17 17:37
大神 我的 APC220有通信库吗???

APC220直接串口发送/接收数据就可以了。
回复 支持 反对

使用道具 举报

发表于 2013-12-17 19:20:22 | 显示全部楼层
哎呀!!!刚刚查了下,  Zigduino,淘宝上买600多,板子还400多呢!!!
玩不起啊!!树莓派2也不过200多啊!!!wr703n也就100左右啊!!
太贵
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-17 20:33:32 | 显示全部楼层
潇洒哥 发表于 2013-12-17 19:20
哎呀!!!刚刚查了下,  Zigduino,淘宝上买600多,板子还400多呢!!!
玩不起啊!!树莓派2也不过200多 ...

OCRBOT出品的Honeybee是Zigduino兼容控制器才168块,值得拥有啊!
http://item.taobao.com/item.htm? ... &id=20740127998
回复 支持 反对

使用道具 举报

发表于 2013-12-17 21:56:46 | 显示全部楼层
这个不错。。。果断加精。。。
回复 支持 反对

使用道具 举报

发表于 2013-12-18 01:51:46 | 显示全部楼层
=。= 写得好详细啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-18 11:32:39 | 显示全部楼层
弘毅 发表于 2013-12-17 21:56
这个不错。。。果断加精。。。

感谢弘毅大大!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-18 11:32:56 | 显示全部楼层
水乐天 发表于 2013-12-18 01:51
=。= 写得好详细啊

快来山寨一个吧~
代码都放出来了~~~
回复 支持 反对

使用道具 举报

发表于 2013-12-19 10:57:29 | 显示全部楼层
这东西能刷openwrt或者ddwrt吗?不过好像没有网口啊!!
回复 支持 反对

使用道具 举报

发表于 2013-12-19 11:45:19 | 显示全部楼层
潇洒哥 发表于 2013-12-19 10:57
这东西能刷openwrt或者ddwrt吗?不过好像没有网口啊!!

。。。。。。wrt需要arm级别的路由器运算速度,那个已经是上操作系统了
回复 支持 反对

使用道具 举报

发表于 2013-12-19 13:19:21 | 显示全部楼层
wrt需要arm级别的路由器运算速度,那个已经是上操作系统了

奥,哪天arduino能集成一个类似wr703n路由似得wifi功能就好了,这样坐小车就不用再拖着一个路由器了!!!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-19 19:46:13 | 显示全部楼层
潇洒哥 发表于 2013-12-19 10:57
这东西能刷openwrt或者ddwrt吗?不过好像没有网口啊!!

亲~~~这是ZigBee无线网~很火的那个哦~~~
无线传感网络~~~
你说的那是wifi吧?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-19 19:46:36 | 显示全部楼层
弘毅 发表于 2013-12-19 11:45
。。。。。。wrt需要arm级别的路由器运算速度,那个已经是上操作系统了

弘毅,你的头像和你真人好像啊~~~~
哈哈哈~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-5-2 18:30 , Processed in 0.047138 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表