使用Arduino Wire Library讀取溫濕度傳感器AM2321


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 <--------->  5V
  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 }
View Code

器件介紹、電路連接可參見之前的日志


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM