By Luke W.
For my project, I came up with a device that explores the idea of cation emission through gas excitation, more commonly known as the thing that makes different elements create different colored flames when they burn. To show this, I created a dictionary of elements that have interesting flame colors (as well as the RGB values for those colors) and hooked them up to a sensor that detects heat in the air to simulate burning.
Here’s an Imgur post that documents my progress through pictures and videos:
The first thing I did was hook up the LCD display to the Arduino. At first, I didn’t realize what the potentiometer was for, and in the schematic from the ELEGOO tutorials, I mistook it for a buzzer and forgot to include it… but I watched this tutorial and figured it out!
From there, I used the ELEGOO tutorials to get the DHT11 output showing in the console logs, and subsequently on the LCD display. I had to download a couple of libraries (LiquidCrystal and dht_nonblocking) to get the example code for each component running separately, and then I combined them into a single file. From there, I added in the RGB LED and button code to make the system light up and scroll between elements. Finally, I put together a set of arrays to correlate elements to the RGB values of their respective flames.
In order to estimate the RGB values for these elements, I did a little bit of research.
I used a website that described the colors for each element:
https://www.thoughtco.com/how-flame-test-colors-are-produced-3963973
I found a video actually showing the colors for some different elements:
And I used this RGB color wheel to get the actual values I needed:
Overall, I’m decently happy with how it turned out! I do wish that the RGB LED was better about handling some of the colors, and it did take a while to actually heat the DHT11 up to the threshold I tested with. But for the most part, it turned out pretty well!
Here’s the code I used to run this thing:
#include <LiquidCrystal.h>
#include <dht_nonblocking.h>
#include <stdio.h>
#define BTN_PRESSED (button == LOW && oldButton == HIGH)
#define BTN_PIN 2
#define DHT_SENSOR_TYPE DHT_TYPE_11
#define ELEMENT_NUM 9
#define TEMP_THRESHOLD 30
#define BLUE 3
#define GREEN 5
#define RED 6
#define DHT_SENSOR_PIN 4
DHT_nonblocking dhtSensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
const char* elements[] = {
"Lithium - Li ",
"Sodium - Na ",
"Magnesium - Mg ",
"Potassium - K ",
"Calcium - Ca ",
"Iron (III) - Fe ",
"Copper - Cu ",
"Strontium - Sr ",
"Barium - Ba "
};
// Li Na Mg K Ca Fe Cu Sr Ba
int elementRed[] = { 255, 255, 255, 255, 255, 255, 75, 255, 255 };
int elementGreen[] = { 28, 239, 155, 214, 113, 201, 255, 0, 211 };
int elementBlue[] = { 70, 9, 255, 231, 50, 71, 200, 62, 0 };
int lightRed = 255;
int lightGreen = 28;
int lightBlue = 70;
int elementIndex = 0;
int button = HIGH;
int oldButton = HIGH;
float temperature = 0;
float humidity = 0;
void setup() {
pinMode(BTN_PIN, INPUT_PULLUP);
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
Serial.begin(9600);
lcd.begin(16, 2);
lcd.print(elements[elementIndex]);
} // setup
/*
* Poll for a measurement, keeping the state machine alive. Returns
* true if a measurement is available.
*/
static bool measureEnvironment(float* temperature, float* humidity) {
static unsigned long measurement_timestamp = millis();
// Measure once every four seconds
if (millis() - measurement_timestamp > 3000ul) {
if (dhtSensor.measure(temperature, humidity) == true) {
measurement_timestamp = millis();
return(true);
} // if
} // if
return(false);
} // measureEnvironment
void loop() {
button = digitalRead(BTN_PIN);
// Scroll to next element when button is pressed
if (BTN_PRESSED) {
elementIndex = (elementIndex + 1) % ELEMENT_NUM;
// char str[30];
// sprintf(str, "%s: R%d G%d B%d", elements[elementIndex], elementRed[elementIndex], elementGreen[elementIndex], elementBlue[elementIndex]);
// Serial.println(str);
lcd.setCursor(0, 0);
lcd.print(elements[elementIndex]);
lightRed = elementRed[elementIndex];
lightGreen = elementGreen[elementIndex];
lightBlue = elementBlue[elementIndex];
} // if
// Light up RGB LED if temperature is high enough
if (temperature > TEMP_THRESHOLD) {
analogWrite(RED, lightRed);
analogWrite(GREEN, lightGreen);
analogWrite(BLUE, lightBlue);
// Otherwise, turn it off
} else {
digitalWrite(RED, LOW);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);
} // if
// Display temperature from DHT11 on LCD display when it updates
if (measureEnvironment(&temperature, &humidity) == true) {
lcd.setCursor(0, 1);
lcd.print("T = ");
lcd.print(temperature, 1);
lcd.print(" deg. C");
} // if
oldButton = button;
delay(20);
} // loop
Leave a Reply