HTU21D NeoPixel Ring Temperature and Humidity Display

Integrating the HTU21D humidity and temperature sensor into a project is straightforward. For this project, the HTU21D’s sensor results will be displayed with a single Adafruit 24 NeoPixel Ring. Both temperature and humidity results will be displayed simultaneously.

HTU21D and NeoPixel Ring

NeoPixels have a digital interface that require strict timing. Fortunately, Adafruit provides a library  which handles the protocol and timing for you. All you need to do is, specify the digital output that your NeoPixels is connected to and the number of NeoPixels in your string of LEDs.

The connections to interface the Arduino and HTU21D are:

Arduino HTU21D
VCC VIN
GND GND
A4 (SDA) SDA
A5 (SCL) SCL

And, for the Arduino and NeoPixel ring:

Arduino NeoPixels
VCC PWR
GND GND
D6 IN

Note, if you are planing to drive your NeoPixel ring at full brightness (which is hurt your eyes bright) you will need to consider using a separate power supply. At full brightness each NeoPixel LED can draw 60mA, so driving a 24 NeoPixel ring will draw about 1.44A! You’ve been warned.

For this example, to display temperature and humidity together, each reading type is going to be assigned their own colour. Temperature results will be assigned red and humidity readings will be blue. You are more than welcome to change these to what ever you please.

Since there are only 24 LEDs, the measurement ranges will need to be set. Relative Humidity (%RH) is measured from 0 – 100%, this can be closely divided into 24 LEDs with each LED representing ~4%RH (remember the HTU21D has an accuracy of about 3%RH anyway.) As for temperature,  we’ll make 1x LED equal 1 degree celcius. This will allow for 25 temperature intervals to be shown (remember no LEDs on is an interval). For me, I’ll set my temperature range from 12 – 36C.

Since both temperature and humidity will be displayed together, most of the time both scaled readings will not be at the same position on the NeoPixel ring. When this occurs, the two colours blend together making the “low” measurement difficult to discern. To compensate for this, code has been added that provides a boost to these LEDs and increases their brightness so their original colour can still be discerned.

 

To implement a NeoPixel Ring into your next project, get a copy of the Adafruit NeoPixel  library and use the code below. Use the provided code as a starting point and make it better. Perhaps, use the green LEDs to display the dew point?


//Code to display temperatuer and humidity readings on a NeoPixel ring.
//Sensor to perform measurements is a HTU21D sensor.
//This example uses a 24LED NeoPixel ring.
//Temperature and Humidity results are spat out of hte serial terminal too for diagnostics and sanity checking.
//
//This demo requries the use of the Adafruit NeoPixel library
//
//Tim Hansen 2015 - www.steelcityelectronics.com
#include <Wire.h>
#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

// Which pin on the Arduino is connected to the NeoPixels?
// On a Trinket or Gemma we suggest changing this to 1
#define PIN 6

// How many NeoPixels are attached to the Arduino?
#define NUMPIXELS 24
byte TempHi; // Variable hold the Temp data high byte
byte TempLo; // Variable hold the Temp data low byte
byte HumidHi; // Variable to hold the Humidity data HIGH byte
byte HumidLo; // Variable to hold the humidity data LOW byte
byte CRC; // Variable to hold the CRC checksum
byte TempScaled; //Variable to hold the scaled temerpature valeu
byte TempMin;
byte TempMax;
byte HumidityScaled;

byte const BaseBrightness = 10; //Set the brightness of the LEDs. The highest measurement reading will display this brightness
byte const ColourBoost = 20; //The lower measuremetn reading needs to be 'boosted' otherwise it gets swamped by the the other higher reading.

int Temperature;
long Humidity; //int is too small
float TemperatureFL;
float HumidityFL;

// When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
// Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
// example for more information on possible values.
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int delayval = 50; // delay for a moment
void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
Serial.begin(9600); // start serial for output
pinMode(13, OUTPUT);

