HDC1000 temperature and humidity sensor breakout, with Arduino library!
Some time ago I came across a new chip from TI, the HDC1000. It’s a temperature and humidity sensor with I2C interface and requires little to no additional components. It comes in an 8BGA package: we can all agree it’s pretty small.
Some of the peculiar characteristics of this chip are that it has a DRDYn pin which goes low any time there is a new reading from the chip (so you can precisely time your requests) and that the sensor is located on the bottom of the IC, so that it’s not exposed to dust and other agents that may false the readings. Also, it has an integrated heater that can remove humidity from the sensor.
So I developed a very small breakout board for this chip as well as an Arduino library (yay, my first one! raspberryPi and nodemcu might come next).
The breakout boards.
I learned quite a lot about PCB design and soldering, effectively putting my new hot air station to good use.
The boards were again fulfilled by DirtyPCBs, perfect for this kind of small projects.
So here are the pictures of my board…
..and here are the features:
- Address selection jumpers: ADR0 and ADR1 are tied to GND by default but you can jump them to VCC in order to change the address of your sensor (default:0x40).
- I2C pull-ups to VCC for SDA, SCL and DRDYn. If you don’t want to use the latter, just don’t solder the resistor and leave it floating.
- 3-5V input, logic 5V tolerant (3.3V recommended).
Parts list:
- IC1: HDC1000 sensor, you can’t really go wrong with the package since, sadly, it’s the only one.
- R1,R2: 4.7k-10k ohm, 0805 package. I2C pull-up resistors.
- R3: 10k ohm, 0805 package. Pull-up resistor to VCC, for the DRDYN pin. Leave the pin floating if not used.
- R4, R5: 10k ohm, pull-down resistors to GND for address selection.
- C1: 0.1uF cap, 0805 package.
- JP1: 0.1″, 5-pin headers.
The board is 1.6×1.6 centimeters, and soldering that BGA chip (1.6×2 millimeters) wasn’t really that hard! I actually struggled more with the resistors, maybe because I used my ugly and huge 60W iron.
Here’s what I found works best:
- Solder the components in this order: resistors, IC, capacitor (on the back of the board), pin headers. If you do it any other way you will have trouble balancing the board, I found it the hard way.
- Apply a small quantity of flux on the pads (not on the middle of them, as it’s where the sensor lies..) – I used a flux pen.
- Place the IC on the pads without pre-tinning anything, and fire up your heatgun.
- If you aligned the chip correctly it will begin to stick to the pads by itself and you shouldn’t have to touch it anymore.
Of course you can do this with a reflow oven but using an hot-air gun it took me less than 3 minutes, for just the IC. You can’t solder this with a regular iron.
Note: the breakout boards should also be compatible with the HDC1008, but I haven’t tested it yet.
Now the best part…
The Arduino library.
Yesterday was a firsts day! (is this even remotely correct?) I soldered my first BGA and wrote my first Arduino library. I don’t think it’s quality code (there could be a lot to improve – should you feel compelled to do so, it’s on Github) but I tried to learn from both tutorials on the Arduino website and other libraries written by Ladyada and Seeedstudio.
How it works:
Just download (click!) and #include the library, declare your HDC1000 object and call the begin() function.
#include <Wire.h>
#include <HDC1000.h>
HDC1000 mySensor;
void setup(){
mySensor.begin();
}
By default, the library is configured to enable both temperature and humidity readings, at 14-bit resolution, with the heater on. Also, the default address is 0x40. Should you want to change these features, you can declare your object like this (all the possible options are in the .h file – also check out the datasheet):
UPDATE 07/03/15: You can now use the DRDYn pin, which is pulled low by the chip itself when a new measurement is ready. It is off by default (drdyn_pin is set to -1).
HDC1000 mySensor(addr, drdyn_pin);
void setup(){
mySensor.begin(HDC1000_BOTH_TEMP_HUMI, HDC1000_TEMP_11BIT, HDC1000_HEAT_OFF);
}
By default, the sensor outputs temperature and humidity readings in a 14-bit format. Fortunately, the library automagically converts them into Celsius degrees (sorry, Americans!) and %. You can access them like this:
double temperature = mySensor.getTemp();
double humidity = mySensor.getHumi();
You can also access raw values using the getRawTemp() and getRawHumi() methods (which return uint16_t values).
One nifty feature of the HDC1000 is that it can detect if the battery that’s powering it is nearly flat.
uint8_t dead = mySensor.battery(); //returns 1 if voltage < 2.8V, 0 otherwise.
The more tech-savvy of you can also read the registers’ configuration:
uint16_t config = mySensor.readConfig(); //returns a 16-bit value: last 8 bits are always zero and leading zeros are not displayed
Full, super-basic sketch:
#include <Wire.h>
#include <HDC1000.h>
HDC1000 mySensor;
//HDC1000 mySensor(addr, drdyn_pin) <--- you can change default options if you want.
void setup(){
Serial.begin(9600);
mySensor.begin();
}
void loop(){
Serial.print("Temperature: "); //too bad the Arduino version of sprintf
Serial.print(mySensor.getTemp()); //doesn't support floats,
Serial.print("C, Humidity: "); //I hate Serial.print().
Serial.print(mySensor.getHumi());
Serial.println("%");
delay(1000);
}
Sadly, I haven’t implemented the DRDYn pin yet, so I’m using a 20ms delay before reading the next value. I know that you can get the two readings at once (I send two separate requests to the chip) but I felt that there was no need to add another function to the library since you’d have to call two of them anyway.
As usual, leftovers (PCBs only!) are available in the store and on Tindie as soon as I get them approved. Design files on Github.
Let me know what you think – happy making!