Arduino调试温湿度传感器AM2321

AM2321是广州奥松电子生产的数字式温湿度传感器。虽是国产品牌,其精度也可以与国外的主流温湿度传感IC媲美。

  • 尺寸:11.3x7.8x4mm(长x宽x高)
  • 封装:0.05 pitch PTH
  • 工作电压:2.6~5V
  • 接口:I2C,最大速率100kbps,有特殊时序要求
  • 分辨率:温度0.1°C,相对湿度0.1%RH
  • 精度:室温时温度误差+/-0.3°C,相对湿度误差+/-3%RH
  • 重复性:温度+/-0.2°C,相对湿度+/-0.1%RH

美中不足:与国外同精度产品相比,AM2321的重复性和漂移指标偏大;只能手动焊接,量产时会很不方便。

电路连接

AM2321支持5V工作,将电源、地、SCL、SDA四个管脚直接与UNO板子的对应管脚相连。对于Arduino UNO,I2C总线的SDA信号线对应A4管脚,SCL时钟线对应A5管脚。之后,SCL、SDA线需要通过上拉电阻连接到5V电源,电阻值可取4.7k或10k。

功能调试

第一次调试花了不少时间,最终借助示波器才搞定。需留意的几个问题:

1. I2C地址问题。虽然手册里写的地址是0xB8(0b10111000),但实际上器件是采用的7位地址,应该表述成0x5C(0b1011100),代码中的地址也应写成0x5C,否则无法通信。

2. 唤醒AM2321时的时序问题。器件不回ACK,且最后一个时钟下降沿到发stop信号需间隔0.8~3ms。这个时序条件在Arduino的Wire库中没有处理的函数,因此只能将A4、A5设置成GPIO,利用bit-banging实现。shiftOut()函数可以实现字节的串行输出,且速率刚好也是100kbps左右。

3. A4、A5管脚在GPIO和硬件I2C之间的功能切换问题。在调用的Wire.begin()函数之后,再使用pinMode()或digitalWrite()函数就无效了。发现在Wire.begin()函数中设置了I2C的控制寄存器TWCR,需将TWCR恢复到调用Wire.begin()前的状态,才可以用GPIO的方式操作A4、A5。

4. 读返回数据时的时序问题。手册要求发送地址后,需要等待至少30μs后才能读取数据。这个功能在Wire库里也不支持,但直接用库里的函数(间隔约10μs)读取,没有发现有通信错误的问题。

