Arduino 是一个开源单片机平台。前两天得到一块测温IC模块,LM75,正好有机会研究下Arduino的 I2C 通讯功能。关于I2C总线的知识,可以在这里找到。
(哪里能得到 LM75 呢,试试万能的taobao吧 ,呵呵)
LM75 是一个I2C接口的测温元件,外围电路仅仅需要一枚电容,它的datasheet可以从官方网站上下载到 ,具体的spec这里就不多讲了,感兴趣的可以查看它的datasheet。说到这里,很是感慨,就这么一个4mm*5mm见方的小东西,手册却一点也不含糊,详详细细介绍了所有的功能。其实,有时候看元器件的手册对扩展知识面也很有帮助。LM75的主要功能是测温,本文的目的就是如何应用Arduino和LM75来获取当前的温度,核心是Arduino的I2C协议的应用。
看LM75的datasheet,会知道它是作为slave,地址是7-bits,1001A2A1A0,我手里这个A2\A1\A0都是短接地的,所以地址就是1001000,继续查找手册,温度的指针寄存器是00000000,温度的格式是16bits,前面8bits最高位是MSB,若MSB为1,表示为负,后面8bits的最高位是LSB,为 0.5度。为了简化程序,我们只取温度的整数部分,即D15-D8。
再看Arduino的Wire库的应用,Arduino作为master,首先要向I2C总线上的LM75地址发送读取温度寄存器的指令,即00000000,这一步本程序版本0.01暂不考虑,因为LM75上电后,指针寄存器里的指针即指向温度寄存器, 然后读取一个byte就可以得到温度的高8位,即整数值。
让我们看程序:(版本0.01)
#include <Wire.h> void setup() { Wire.begin(); // join i2c bus (address optional for master) Serial.begin(9600); // start serial for output } void loop() { Wire.requestFrom(B1001000, 1); // request 1 byte from adress 1001000 while(Wire.available()) { int temp = Wire.receive(); Serial.println(temp); } delay(500); }
上传到Arduino后,打开Serial Monitor ,就可以在下部的窗口里读到温度值。
哈,我现在室内温度是28度!看来南京最近的天气还是比较凉快的!
关于如何使用小数部分,参阅:《Arduino 和 LM75 的 I2C 总线通讯(2) – 温度小数部分》,这样可以由原来1度的分辨率提高到0.5度的分辨率。
扩展阅读
- SoftI2CMaster: Add I2C to any Arduino pins
http://todbot.com/blog/2010/09/25/softi2cmaster-add-i2c-to-any-arduino-pins/ - 双Arduino主从机之间的I2C总线通讯实验
http://blog.sina.com.cn/s/blog_705dc8d40100y2iv.html - 浅谈I2C总线工作原理与应用
http://www.robotsky.com/ChuanGan/WangLuo/2012-03-27/13328458917231.html - I2C应用: 不能说的秘密
http://www.rosoo.net/a/201101/10749.html - Library f. LM75 – measure temperature and more..
http://arduino.cc/forum/index.php?topic=38058.0 - linux下的I2C温度传感器应用
http://blog.csdn.net/vastsmile/article/details/5456878 - 主板上的温度监控技术
http://www.yesky.com/4/23504.shtml - Arduino教程 – I2C模块的使用 – 集成DS1307时钟芯片、AT24C32存储芯片、LM75温度侦测
http://www.geek-workshop.com/thread-5929-1-1.html - http://rweather.github.io/arduinolibs/index.html
关键字:Arduino, I2C, Wire, LM75, slave
写的很诱人,图片看不到~!
@XDash
picasa 被墙了,要改hosts解决,参看 http://www.davidrobot.com/2009/07/picasa-pic-blocked.html
I tested your code to read the temperature. I have noticed that sometimes the arduino gets stuck and does not read the temperature. After looking for the problem. I noticed that it is recommended to read 2 octets at a time.
This is your code slightly modified
#include
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
Serial.println(“Let’s measure the Temperature.”);
}
void loop()
{
Wire.requestFrom(B1001000, 2); // request 2 byte from address 1001000
while(Wire.available())
{
int temp = Wire.receive(); // Read the first octet
int lsb = Wire.receive(); // Read the second octet
Serial.print(“temperature = “);
Serial.println(temp);
}
delay(500);
}
Best regards
@Tom Dupont
Thanks for your codes !