Automatic Faux/Fake Fireplace
A few weeks ago, much to the Wife Units™ glee, Costco had a deal on their entertainment centers with a built-in faux fireplace (it also has an electric heater that is of less consequence). While it’s a nice entertainment center, and the faux fireplace is convincing enough for our enjoyment, after having the unit for a couple of days, I did find a problem.
The Problem
For the first few days the fireplace was always on, even when we weren’t in the room or home. This wasn’t a big deal, in just fireplace mode (heater not running) it can’t be using that much power, but it’s still a waste. It does have an auto off timer but it needs to be manually set each time you turn the fireplace on. Plus, it doesn’t solve the second problem I found.
After about a week, the novelty wore off enough that it became too much work to walk over to the center and press the power button, or use the remote to turn the fireplace on. I’m mostly kidding, but we did stop turning it on. Sort of pointless to have a nice faux fireplace and not have it turned on.
The Idea
My plan is to make the fireplace come on when the room is occupied. I haven’t opened up the fireplace yet but I’ve played around with the controls enough to conclude that I should be able to easily interface with the fireplace power button. It should simply be a matter of turning it on or off based on if the room is occupied or not. When turned on the fireplace always starts with the same settings before being turned off.
I’ll use a motion sensor to detect when the room is occupied. The motion sensor will be connected to a microcontroller that will turn the fireplace on when motion is detected, and off after a set interval of no motion.
I can use optocouplers (NSL-32SR2) to control the power switch on the fireplace, and possibly to detect the state (on/off) of the fireplace.
I have a PIR (i.e. motion) sensor on hand that’s been waiting to be used for something. While there are stand alone motion sensors that have relays and such built in to control devices, this one (made by Parallax) has a digital output for use with a microcontroller. This is perfect because I want to use a microcontroller so I can make operation a little smarter than simply on/off after x number of minutes.
A full-blown Arduino would be overkill for this, so I’ll use an ATtiny85. The ATTiny85 is a baby microcontroller that can function normally without any external components; all it needs is power. It only has 5 input/output PINs, but I only need 3: One PIN for the power button (output), one to detect when the fireplace is on (input), and one for the PIR sensor (input). You can use the Arduino IDE to program the ATtiny85 but since it has no USB it requires an external programmer. I use SparkFun’s Pocket AVR Programmer.
The ATtiny85 and PIR sensor run on 5 volts. I’m hoping that there will be a low voltage supply in the fireplace that I can tap into. If not, I’ll need to wire in a dedicated power supply.
The Build
Power
The fireplace control panel has several buttons that control various functions of the fireplace. The buttons are connected to an IC that’s being used to “digitize” the physical button presses. The control panel is connected to the main control board via a ribbon cable.
After some probing with the multimeter, I found that the control board is powered by 5v, Yippee! I can tap into that for the power needed for the ATtiny and PIR sensor.
I could have tapped in closer to the power supply but because of the way the fireplace is constructed, it was easier to get to the front panel with the soldering iron then it was the main power supply.
Fireplace on/off Control
I’m going to use an optocoupler to “press” the fireplace power button with the ATTiny85. I need to add some leads to the fireplace power switch which will connect to the photocell side of the optocoupler.
PIR Sensor
I’ll mount the PIR sensor next to the control panel, behind the heater grille. The sensor has a red LED that lights when it detects motion, this is generally a nice feature but may be an annoyance for this application. If it becomes an annoyance I may remove the LED.
Fireplace State Detection
I need to be able to detect when the fireplace is on or off. This way I can program the microcontroller to only turn off the fireplace when it’s on and vice versa. This will prevent a scenario where the microcontroller thinks that it should turn the fireplace on (motion detected), but turns it off instead because it does not know that it was already on.
The fireplace has various flame modes — different flame styles, colors and speeds. All the lighting is done with LEDs. I was thinking that I could tap on to one of the LEDs output with an optocoupler to detect when the fireplace is on. Problem is, none of the flame LEDs are on in every flame mode. The LEDs used to light the faux log, however, are always on when the fireplace is “lit.” So, I’ll connect the LED side of the optocoupler inline with the log LEDs. When the fireplace is on, the LED in the optocoupler will light, lowering the photocell resistance, which I can detect with the microcontroller.
The log LEDs are actually a strip of LEDs powered with 12v, way too high for the NSL-32SR2 optocoupler, which nominally wants 2.5v @ 25mA. So I’ll have to use a resistor to knock that down. Another possible problem is that the fireplace lights are dimmable. At the lowest brightness setting the optocoupler may not be supplied with enough voltage to lower the photocell resistance enough to trigger a logic level change on the microcontroller.
To reduce components, I’m using the the ATtiny’s internal pullup resistor. Because I’m using a pullup resistor, the logic is flipped. Rather than drive the optocoupler input to 5v, I’m driving it to Ground. So, when the fireplace is off the optocoupler’s photocell resistance will be at its maximum, and the microcontroller will see that input as HIGH (i.e. the input will be at 5v). When the fireplace is on, the optocoupler’s photocell resistance will either be basically zero or low enough that the microcontroller will read the input as LOW (i.e. the input will be at less than 5v). After testing I found that this works, no matter what the brightness setting of the fireplace.
Final Build
The ATTiny85, and optocoupler’s were soldered to a Perma-Proto board. I used screw terminals for the connections to the PIR sensor and optocoupler inputs/outputs. The proto board was mounted in the back of the fireplace, next to the fireplace’s IR sensor board.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
const int OnOffDetect = 0;
const int PowerSW = 3;
const int PIR = 4;
unsigned long OnTimer = 1800000; // How long (in milliseconds) we want the fireplace to stay on (30 min in this case).
unsigned long OnTimerCount = 0;
unsigned long CurrMills = 0;
unsigned long TimerPreMills = 0;
void setup() {
pinMode(OnOffDetect, INPUT);
pinMode(PowerSW, OUTPUT);
pinMode(PIR, INPUT);
digitalWrite(OnOffDetect, HIGH); // Enable internal resistor.
OnTimerCount = OnTimer;
delay(60000); // Give the PIR its calibration time on boot.
}
void loop() {
if (millis() - CurrMills > 1000) { // If a second has passed, subtract that from OnTimerCount.
OnTimerCount = OnTimerCount - 1000;
CurrMills = millis();
}
if (OnTimerCount <= 0 && digitalRead(OnOffDetect) == LOW) { // If the timer runs out and the fireplace is on.
digitalWrite(PowerSW, HIGH); // "Press" the fireplace power button to turn it off.
delay(500);
digitalWrite(PowerSW, LOW); // Stop pressing the fireplace power button.
OnTimerCount = OnTimer; // Reset the timer.
}
if (OnTimerCount <= 0 && digitalRead(OnOffDetect) == HIGH) { // If the timer runs out and the fireplace is off.
OnTimerCount = OnTimer; // Reset the timer.
}
if (digitalRead(PIR) == HIGH && digitalRead(OnOffDetect) == HIGH) { // If motion is detected and the fireplace is off.
digitalWrite(PowerSW, HIGH); // "Press" the fireplace power button to turn it on.
delay(500);
digitalWrite(PowerSW, LOW); // Stop pressing the fireplace power button.
}
else if (digitalRead(PIR) == HIGH && digitalRead(OnOffDetect) == LOW) { // If motion is detected and the fireplace is on.
OnTimerCount = OnTimer; // Reset the timer.
}
}
The tl;dr version of the code is:
-
If motion is detected, and the fireplace is off, then the fireplace is turned on and the timer is reset.
-
If 30 minutes pass without motion being detected, and the fireplace is on, then the fireplace is turned off.
-
If the fireplace is on and motion is detected, then timer is reset.
-
If 30 minutes pass and the fireplace is off, the timer is reset.
Pullup vs. Pulldown Resistor image used under CC BY-NC-SA licence. Original image courtesy of Justin Love.