参考代码:

  1 /*
  2 Measurement of temperature and humidity using the AM2321 sensor
  3 Attention:
  4     The protocol AM2321 used is not a standard i2c.
  5     Bit-banging is used to wake up the sensor,
  6     and then i2c functions are used to communicate.
  7 Connection:
  8 AM2321             UNO
  9 VDD <---------->   GND
 10 GND <---------->   GND
 11 SCL <----------> SCL(A5)
 12 SDA <----------> SDA(A4)
 13 */
 14
 15 #include <Wire.h>
 16
 17 #define ADDRESS_AM2321 0x5C //not 0xB8
 18 #define SIGN_WRITE 0x00
 19 #define SDA_PIN A4
 20 #define SCL_PIN A5
 21
 22 byte fuctionCode = 0;
 23 byte dataLength = 0;
 24 byte humiHigh = 0;
 25 byte humiLow = 0;
 26 byte tempHigh = 0;
 27 byte tempLow = 0;
 28 byte crcHigh = 0;
 29 byte crcLow = 0;
 30
 31 int humidity = 0;
 32 int temperature = 0;
 33 unsigned int crcCode = 0;
 34
 35 byte backupTWCR = 0;
 36
 37 void setup()
 38 {
 39     Serial.begin(115200);
 40 }
 41
 42 void loop()
 43 {
 44     //step 1. wake up the sensor
 45     SendWakeUp();
 46     backupTWCR = TWCR;
 47
 48     //step 2. send command
 49     Wire.begin();
 50     Wire.beginTransmission(ADDRESS_AM2321);
 51     Wire.write(0x03);
 52     Wire.write(0x00);
 53     Wire.write(0x04);
 54     Wire.endTransmission();
 55
 56     delayMicroseconds(1500);
 57
 58     //step 3. read data, and recover the TWCR register
 59     Wire.requestFrom(ADDRESS_AM2321, 8);
 60     fuctionCode = Wire.read();
 61     dataLength = Wire.read();
 62     humiHigh = Wire.read();
 63     humiLow = Wire.read();
 64     tempHigh = Wire.read();
 65     tempLow = Wire.read();
 66     crcLow = Wire.read();
 67     crcHigh = Wire.read();
 68
 69     //get the result
 70     humidity = (humiHigh<<8) | humiLow;
 71     temperature = (tempHigh<<8) | tempLow;
 72     crcCode = (crcHigh<<8) | crcLow;
 73
 74     Serial.print(temperature/10.0, 1);    Serial.println(" `C");
 75     Serial.print(humidity/10.0, 1);    Serial.println(" \%RH");
 76     CheckCRC();
 77
 78     //recover the TWCR register
 79     TWCR = backupTWCR;
 80
 81     delay(4000);
 82 }
 83
 84 void SendWakeUp()
 85 {
 86     //set pinmode
 87     pinMode(SCL_PIN, OUTPUT);
 88     pinMode(SDA_PIN, OUTPUT);
 89     digitalWrite(SCL_PIN, HIGH);
 90     digitalWrite(SDA_PIN, HIGH);
 91
 92     //issue a START condition
 93     delayMicroseconds(5);
 94     digitalWrite(SDA_PIN, LOW);
 95     delayMicroseconds(5);
 96     digitalWrite(SCL_PIN, LOW);
 97     delayMicroseconds(5);
 98
 99     //send ADDRESS+W
100     shiftOut(SDA_PIN, SCL_PIN, MSBFIRST, ((ADDRESS_AM2321<<1) | SIGN_WRITE));
101
102     //send clock for ack
103     pinMode(SDA_PIN, INPUT_PULLUP);// or INPUT mode
104     delayMicroseconds(5);
105     digitalWrite(SCL_PIN, HIGH);
106     delayMicroseconds(5);
107     digitalWrite(SCL_PIN, LOW);
108     pinMode(SDA_PIN, OUTPUT);
109     digitalWrite(SDA_PIN, LOW);
110
111     delayMicroseconds(1000);
112
113     //issue a STOP condition
114     digitalWrite(SCL_PIN, HIGH);
115     delayMicroseconds(5);
116     digitalWrite(SDA_PIN, HIGH);
117 }
118
119 void CheckCRC() //from the datesheet
120 {
121     byte backValues[] = {fuctionCode, dataLength, humiHigh, 122         humiLow, tempHigh, tempLow};
123     unsigned int crc = 0xFFFF;
124     int i;
125     int len = 6;
126     int j = 0;
127     while (len--)
128     {
129         crc ^= backValues[j];
130         j++;
131         for (i=0; i<8; i++)
132         {
133             if (crc & 0x01)
134             {
135                 crc >>= 1;
136                 crc ^= 0xA001;
137             }
138             else
139             {
140                 crc >>= 1;
141             }
142         }
143     }
144     if (crc == crcCode)
145     {
146         Serial.println("CRC checked.");
147     }
148     else
149     {
150         Serial.println("CRC Error!");
151     }
152 }

参考资料

奥松官网信息 - AM2321数字温湿度传感器
TI - Troubleshooting I2C Bus Protocol关于I2C调试问题处理的文档,推荐

时间: 2024-09-27 01:17:10

Arduino调试温湿度传感器AM2321的相关文章

使用Arduino Wire Library读取温湿度传感器AM2321

AM2321是采用I2C总线或单总线通讯的国产温湿度传感器.在AM2321手册中,当采用I2C通讯时,手册指定了多处需要主机等待的时间间隔,包括: (1)唤醒传感器时,从机不回复ACK,但主机主要等待800us~3ms再发送STOP信号: (2)主机发送读/写指令后,需等待至少1.5ms再发送读取时序: (3)读返回数据时,主机发送I2C地址后,需等待至少30us以上才能发送下一个串行时钟. 由于Arduino标准库Wire中的函数不支持指定(1)和(3)中的等待间隔,因此在之前的日志中,采用关