pixels.begin(); // This initializes the NeoPixel library.
}

void loop()
{
const int I2C_address = 0x40; // I2C write address - the device has an address of 0x40.

delay(100);

while (1)
{
delay(10);

// Read the temperature value
Wire.beginTransmission(I2C_address);
Wire.write(0xE3); // request temp measurement
Wire.endTransmission();

Wire.requestFrom(I2C_address, 3);
while(Wire.available()) // Check for data from slave
{
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
TempHi = Wire.read(); // Read temperature high byte
TempLo = Wire.read(); // Read temperature low byte
CRC = Wire.read(); //Read the CRC byte
}

// Read the humidty value
Wire.beginTransmission(I2C_address);
Wire.write(0xE5); // request humidity measurement
Wire.endTransmission();

Wire.requestFrom(I2C_address, 3);
while(Wire.available()) // Check for data from slave
{
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)
HumidHi = Wire.read(); // Read temperature high byte
HumidLo = Wire.read(); // Read temperature low byte
CRC = Wire.read(); //Read the CRC byte
}


Temperature = int(TempHi);
Temperature = Temperature <<8;
Temperature = Temperature + int(TempLo);
TemperatureFL = -46.85 + 175.72*(Temperature/pow(2, 16));
Serial.print("Temperature:");
Serial.print(char(TemperatureFL), DEC);
Serial.print("\t");
Humidity = long(HumidHi);
Humidity = Humidity <<8;
Humidity = Humidity + long(HumidLo);
HumidityFL = -6 + 125*(Humidity/pow(2, 16));
Serial.print("Humidity:");
Serial.println(char(HumidityFL), DEC);

//scale temperature
//temp range is 12C to 36C
TempMin = 12;
TempMax = TempMin + 24; //think about a better way to do this for smaller neopixel products

TempScaled = byte(TemperatureFL);
TempScaled = TempScaled - TempMin;

HumidityScaled = byte(HumidityFL)>>2; //divide by 4
//drive the neopixel ring
for(int i=0;i<NUMPIXELS;i++)
{
if(i<= TempScaled)
{
if(i<= HumidityScaled)
{ //Set the temperature and humidity coloured pixel
//pixels.setPixelColor(i, pixels.Color(10,0,10)); //temperature pixels are red, humidity pixels are blue
if(TempScaled == HumidityScaled)
{
pixels.setPixelColor(i, pixels.Color(BaseBrightness,0,BaseBrightness)); //temperature pixels are red, humidity pixels are blue
}
else if(TempScaled >= HumidityScaled) //boost the humidity pixels so they can be seen more easily
{
pixels.setPixelColor(i, pixels.Color(BaseBrightness,0,BaseBrightness + ColourBoost)); //temperature pixels are red, humidity pixels are blue
}
else //Boost the temperature pixels so they are more easily seen
{
pixels.setPixelColor(i, pixels.Color(BaseBrightness + ColourBoost,0,BaseBrightness)); //temperature pixels are red, humidity pixels are blue
}

}
else
{ //Set the temperature coloured pixel, but the humidity pixel is off
pixels.setPixelColor(i, pixels.Color(BaseBrightness,0,0)); //temperature pixels are red, humidity pixels are OFF
}
}

else
{
if(i<= HumidityScaled)
{ //Set the humidity coloured pixel but not the temperature
pixels.setPixelColor(i, pixels.Color(0,0,BaseBrightness)); //temperature pixels are OFF, humidity pixels are blue
}
else
{ //Both the temperature and humidty pixel is off
pixels.setPixelColor(i, pixels.Color(0,0,0)); //temperature pixels are OFF, humidity pixels are OFF
}
}

pixels.show(); // This sends the updated pixel color to the hardware.

delay(delayval); // Delay for a period of time (in milliseconds).
}

digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level)

delay(10);
}
}

Share your thoughts

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s