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.
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); } }