Arduino I2C + 温湿度传感器Si7021

  Si7021是Silicon Labs生产的温湿度传感器芯片.其主要特性: 湿度精度:误差典型值+/-2%RH,最大值+/-3%RH(0~80%RH),出厂已校正 温度精度:误差典型值+/-0.3%°C,最大值+/-0.4%°C(-10°C~85°C),出厂已校正 测量范围:温度范围0~100%RH:温度范围最大-40°C~125°C 工作电压:1.9~3.6V 低功耗:工作时150μA,待机时60nA 接口:I2C,最大速率支持400kbps 长期稳定性:湿度≤0.25%RH/yr,温度≤

Arduino I2C + 温湿度传感器HTS221

主要特性 HTS221是意法半导体(STMicroelectronics)生产的小体积.数字式温湿度传感器IC.该IC目前在官网仍处在“评估”状态.其主要特性: 工作电压:1.7~3.6V 数据输出频率(ODR)可设:1Hz ~ 12.5Hz 低功耗:2μ[email protected] ODR 温度精度:给出误差典型值+/-0.5°C, 15~40°C:但注明“Typical specifications are not guaranteed.”.无误差最大值信息. 湿度精度:给出误差典型值

Arduino连接SHT10温湿度传感器--返回值不正常解决办法

如题目,arduino中连接温湿度传感器,用的是一个github开源项目,地址:点击打开,其实这个就是一个封装好的库,下载后把解压的文件夹复制到Arduino目录下的librarys文件夹内,重启Arduino,到此就算是到库成功了.下面看电路连接图: 注意DATA和SCK两个脚对于Arduino上的数字引脚,在写程序的时候要用到,如图所示:将 SHT15 的 Data 脚接到 pin11, SCK 接到 pin10 电路图片: 导入库的路径: 其实库里面提供了一个实例代码,你可以直接拿过来使用

Arduino 温湿度传感器DHT11模块实验

网上有很多DHT11的测试,试了N个程序,总是不得要领,各种报错,最后终于找到一套可用的库. 首先是DHT11.h文件 #ifndef __DHT11_H__ #define __DHT11_H__ #include <Arduino.h> //DHT11 IO设置 #define DHT11_DQ 2 #define DHT11_DQ_0 digitalWrite(DHT11_DQ,LOW) #define DHT11_DQ_1 digitalWrite(DHT11_DQ,HIGH) //函

Arduino和C51开发DHT11温湿度传感器

技术:51单片机.Arduino.DHT11.温湿度传感器.传感器 概述 学习单片机离不开对传感器的学习,本文主要介绍DHT11温湿度传感器的使用方法,同学也可以了解更多的传感器,这对你以后开发产品的思维有很大的帮助 详细 代码下载:http://www.demodashi.com/demo/14729.html 一.DHT11温度传感器 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳

温湿度传感器DHT11

如果想使用 Arduino 开发板驱动 DHT11 来获取温湿度的时候建议使用第三方的库,这样可以加快程序的开发速度,而且不容易出错,下面的代码我已经安转了第三方的库了.详细的安装方法请参考极客先锋的博客:http://www.cnblogs.com/jikexianfeng/p/6290203.html 作者安装的为最低版本(1.0.0).这样为了更好的兼容. 1 /********************************* 2 代码功能:温湿度传感器DHT11 3 使用函数: 4 s

DH11数字温湿度传感器

DH11数字温湿度传感器是一种集温度.湿度一体的复合传感器,它能把温度和湿度物理量通过温.湿度敏感元件和相应电路转化成方便计算机.PLC.智能仪表等数据采集设备直接读取的数字量.DHT11由电阻式感湿器件和NTC系数感温器件构成,具有校准数字信号输出功能,采用单总线串行接口,输出数据一共5个字节,分别表示:湿度整数位.湿度小数位,温度整数位.温度小数位及校验和,其中检验和为湿度与温度之和的最低八位数据. arduino引脚 模块引脚 D2 S 5V VCC GND GND 1 double Fa

AM2320 温湿度传感器 C51程序 uart串口输出温湿度

实物图 引脚图 接线图 效果图 源代码 //****************************************************************// //AM系列温湿度传感器,读IIC使用示例  //单片机 :AT89S52 或 STC89C52RC  //功能  :串口发送温湿度数据  波特率 9600  //晶振  :12M (用户系统时钟如不是12M 请更改相关宏定义及注释的延时时间) //波特率:9600 //编译环境:  Keil 4 //*********