目的:
HTU21D湿度/温度 センサーはIIC ポートを搭載、入力電圧は3.3Vとなります。このプロジェクトでは、Arduinoボードを使用して、
センサーからの湿度/温度データを獲得し、 ArduinoIDEのserial モニター窓に表示します。
必要なパーツ:
Arduino UNO R3ボード x 1
USB ケーブルx 1
Breadboardとjumper wires
HTU21D センサーx 1
10k ohm 抵抗x 1
Circuit Graph:
サンプルコード:
#include
#define HTDU21D_ADDRESS 0x40 //Unshifted 7-bit I2C address for the sensor
#define TRIGGER_TEMP_MEASURE_HOLD 0xE3
#define TRIGGER_HUMD_MEASURE_HOLD 0xE5
#define TRIGGER_TEMP_MEASURE_NOHOLD 0xF3
#define TRIGGER_HUMD_MEASURE_NOHOLD 0xF5
#define WRITE_USER_REG 0xE6
#define READ_USER_REG 0xE7
#define SOFT_RESET 0xFE
byte sensorStatus;
void setup()
{
Serial.begin(9600);
Serial.println(“HTU21D Example!”);
Wire.begin();
}
void loop()
{
unsigned int rawHumidity = htdu21d_readHumidity();
unsigned int rawTemperature = htdu21d_readTemp();
float temperature = calc_temp(rawTemperature);
float relativeHumidity = calc_humidity(rawHumidity); //Turn the humidity signal into actual humidity
Serial.print(“Temperature: “);
Serial.print(temperature, 1);
Serial.print(” C”);
Serial.print(” Relative Humidity: “);
Serial.print(relativeHumidity, 1);
Serial.print(” %”);
Serial.println();
delay(1000);
}
//Read the uncompensated temperature value
unsigned int htdu21d_readTemp()
{
//Request the temperature
Wire.beginTransmission(HTDU21D_ADDRESS);
Wire.write(TRIGGER_TEMP_MEASURE_NOHOLD);
Wire.endTransmission();
//Wait for sensor to complete measurement
delay(60); //44-50 ms max – we could also poll the sensor
//Comes back in three bytes, data(MSB) / data(LSB) / CRC
Wire.requestFrom(HTDU21D_ADDRESS, 3);
//Wait for data to become available
int counter = 0;
while(Wire.available() < 3)
{
counter++;
delay(1);
if(counter > 100) return 998; //Error out
}
unsigned char msb, lsb, crc;
msb = Wire.read();
lsb = Wire.read();
crc = Wire.read(); //We don’t do anything with CRC for now
unsigned int temperature = ((unsigned int)msb << 8) | lsb;
temperature &= 0xFFFC; //Zero out the status bits but keep them in place
return temperature;
}
//Read the humidity
unsigned int htdu21d_readHumidity()
{
byte msb, lsb, checksum;
//Request a humidity reading
Wire.beginTransmission(HTDU21D_ADDRESS);
Wire.write(TRIGGER_HUMD_MEASURE_NOHOLD); //Measure humidity with no bus holding
Wire.endTransmission();
//Hang out while measurement is taken. 50mS max, page 4 of datasheet.
delay(55);
//Read result
Wire.requestFrom(HTDU21D_ADDRESS, 3);
//Wait for data to become available
int counter = 0;
while(Wire.available() < 3)
{
counter++;
delay(1);
if(counter > 100) return 0; //Error out
}
msb = Wire.read();
lsb = Wire.read();
checksum = Wire.read();
unsigned int rawHumidity = ((unsigned int) msb << 8) | (unsigned int) lsb;
rawHumidity &= 0xFFFC; //Zero out the status bits but keep them in place
return(rawHumidity);
}
//Given the raw temperature data, calculate the actual temperature
float calc_temp(int SigTemp)
{
float tempSigTemp = SigTemp / (float)65536; //2^16 = 65536
float realTemperature = -46.85 + (175.72 * tempSigTemp); //From page 14
return(realTemperature);
}
//Given the raw humidity data, calculate the actual relative humidity
float calc_humidity(int SigRH)
{
float tempSigRH = SigRH / (float)65536; //2^16 = 65536
float rh = -6 + (125 * tempSigRH); //From page 14
return(rh);
}
//Read the user register
byte read_user_register(void)
{
byte userRegister;
//Request the user register
Wire.beginTransmission(HTDU21D_ADDRESS);
Wire.write(READ_USER_REG); //Read the user register
Wire.endTransmission();
//Read result
Wire.requestFrom(HTDU21D_ADDRESS, 1);
userRegister = Wire.read();
return(userRegister);
}
//Write to the user register
//NOTE: We disable all bits except for measurement resolution
//Bit 7 & 0 = Measurement resolution
//Bit 6 = Status of battery
//Bit 5/4/3 = Reserved
//Bit 2 = Enable on-board heater
//Bit 1 = Disable OTP reload
void write_user_register(byte thing_to_write)
{
byte userRegister = read_user_register(); //Go get the current register state
userRegister &= 0b01111110; //Turn off the resolution bits
thing_to_write &= 0b10000001; //Turn off all other bits but resolution bits
userRegister |= thing_to_write; //Mask in the requested resolution bits
//Request a write to user register
Wire.beginTransmission(HTDU21D_ADDRESS);
Wire.write(WRITE_USER_REG); //Write to the user register
Wire.write(userRegister); //Write to the data
Wire.endTransmission();
}
//Give this function the 2 byte message (measurement) and the check_value byte from the HTU21D
//If it returns 0, then the transmission was good
//If it returns something other than 0, then the communication was corrupted
//From: http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html
//POLYNOMIAL = 0x0131 = x^8 + x^5 + x^4 + 1 : http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks
#define SHIFTED_DIVISOR 0x988000 //This is the 0x0131 polynomial shifted to farthest left of three bytes
unsigned int check_crc(uint16_t message_from_sensor, uint8_t check_value_from_sensor)
{
//Test cases from datasheet:
//message = 0xDC, result is 0x79
//message = 0x683A, result is 0x7C
//message = 0x4E85, result is 0x6B
uint32_t remainder = (uint32_t)message_from_sensor << 8; //Pad with 8 bits because we have to add in the result/check value
remainder |= check_value_from_sensor; //Add on the check value
uint32_t divsor = (uint32_t)SHIFTED_DIVISOR;
for (int i = 0 ; i < 16 ; i++) //Operate on only 16 positions of max 24. The remaining 8 are our remainder and should be zero when we're done.
{
//Serial.print(“remainder: “);
//Serial.println(remainder, BIN);
//Serial.print(“divsor: “);
//Serial.println(divsor, BIN);
//Serial.println();
if( remainder & (uint32_t)1<<(23 - i) ) //Check if there is a one in the left position
remainder ^= divsor;
divsor >>= 1; //Rotate the divsor max 16 times so that we have 8 bits left of a remainder
}
return remainder;
}
結果:
Arduino IDEのserial モニターを開けて、 周囲環境の温度と湿度データが表示します:
センサーを火焰に近づいてくると温度数値は高くなります:
DownLoad Url osoyoo.com