Hello all, Im looking for someone to help with a project. I want to use the dht11 sensor with the neopixel ws2812 and piezo buzzer. I would like to have the dht11 take the current room temperature and settle for a bit, and display it as green on the leds when it has settled on the current temperature. When a +/- 5degree change is detected i would like the leds to change red for the + blue for the - and alarm on the buzzer.
Have you got a particular Arduino (or other) board in mind for this project ?
The requirements seem quite simple. Have you tried to write it for yourself ?
I tried but being completely new to writing code Ive gotten nowhere. I was going to use the nano but would prefer something smaller if possible. I did have someone claim to be able to write it but after being paid they blocked me so I lost money there
I am happy to help, and what you are asking for does not sound difficult as long as what you have stated is all you need. If there is more such as buttons to interact with the system or maybe a display of current and/or trigger temperature then now is the time to say
I don't want paying for providing help but would ask that you make a donation to an animal charity of your choice if you are happy with what I do. I would leave the amount donated up to you
If you are happy to proceed on that basis then please provide more details as follows
- how many NeoPixels are in the ring ?
- how often should the system take the current temperature and then look for changes ?
- will the system run 24/7 ?
- how is the project to be powered when complete ?
- which Arduino board or boards do you have ?
Thank you so much! I actually volunteer at a local shelter, so I have no problem donating to them. The ring is 16led, the system may run a maximum of 4hrs -8hrs and would be powered via a rechargeable battery pack. I will probably just use the nano v3.0 since thats what I have. I would like it to be able to stabilize on the current room temperature and light the ring up green. I guess it should be taking reading rather often, then when a + or - of 5 degrees is detected, it would sound the buzzer and light up a new color in correspondence with the +(red) or -(blue). The biggest thing is making sure it stabilizes on the rooms current temperature. There wont be anything extra added to it just whats described
Neopixels and battery power are not a great combination! All LEDs use quite a lot of power compared to other types of displays, and Neopixels even more so. Why choose a neopixel ring? Do you need to see it from a distance, for example? Do you have a battery of any type in mind?
Also, why use a dht11? It's a temperature + humidity sensor. Do you need to measure humidity?
As Paul has said, battery power is going to be a problem
As to your description, I am still not clear how often the system should recalibrate itself or is it only once at startup ?
Name & shame so others don't lose money too.
I write "code for cash" all the time, and usually require upfront payment. People like this make all of us look bad and make it harder for us to be trusted.
In the very rare case that I can't work with someone, I refund their money and get on with life.
I Believe once at startup would probably be fine. I need to be able to see it in a dark room at a distance which is why I chose the led ring. I have all the components, so it is why I chose everything. As for the battery, I have several high mah battery packs here so ill experiment with that
You may not realise it yet, but with that led ring on full brightness, it won't be a dark room any more!
But, you can use a much lower level of brightness and increase the battery life significantly. It should still be easily visible in a dark room.
With 16 LEDs, the ring could draw up to 900mA on full brightness white. But on full brightness green, that would drop to around 300mA. At 33% brightness green, only around 100mA. At that consumption, for 8 hours life, your battery pack would need to be be around 2,400mAh, which isn't unreasonable.
You could add a light-dependant resistor (LDR) to the project to measure the ambient light level in the room and adjust the ring brightness automatically, so that it doesn't dazzle. That would also help maximize the battery life. The LDR would need to be carefully placed, perhaps on the back of the ring, so that it is not affected too much by the light from the ring itself.
A sketch for you to try
#include <FastLED.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTTYPE DHT11
#define NUM_LEDS 8
#define LEDS_PIN 2
#define LED_BRIGHTNESS 8 //0 to 255
#define CALIBRATION_PERIOD 10000 //calibration time in milliseconds
#define TIME_BETWEEN_CALIBRATIONS 60000 //milliseconds
#define DHT_PIN 12
#define TEMP_CHANGE_TRIGGER 2.0 //alert after temp changes this much
boolean calibrateOnce = false;
CRGB leds[NUM_LEDS];
DHT_Unified dht(DHT_PIN, DHTTYPE);
void setup()
{
Serial.begin(115200);
FastLED.addLeds<NEOPIXEL, LEDS_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(LED_BRIGHTNESS);
setLeds(CRGB::Black);
dht.begin();
calibrate();
}
void loop()
{
unsigned long currentTime = millis();
static unsigned long previousCalibrationTime = millis();
sensors_event_t event;
dht.temperature().getEvent(&event);
float currentTemperature = event.temperature;
static float calibratedTemperature = currentTemperature;
Serial.print(F("Current temperature "));
Serial.println(currentTemperature);
Serial.print(F("Difference from calibrated temperature "));
Serial.println(currentTemperature - calibratedTemperature);
if (currentTemperature - calibratedTemperature >= TEMP_CHANGE_TRIGGER)
{
setLeds(CRGB::Red);
}
else if (calibratedTemperature - currentTemperature >= TEMP_CHANGE_TRIGGER)
{
setLeds(CRGB::Blue);
}
if (currentTime - previousCalibrationTime >= TIME_BETWEEN_CALIBRATIONS)
{
if (calibrateOnce == false)
{
calibratedTemperature = calibrate();
previousCalibrationTime = millis();
}
}
}
void setLeds(CRGB colour)
{
for (int led = 0; led < NUM_LEDS; led++)
{
leds[led] = colour;
}
FastLED.show();
}
float calibrate()
{
setLeds(CRGB::Black);
float calibratedTemperature;
unsigned long currentTime = millis();
unsigned long calibratedStartTime = millis();
unsigned long flashStartTime = calibratedStartTime;
unsigned long flashPeriod = 100;
byte currentLed = 0;
while (currentTime - calibratedStartTime <= CALIBRATION_PERIOD)
{
currentTime = millis();
if (currentTime - flashStartTime >= flashPeriod)
{
sensors_event_t event;
dht.temperature().getEvent(&event);
calibratedTemperature = event.temperature;
Serial.print(F("Calibrating\t"));
Serial.println(calibratedTemperature);
leds[currentLed++] = CRGB::Black;
currentLed = currentLed % NUM_LEDS;
leds[currentLed] = CRGB::Green;
flashStartTime = currentTime;
FastLED.show();
}
}
setLeds(CRGB::Green);
Serial.print(F("Calibrated temperature = "));
Serial.println(calibratedTemperature);
return calibratedTemperature;
}
There are a bunch of parameters that you can change at the start of the sketch. As currently set the system will calibrate for 10 seconds at startup or reset then again at one minute intervals. You can prevent recalibration by setting calibrateOnce to true and set the calibration period and interval if you decide to use recalibration
The temperature difference to trigger the alerts is set to 2.0 degrees and the brightness of the display is set to 8
You can change the number of LEDs to suit your ring and the pins that the LEDs and DHT11 are connected to
The buzzer has not been implemented but is trivial to add. What type of buzzer do you have, passive (apply 5V and it makes a single sound) or passive (you can make any note or tune within reason but you have to program it)
You will need to install the libraries if you don't have them but they are available from the IDE Library Manager
Try the sketch and see how you get on. It needs some error checking to be added and could be tidied up, but try it and let's have some feedback
Ok my findings so far. The code seems to work to a point. If I trigger an increase in temperature, the leds stay red even after the temperature drops below the trigger point. The buzzer would be a regular piezo disk style
I adjusted the parameters for 5 degree increase or decrease. Increased the calibration time to 3000ms and time between calibration to 60000ms. The leds will go back to green after the calibration but I was hoping they would revert back after the temperature goes back under the 5 degrees even before the recalibration period
I am glad that it worked OK. Did you note the animation during calibration (added at no extra cost) ?
Naughty boy !
That was not part of the specification ![]()
I will add that later and add the buzzer code, but be aware that should you miss seeing/hearing the alert for high or low temperature then, when the alert is over you will not be aware that it occurred
I love the animation at the beginning, thank you so much! I thought that was actually part of the neopixel so cudos for that! Sorry I always miss details, I have too much spinning around up there to get it all out at once. That is ok, there is a camera setup in that room so I can review it if I were to miss it
Give this version a try
You can #define the pin that you want to use for the buzzer. If at any time the temperature cannot be read then the LEDs will flash red and the fault will need to be corrected. Most likely a loose connection. and the Arduino will need to be reset
#include <FastLED.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>
#define DHTTYPE DHT11
#define NUM_LEDS 8
#define LEDS_PIN 2
#define LED_BRIGHTNESS 8 //0 to 255
#define CALIBRATION_PERIOD 10000 //calibration time in milliseconds
#define TIME_BETWEEN_CALIBRATIONS 60000 //milliseconds
#define DHT_PIN 12
#define TEMP_CHANGE_TRIGGER 2.0 //alert after temp changes this much
#define BUZZER_PIN 13
boolean calibrateOnce = false;
CRGB leds[NUM_LEDS];
DHT_Unified dht(DHT_PIN, DHTTYPE);
void setup()
{
Serial.begin(115200);
pinMode(BUZZER_PIN, OUTPUT);
digitalWrite(BUZZER_PIN, LOW);
FastLED.addLeds<NEOPIXEL, LEDS_PIN>(leds, NUM_LEDS);
FastLED.setBrightness(LED_BRIGHTNESS);
setLeds(CRGB::Black);
dht.begin();
calibrate();
}
void loop()
{
unsigned long currentTime = millis();
static unsigned long previousCalibrationTime = millis();
float currentTemperature = readTemperature();
static float calibratedTemperature = currentTemperature;
Serial.print(F("Current temperature "));
Serial.println(currentTemperature);
Serial.print(F("Difference from calibrated temperature "));
Serial.println(currentTemperature - calibratedTemperature);
if (currentTemperature - calibratedTemperature >= TEMP_CHANGE_TRIGGER)
{
setLeds(CRGB::Red);
digitalWrite(BUZZER_PIN, HIGH);
}
else if (calibratedTemperature - currentTemperature >= TEMP_CHANGE_TRIGGER)
{
setLeds(CRGB::Blue);
digitalWrite(BUZZER_PIN, HIGH);
}
else
{
setLeds(CRGB::Green);
digitalWrite(BUZZER_PIN, LOW);
}
if (currentTime - previousCalibrationTime >= TIME_BETWEEN_CALIBRATIONS)
{
if (calibrateOnce == false)
{
calibratedTemperature = calibrate();
previousCalibrationTime = millis();
}
}
}
void setLeds(CRGB colour)
{
for (int led = 0; led < NUM_LEDS; led++)
{
leds[led] = colour;
}
FastLED.show();
}
float calibrate()
{
setLeds(CRGB::Black);
float calibratedTemperature;
unsigned long currentTime = millis();
unsigned long calibratedStartTime = millis();
unsigned long flashStartTime = calibratedStartTime;
unsigned long flashPeriod = 100;
byte currentLed = 0;
while (currentTime - calibratedStartTime <= CALIBRATION_PERIOD)
{
currentTime = millis();
if (currentTime - flashStartTime >= flashPeriod)
{
calibratedTemperature = readTemperature();
Serial.print(F("Calibrating\t"));
Serial.println(calibratedTemperature);
leds[currentLed++] = CRGB::Black;
currentLed = currentLed % NUM_LEDS;
leds[currentLed] = CRGB::Green;
flashStartTime = currentTime;
FastLED.show();
}
}
setLeds(CRGB::Green);
Serial.print(F("Calibrated temperature = "));
Serial.println(calibratedTemperature);
return calibratedTemperature;
}
void errorFlash()
{
while (true)
{
setLeds(CRGB::Red);
delay(200);
setLeds(CRGB::Black);
delay(200);
}
}
float readTemperature()
{
sensors_event_t event;
dht.temperature().getEvent(&event);
if (isnan(event.temperature))
{
Serial.println(F("Error reading temperature !"));
errorFlash();
}
else
{
return event.temperature;
}
}
To allow time for the sensor to initialise on initial power up a delay() of 2 seconds before calling calibrate() in setup() would be a good idea
dht.begin();
delay(2000); //allow sensor to settle
calibrate();
Everything works great! Thank you. Also, does adopting count? because that happened yesterday. I adopted a poor 7 year old cat from my local shelter. He survived cancer but no one wanted the poor old boy. Well I did and he is now home with me!
I am glad that it works for you. I suggested adding the short delay() at startup because the DHT11 seems to need some settling time from a power on start although it is OK immediately following a reset. As a matter of interest what is the application for the project ? From how it works I gather that you want to know whether the air temperature varies outside of certain limits over a period of time, but what are you trying to protect ?
For my own amusement I may make some adjustments to the sketch and if I do I will post it here. How do you fancy an intermittent noise from the buzzer in the case of an alarm ? If I do add that, or anything else, I will make them options in the sketch so that they can be controlled without programming beyond editing a #define
I will gladly take adopting a cat as payment. We had 2 cats for 18 years that were rescued as kittens and when we lost both of them in the same year we got a rescued (ex racing) greyhound and had her for 8 years
Another thought. The DHT11 is not exactly renowned for its accuracy but it is what you have. Should there be a need for more accuracy then there are other temperature measuring devices available that could be used instead