标签:
AM2321是采用I2C总线或单总线通讯的国产温湿度传感器。在AM2321手册中,当采用I2C通讯时,手册指定了多处需要主机等待的时间间隔,包括:
(1)唤醒传感器时,从机不回复ACK,但主机主要等待800us~3ms再发送STOP信号;
(2)主机发送读/写指令后,需等待至少1.5ms再发送读取时序;
(3)读返回数据时,主机发送I2C地址后,需等待至少30us以上才能发送下一个串行时钟。
由于Arduino标准库Wire中的函数不支持指定(1)和(3)中的等待间隔,因此在之前的日志中,采用关闭I2C并采用bit-banging的方式唤醒传感器。
然而,就我手头的传感器测试发现,即使(3)的等待时间降低到10us左右(即100kHz速率正常通讯),并且将(1)改成“发送STOP信号后等待800us”,器件也是可以正常工作的。
这样的话,利用Wire库自带的函数,就可以实现对AM2321的操作。我利用手头的传感器分别在5V和3.3V供电下测试,都可以正常读写。
1 /* 2 Measurement of temperature and humidity using the AM2321 sensor 3 Attention: 4 Use functions in Wire library to wake up the sensor. 5 Although the sequence is different with the datasheet, it indeed works. 6 Connection: 7 AM2321 UNO 8 VDD <---------> GND 9 GND <---------> GND 10 SCL <---------> SCL(A5) 11 SDA <---------> SDA(A4) 12 */ 13 14 #include <Wire.h> 15 16 #define ADDRESS_AM2321 0x5C //not 0xB8 17 #define SDA_PIN A4 18 #define SCL_PIN A5 19 20 byte fuctionCode = 0; 21 byte dataLength = 0; 22 byte humiHigh = 0; 23 byte humiLow = 0; 24 byte tempHigh = 0; 25 byte tempLow = 0; 26 byte crcHigh = 0; 27 byte crcLow = 0; 28 29 int humidity = 0; 30 int temperature = 0; 31 unsigned int crcCode = 0; 32 33 void setup() 34 { 35 Wire.begin(); 36 Serial.begin(115200); 37 } 38 39 void loop() 40 { 41 //step 1. wake up the sensor 42 Wire.beginTransmission(ADDRESS_AM2321); 43 Wire.endTransmission(); 44 45 delayMicroseconds(800); 46 47 //step 2. send command 48 Wire.beginTransmission(ADDRESS_AM2321); 49 Wire.write(0x03); 50 Wire.write(0x00); 51 Wire.write(0x04); 52 Wire.endTransmission(); 53 54 delayMicroseconds(1500); 55 56 //step 3. read data 57 Wire.requestFrom(ADDRESS_AM2321, 8); 58 fuctionCode = Wire.read(); 59 dataLength = Wire.read(); 60 humiHigh = Wire.read(); 61 humiLow = Wire.read(); 62 tempHigh = Wire.read(); 63 tempLow = Wire.read(); 64 crcLow = Wire.read(); 65 crcHigh = Wire.read(); 66 67 //get the result 68 humidity = (humiHigh<<8) | humiLow; 69 temperature = (tempHigh<<8) | tempLow; 70 crcCode = (crcHigh<<8) | crcLow; 71 72 Serial.print(temperature/10.0, 1); Serial.println(" `C"); 73 Serial.print(humidity/10.0, 1); Serial.println(" \%RH"); 74 CheckCRC(); 75 76 delay(4000); 77 } 78 79 void CheckCRC() //from the datesheet 80 { 81 byte backValues[] = {fuctionCode, dataLength, humiHigh, 82 humiLow, tempHigh, tempLow}; 83 unsigned int crc = 0xFFFF; 84 int i; 85 int len = 6; 86 int j = 0; 87 while (len--) 88 { 89 crc ^= backValues[j]; 90 j++; 91 for (i=0; i<8; i++) 92 { 93 if (crc & 0x01) 94 { 95 crc >>= 1; 96 crc ^= 0xA001; 97 } 98 else 99 { 100 crc >>= 1; 101 } 102 } 103 } 104 if (crc == crcCode) 105 { 106 Serial.println("CRC checked."); 107 } 108 else 109 { 110 Serial.println("CRC Error!"); 111 } 112 }
器件介绍、电路连接可参见之前的日志。
使用Arduino Wire Library读取温湿度传感器AM2321
标签:
原文地址:http://www.cnblogs.com/zlbg/p/4510447.html