1.
Part Description |
Amazon.com |
---|---|
Arduino Uno | Arduino Uno R3 with Atmega 328P |
Arduino Ethernet Shield | Arduino Ethernet Shield R3 |
DHT11 Temperature and Humidity Sensor | DHT11 Digital Temp Sensor 4 Pack |
1x 10k Ohm resistor | 860 Piece 1/4W 86 Value Resistor Kit |
Jumper Wires | 60 Piece Jumper Wire Kit |
Bread Board | Tektrum 2200 Tie-Point Breadboard |
2x 5V 2A Power Source | USTEK 5V 2A Wall Adapter |
Ethernet Cable | Amazon Basics 14' Etherthet Cable |
1000 µF, 25V Capacitor | 50pc 1000uF 25V Electrolytic Capacitors |
Female DC Power adapter
|
10pc Female Power Jack Adapter |
Tool Description |
Download Link |
---|---|
Arduino IDE | Download from Arduino.cc |
FastLED Arduino Library | Download from Fastled.io |
DHT Arduino Library | Download from Github |
Over the last few months I have became infatuated with individually addressable RGB LED strips known as NeoPixels, and their WS2012b generic flavor. I have incorporated them into a product for a business I own, as well as my new custom gaming PC build. I simply can not get over how easy it is to integrate these into projects of every flavor.
A few days ago, I started working on a environment temperature monitoring project that I wanted to turn into a tutorial here at TMWB, and half way through, I decided to integrate NeoPixels as a sort of basic visual aid. Basically I wanted the NeoPixels to change color based on a hot / cold threshold. While this is simple in function, it will give users an easy way to determine if a room is warm or cool. You could simply modify the code with more “if” statements to add in more colors and temperature breakpoints. You will need to download and install the Arduino Libraries listed below. If you need more information on installing libraries in Arduino, check out this turorial by Adafruit.
Arduino Libraries Needed: (Click to download)
Download the code for this project from Github:
Wiring up the circuit:
Follow the breadboard schematic pictured above (click to make it larger), and make the following connections.
DHT11 Pin 1 - Arduino VCC
DHT Pin 2 - Arduino Digital Pin 2
10k Resistor Pin 1 - Arduino VCC
10k Resistor Pin 2 - DHT11 Pin 2
DHT11 Pin 3 - No Contact
DHT11 Pin 4 - Arduino Gnd
Arduino 5V - Breadboard VCC Rail 1
Arduino GND - Breadboard Gnd Rail 1
NeoPixel DIN - Arduino Digital Pin 6
NeoPixel 5V - Breadboard VCC Rail 2
NeoPixel GND - Breadboard GND Rail 2
Breadboard GND Rail 1 - Breadboard GND Rail 2
Barrel Jack VCC - Breadboard VCC Rail 2
Barrel Jack GND - Breadboard GND Rail 2
Capacitor + Pin - Breadboard VCC Rail 2
Capacitor GND Pin - Breadboard GND Rail 2
With those connections wired up you simply need to give the arduino a 5V power source, connect the USB cable, and plug in the ethernet cable to finish things up. Before we move on to the code, I want to explain why I am using an external 5V source to power the NeoPixels. Usually a normal Arduino Uno will have enough current to power a 30-pixel strip of NeoPixels, but with the Ethernet Shield stacked on top, the Arduino has very little current left to pass around. My Arduino was actually dropping out when the pixels changed from red to blue due to this. So adding in the external 5V source and the big filtering capacitor (as recommended by Adafruit) eliminated the issues.
The Code:
Im going to break the code down in pieces here so that it is easier for some to understand. Lets get started with the Variable Declaration Section. This is where we tell the Arduino IDE to include the libraries we will be using as well as declaring the variables we will be using in our program.
You will notice that we will need several libraries in order for our program to function correctly. We will use the SPI library to allow our program to communicate over ethernet via the serial bus. The Ethernet library will allow us to easily use the Ethernet shield, while the FastLED library will allow the Arduino to send SPI commands to the NeoPixel strip. Finally the DHT library will allow us to easily access the data that the DHT11 sensor is outputting.
#include <SPI.h> #include <Ethernet.h> #include <FastLED.h> #include <DHT.h>
Now we need to define the variables for the DHT11 Sensor:
Setup the DHT Sensor:
We will define what Arduino Pin the DHT signal pin is connected to. We will also have to define what type of DHT sensor we are using. In this case it is a DHT11.
#define DHTPIN 2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE);
With the sensor setup we need to get the NeoPixel’s declared in the program.
We will need to define how many LEDs (Pixels) there are in the strip as well as which Arduino Pin the NeoPixel's data pin is connected too. We will also need to define the array of the leds.
#define NUM_LEDS 7 #define DATA_PIN 6 CRGB leds[NUM_LEDS];
Finally we need to define the variables for the ethernet shield.
We will first need to enter a MAC address and IP address for the ethernet shield we are using.
The MAC address is found on the back of your ethernet shield (Use this default MAC if your shield does not specify one.
IP address dependent upon your network addresses. (Typically this will look like 192.168.1.177)
Finally we will need to initialize the Ethernet server library with the IP address and which port you would like to use. Default is port 80 for HTTP.
byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x23, 0x36 }; IPAddress ip(10,10,1,177); EthernetServer server(80);
With the program’s variables declared, lets move onto the programs setup section.
The first thing we will need to do is open serial communications and tell the Arduino to wait for the serial port to open.
void setup() { Serial.begin(9600); while (!Serial) { ; }
Then we need to tell the DHT sensor to begin recording and relaying data back to the Arduino.
dht.begin(); //Initalize the DHT11 sensor.
With those two task taken care of, we need to allow the ethernet shield to begin talking to our network.
The first thing we need to do is start the Ethernet connection, and initialize the server.
Then we will need to tell the Arduino to print some help text via serial.
Finally we need to initialize our NeoPixel strip.
Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at ") Serial.println(Ethernet.localIP()); FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); }
With our programs variables defined, and the setup taken care of, we can now move onto the loop. Reading temperature or humidity takes about 250 milliseconds! Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
void loop() { float h = dht.readHumidity(); float t = dht.readTemperature();
This checks if returns are valid, if they are NaN (not a number) then something went wrong!
if (isnan(t) || isnan(h)) { Serial.println("Failed to read from DHT"); } else { Serial.print("Humidity: "); Serial.print(h); Serial.print(" %\t"); Serial.print("Temperature: "); Serial.print(t); Serial.println(" *C"); }
This code tells the Ethernet Shield to listen for incoming clients
EthernetClient client = server.available(); if (client) { Serial.println("new client"); boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c);
This tell the Arduino that if it has gotten to the end of the line (received a newlinecharacter) and the line is blank, the http request has ended, so you can send a reply. The Arduino will refresh the connection 5 times.
if (c == '\n' && currentLineIsBlank) { client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println("Refresh: 5"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>");
This block of code outputs the value of the DHT-11 to the webpage located at the IP address you set up in the beginning of this sketch.
client.println("<H2>"); client.print("Humidity: "); client.println("</H2>"); client.println("<p />"); client.println("<H1>"); client.print(h); client.print(" %\t"); client.println("</H1>"); client.println("<p />"); client.println("<H2>"); client.print("Temperature: "); client.println("</H2>"); client.println("<H1>"); client.print(t*1.8+32); client.println(" °"); client.println("F"); client.println("</H1>"); client.println("</html>"); break; }
This block of code starts a new line if c equals \n, and if c does not equal \n, it does not strart a new line.
if (c == '\n') { currentLineIsBlank = true; } else if (c != '\r') currentLineIsBlank = false; } } }
Here we give the web browser time to receive the data, and then close the connection.
delay(1); client.stop(); Serial.println("client disonnected"); }
This block of code sets the NeoPixel's color based on the temperature of the room. Note that the temperature is in degrees celcius and not ferienheight.
This if statement sets the NeoPixel's color to Blue if the temperature is less than or equal to 23.66C (74.5F)
if (t <= 23.66) {fill_solid( &(leds[0]), NUM_LEDS, CRGB::Blue); FastLED.show(); }
This else statement sets the NeoPixel's color to red if the temperature is above 23.66C (74.5fF)
else { fill_solid( &(leds[0]), NUM_LEDS, CRGB::Red); FastLED.show(); } }
Putting everything together, the code should look like this:
//This code uses a DHT11 Digital Temperature and Humidity sensor //and reports back the temperature of the room as well as the //humidity to a website. At the same time it utilizes a strip of //NeoPixel LED's to indicate whether or not the //room is warm or cool. // Portions of this code were written by Charles Gantt, //Curtis Gauger, and the original (unknown) of //the basic DHT code example. // This code is released under the //Creative Commons Attribution-ShareAlike 4.0 International //CC BY-SA 4.0) License //(http://creativecommons.org/licenses/by-sa/4.0/) //We will use the SPI library to allow our program to communicate //over ethernet via the serial bus. #include <SPI.h> //The Ethernet library will allow us to easily //use the Ethernet shield #include <Ethernet.h> //The FastLED library will allow the Arduino to send SPI commands //to the NeoPixel strip (Download at http://www.http://fastled.io/) #include <FastLED.h> //The DHT library will allow us to easily access the data that the //DHT11 sensor is outputting //(Download at https://github.com/adafruit/DHT-sensor-library) #include <DHT.h> // Setup the DHT Sensor #define DHTPIN 2 // what pin we're connected to // Defines what model of DHT Sensor we are using, in this case a DHT11 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); //Setup the NeoPixel Strip // How many leds in your strip? #define NUM_LEDS 7 // What pin is the NeoPixel's data line connected to? #define DATA_PIN 6 CRGB leds[NUM_LEDS]; // Define the array of leds //Setup the Ethernet Shield // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: //MAC address found on the back of your ethernet shield //(Use this default MAC if your shield does not specify one byte mac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x23, 0x36 }; // IP address dependent upon your network addresses. //(Typically this will look like 192.168.1.177) IPAddress ip(10,10,1,177); // Initialize the Ethernet server library // with the IP address and port you want to use // (port 80 is default for HTTP): EthernetServer server(80); void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. } dht.begin(); //Initalize the DHT11 sensor. // start the Ethernet connection and the server: Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS); } void loop() { // Reading temperature or humidity takes about 250 milliseconds! // Sensor readings may also be up to //2 seconds 'old' (its a very slow sensor) float h = dht.readHumidity(); float t = dht.readTemperature(); // check if returns are valid //If they are NaN (not a number) then something went wrong! if (isnan(t) || isnan(h)) { Serial.println("Failed to read from DHT"); } else { Serial.print("Humidity: "); Serial.print(h);% Serial.print(" %\t"); Serial.print("Temperature: "); Serial.print(t); Serial.println(" *C"); } // listen for incoming clients EthernetClient client = server.available(); if (client) { Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); // the connection will be closed after completion of the response client.println("Connection: close"); // refresh the page automatically every 5 sec client.println("Refresh: 5"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); // output the value of the DHT-11 client.println("<H2>"); client.print("Humidity: "); client.println("</H2>"); client.println("<p />"); client.println("<H1>"); client.print(h); client.print(" %\t"); client.println("</H1>"); client.println("<p />"); client.println("<H2>"); client.print("Temperature: "); client.println("</H2>"); client.println("<H1>"); client.print(t*1.8+32); client.println(" °"); client.println("F"); client.println("</H1>"); client.println("</html>"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(1); // close the connection: client.stop(); Serial.println("client disonnected"); } //This sets the NeoPixel's color based on the //temperature of the room. //Note that the temperature is in degrees celcius //and not ferienheight. // This if statement sets the NeoPixel's color to Blue //if the temperature is less than or equal to 23.66C (74.5F) if (t <= 23.66) {fill_solid( &(leds[0]), NUM_LEDS , CRGB::Blue); FastLED.show(); } //This else statement sets the NeoPixel's color to Red //if the temperature is above 23.66C (74.5fF) else { fill_solid( &(leds[0]), NUM_LEDS , CRGB::Red); FastLED.show(); } }
With the code uploaded to your Arduino, open a web browser on a device that is connected to your home network. Then visit the IP address you set up at the beginning of the sketch. In my case, it is 10.10.1.177 as my home network is 10.10.1.XX based. Chances are, yours is 198.162.1.XX based. If everything is connected correctly, and you set up your sketch right, then you should see a plain white webpage with the data from the DHT sensor being reported back in the top lefthand corner.
As you can tell from the image above, my office temperature is 75.2F with a humidity of 41.00%. Since this temperature is above the 74.5F breakpoint, the NeoPixel strip is red.
If we hit the sensor with a short burst of freez spray (canned air held upside down) the temperature rapidly drops to 33.8F and the NeoPixel strip turns blue.
You can set the code up to change the NeoPixel’s color at any temperature you would like, just remember to set the temp to C in the code. You can also modify this code to add more breakpoints by adding more “if” statements, and even modify what the NeoPixels do on temp trigger. If you wanted them to strobe bright red, or maybe have them animate with a chase of different colors, its all simple with the FastLED library.
If you use this tutorial to make something awesome, please share it in the comments as I would love to see what everyone comes up with!
If you like this tutorial, and would like to see more like it, consider visiting our Patreon page and donating to help us keep TheMakersWorbench.com up and running! You can also support us by using the Amazon.com search bar in the left-hand sidebar on the homepage, or by clicking on and purchasing any of the hardware items we listed during this tutorial!