-
-
Save blackcj/463e22654c4c708a1279 to your computer and use it in GitHub Desktop.
HTU21D Spark Core files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
HTU21D Humidity Sensor Library | |
By: Nathan Seidle | |
SparkFun Electronics | |
Date: September 22nd, 2013 | |
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). | |
This library allows an Arduino to read from the HTU21D low-cost high-precision humidity sensor. | |
If you have feature suggestions or need support please use the github support page: https://github.com/sparkfun/HTU21D | |
Hardware Setup: The HTU21D lives on the I2C bus. Attach the SDA pin to A4, SCL to A5. If you are using the SparkFun | |
breakout board you *do not* need 4.7k pull-up resistors on the bus (they are built-in). | |
Link to the breakout board product: | |
Software: | |
Call HTU21D.Begin() in setup. | |
HTU21D.ReadHumidity() will return a float containing the humidity. Ex: 54.7 | |
HTU21D.ReadTemperature() will return a float containing the temperature in Celsius. Ex: 24.1 | |
HTU21D.SetResolution(byte: 0b.76543210) sets the resolution of the readings. | |
HTU21D.check_crc(message, check_value) verifies the 8-bit CRC generated by the sensor | |
HTU21D.read_user_register() returns the user register. Used to set resolution. | |
*/ | |
#include "HTU21D.h" | |
HTU21D::HTU21D() | |
{ | |
//Set initial values for private vars | |
} | |
//Begin | |
/*******************************************************************************************/ | |
//Start I2C communication | |
bool HTU21D::begin(void) | |
{ | |
Wire.begin(); | |
} | |
//Read the humidity | |
/*******************************************************************************************/ | |
//Calc humidity and return it to the user | |
//Returns 998 if I2C timed out | |
//Returns 999 if CRC is wrong | |
float HTU21D::readHumidity(void) | |
{ | |
//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); | |
//Comes back in three bytes, data(MSB) / data(LSB) / Checksum | |
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 | |
} | |
byte msb, lsb, checksum; | |
msb = Wire.read(); | |
lsb = Wire.read(); | |
checksum = Wire.read(); | |
/* //Used for testing | |
byte msb, lsb, checksum; | |
msb = 0x4E; | |
lsb = 0x85; | |
checksum = 0x6B;*/ | |
unsigned int rawHumidity = ((unsigned int) msb << 8) | (unsigned int) lsb; | |
if(check_crc(rawHumidity, checksum) != 0) return(999); //Error out | |
//sensorStatus = rawHumidity & 0x0003; //Grab only the right two bits | |
rawHumidity &= 0xFFFC; //Zero out the status bits but keep them in place | |
//Given the raw humidity data, calculate the actual relative humidity | |
float tempRH = rawHumidity / (float)65536; //2^16 = 65536 | |
float rh = -6 + (125 * tempRH); //From page 14 | |
return(rh); | |
} | |
//Read the temperature | |
/*******************************************************************************************/ | |
//Calc temperature and return it to the user | |
//Returns 998 if I2C timed out | |
//Returns 999 if CRC is wrong | |
float HTU21D::readTemperature(void) | |
{ | |
//Request the temperature | |
Wire.beginTransmission(HTDU21D_ADDRESS); | |
Wire.write(TRIGGER_TEMP_MEASURE_NOHOLD); | |
Wire.endTransmission(); | |
//Hang out while measurement is taken. 50mS max, page 4 of datasheet. | |
delay(55); | |
//Comes back in three bytes, data(MSB) / data(LSB) / Checksum | |
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, checksum; | |
msb = Wire.read(); | |
lsb = Wire.read(); | |
checksum = Wire.read(); | |
/* //Used for testing | |
byte msb, lsb, checksum; | |
msb = 0x68; | |
lsb = 0x3A; | |
checksum = 0x7C; */ | |
unsigned int rawTemperature = ((unsigned int) msb << 8) | (unsigned int) lsb; | |
if(check_crc(rawTemperature, checksum) != 0) return(999); //Error out | |
//sensorStatus = rawTemperature & 0x0003; //Grab only the right two bits | |
rawTemperature &= 0xFFFC; //Zero out the status bits but keep them in place | |
//Given the raw temperature data, calculate the actual temperature | |
float tempTemperature = rawTemperature / (float)65536; //2^16 = 65536 | |
float realTemperature = -46.85 + (175.72 * tempTemperature); //From page 14 | |
return(realTemperature); | |
} | |
//Set sensor resolution | |
/*******************************************************************************************/ | |
//Sets the sensor resolution to one of four levels | |
//Page 12: | |
// 0/0 = 12bit RH, 14bit Temp | |
// 0/1 = 8bit RH, 12bit Temp | |
// 1/0 = 10bit RH, 13bit Temp | |
// 1/1 = 11bit RH, 11bit Temp | |
//Power on default is 0/0 | |
void HTU21D::setResolution(byte resolution) | |
{ | |
byte userRegister = read_user_register(); //Go get the current register state | |
userRegister &= 0b01111110; //Turn off the resolution bits | |
resolution &= 0b10000001; //Turn off all other bits but resolution bits | |
userRegister |= resolution; //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 the new resolution bits | |
Wire.endTransmission(); | |
} | |
//Read the user register | |
byte HTU21D::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); | |
} | |
//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 | |
byte HTU21D::check_crc(uint16_t message_from_sensor, uint8_t check_value_from_sensor) | |
{ | |
//Test cases from datasheet: | |
//message = 0xDC, checkvalue is 0x79 | |
//message = 0x683A, checkvalue is 0x7C | |
//message = 0x4E85, checkvalue is 0x6B | |
uint32_t remainder = (uint32_t)message_from_sensor << 8; //Pad with 8 bits because we have to add in the 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 (byte)remainder; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
HTU21D Humidity Sensor Library | |
By: Nathan Seidle | |
SparkFun Electronics | |
Date: September 22nd, 2013 | |
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). | |
Get humidity and temperature from the HTU21D sensor. | |
*/ | |
#if defined(ARDUINO) && ARDUINO >= 100 | |
#include "Arduino.h" | |
#else | |
#include "application.h" | |
#endif | |
#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 | |
class HTU21D { | |
public: | |
HTU21D(); | |
//Public Functions | |
bool begin(); | |
float readHumidity(void); | |
float readTemperature(void); | |
void setResolution(byte resBits); | |
//Public Variables | |
private: | |
//Private Functions | |
byte read_user_register(void); | |
byte check_crc(uint16_t message_from_sensor, uint8_t check_value_from_sensor); | |
//Private Variables | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This #include statement was automatically added by the Spark IDE. | |
/* | |
HTU21D Humidity Sensor Example Code | |
By: Nathan Seidle | |
SparkFun Electronics | |
Date: September 15th, 2013 | |
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license). | |
Uses the HTU21D library to display the current humidity and temperature | |
Open serial monitor at 9600 baud to see readings. Errors 998 if not sensor is detected. Error 999 if CRC is bad. | |
Hardware Connections (Breakoutboard to Arduino): | |
-VCC = 3.3V | |
-GND = GND | |
-SDA = A4 (use inline 330 ohm resistor if your board is 5V) | |
-SCL = A5 (use inline 330 ohm resistor if your board is 5V) | |
*/ | |
#include "HTU21D.h" | |
//Create an instance of the object | |
HTU21D myHumidity; | |
char resultstr[128]; | |
void setup() | |
{ | |
myHumidity.begin(); | |
// expose your char buffer to the Cloud API | |
Spark.variable("result", &resultstr, STRING); | |
} | |
void loop() | |
{ | |
float humd = myHumidity.readHumidity(); | |
float temp = myHumidity.readTemperature() * 9 / 5 + 32; | |
sprintf(resultstr, "{\"data1\":%f,\"data2\":%f}", humd, temp); | |
delay(30000); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment