Four Channel 'Fake TV' With Arduino or Attiny




Introduction: Four Channel 'Fake TV' With Arduino or Attiny

About: I am a physician by trade. After a career in the pharmeceutical world I decided to take it a bit slower and do things I like. Other than my hobbies that involves grassroots medicine in S.E.&P Asia. I have buil…

While I was working on an "At home" simulator annex alarm system, one of the things I wanted to do is to have a TV on and from time to time change the channel. For that I had an IR Led incorporated in the project and that worked fine.
However, TV's are energy guzzlers and the idea to have a TV on standby for longer periods while on holiday also didn’t really appeal to me.
So I was thinking that maybe I could simulate the light of a TV with LEDs.

Why was I not surprised that such a product already existed, aptly called 'fakeTV' It is a device that uses 7-12 LED's to mimic the flicker of a TV. It can be set to react to light (i.e. switching on at dusk).
The price -depending on the model- is from 25 USD to 30 USD to 40 USD for their latest model that simulates a 40"flat-screen. Now of course the risk with that is that you actually may attract a burglar who is after your presumably 'huge flat-screen'
I have heard mixed reviews. The object is that you put it somewhere where it cant be seen but still has something to project its light on (blinds, curtains). Obviously the curtains cant be too thick and the device itself shouldn’t be visible from the outside.
One of the complaints I heard was that the 'scenes' played repeated too often and that a potential burglar who is "casing the joint" would soon see that it was fake. He still of course might not want to take a risk and go to a neighbours house. The FakeTV - if you check their Website is in fact really tiny. Not bigger than a cup of coffee it seems
Because I found the price a bit steep for 7-12 LEDs (depending on the model), I started to think how to construct one myself. Judging from their website their simplest model has one blue, one green, one red and 4 white LED's, so, 4 channels
Ideally I thought of an Attiny, but that has only 5 outputs Supposedly all 5 can be used as SoftwarePWM ( PB0 and PB1 can be used as hardware PWM, PB4 could be used as hardware PWM if analogWrite would be implemented for that pin in the core), that is if you leave Pin 1 (Reset) as is. I do not like messing with pin 1.
I came upon a 'mini moodlight' with an Attiny85 with 3 LEDs and a moodlight with an Attiny85 that used 3 RGB LEDs. Actually there is a hoist of Moodlights on instructables. Moodlights of course change their colour very gradually, whereas with a TV that can be more abruptly, but that is a matter of programming.

Then I came upon someone ('modeller') in the adafruit forums who owned a 'fakeTV' and had decided to also build one himself... with an Arduino. The interesting thing was that he used 6 LEDs instead of 12 and claimed to get good results with that. I was however more concerned about the amount of pins he used rather than the amount of LEDs. Well he used 6 pins, but since he seemed to write the same value every time to his 2 green LEDs and his 2 red LEDs, I could just put those LEDs in parallel respectively. That would even save me 2 pins, being left with needing again only 4 pins (Red Green Blue and White), which is OK for an Attiny85. I would then still have 1 pin left to add some kind of trigger.

Now as said above, the Arduino has 6 PWM pins and the Attiny only 2 (PB0 and PB1). Supposedly PB4 is also a PWM pin, but there is no implementation of the 'AnalogWrite' command. So I was considering a software PWM.
With software PWM basically what you do is switching a Digital pin between HIGH and LOW with the duty cycle determining the 'analogWrite'.
That however creates another problem as the processor would be mainly busy with 'waiting' and also, you can only handle one pin at the time. The moment you go to another pin, you leave the previous pin either HIGH or LOW. Although you could construct a 'state machine' that doesn’t have all those problems

Call me stupid for wanting to use an Attiny85, as a pro mini is very cheap these days and using one would solve the problems, but I just didnt feel right to use a 14 digital pin, 6 Analog pin controller board for a circuit that needs 4-5 pins.
So I had to find another solution.
The PWM pins PB0 and PB1 are controlled by timer 0.

Looking at the possible PWM output pin options the ATtiny85 supports:
Output PB0: OC0A or /OC1A.
Output PB1: OC0B or OC1A.
Output PB2: none.
Output PB3: /OC1B.
Output PB4: OC1B.

We've already got OC0A on PB0 and OC0B on PB1.

So how do we get 4 PWM outputs
The ATtiny chip provides two timer/counters, Timer/Counter0 and Timer/Counter1, and each of these provides two PWM comparators, OCR0A, OCR0B, OCR1A, and OCR1B. So in theory we should be able to get four PWM outputs.

But looking at the above table of pin assignments it's clear that we can't get both OC0B and OC1A at the same time, even though there are two pins available: PB3 and PB4.

Fortunately the solution is fairly simple; we define an interrupt to occur when register OCR1A matches Timer/Counter1, and another interrupt to occur when the counter overflows; ie reaches 00 again. We do this using the TIMSK register, so basically the interrupt occurs on a compare and an overflow.

I quickly built something on a breadboard and that seemed to work, So it was time to build something more durable.

4x330 Ohm Resistor
5x150 Ohm resistor
1x 10k Ohm Resistor
1x 470kOhm Resistor (optional)
6x Green LED
6x Blue LED
9x white LED
1x phototranistor, photodiode or LDR (optional)
4x BC547 (or other NPN switching transistor)
7812 (optional)
1x Attiny85
1x 8 pin DIL socket
Arduino/RBB Arduino
mind you: the circuit mentions 220 Ohm resistors but those were initial guesses when I had not checked the LED's forward voltage yet.

Just one remark about the 7812: you will need an input of at least 14.5 Volts for that. a PSU of 14.5 volt is rare. Though some wal-warts give off more if they are not connected to a load, the voltage often drops on load.
If you have a 12 Volt PSU, you can omit the 7812.

If getting the 12 Volts/14.5 Volts from a walwart proves to be a problem, consider a 75 eurocents(!) 5 to 12 Volt converter

Step 1: Fake TV. the Built

Though I started out with a print design, I guessed building it on an old piece of perfboard would be just as easy.
The LED's I ordered from China gave me the following forward voltages:
RED 1.96 Volt
GREEN 2.73 Volt
BLUE 2.87 Volt
WHITE 2.88 Volt

feeding them from 12 Volt, taking a 0.1 Volt collector-emitter drop into account that gives the following current limiting resistor values for 20mA:

3 4 5 6 LEDs
red 306, 200, 110, 7
green 190, 49
blue 169, 21
white 169, 21

I used 3 LEDs each and settled for red/green 330 ohm and blue white 150 ohm

Step 2: Fake TV-Arduino Code

The code for an Arduino can be seen below. It is easily expandable by adding new 'scenes'

Step 3: Fake TV-Attiny Code

The code for the Attiny85 is as follows:
NOTE: as instructables is known to screw up code with the "smaller than sign" (and apparently did here as well) I put the code in codebender:

/* Four PWM Outputs */
// ATtiny85 outputs
// code adapted for Fake TV
const int Red = 0;
const int Green = 1;
const int Blue = 2;
const int BluePin=4;
const int White = 3;
int randpwm=0;
volatile uint8_t* Port[] = {
  &OCR0A, &OCR0B, &OCR1A, &OCR1B};
void setup() {
  pinMode(Red, OUTPUT);
  pinMode(Green, OUTPUT);
  pinMode(BluePin, OUTPUT);
  pinMode(White, OUTPUT);
  // Configure counter/timer0 for fast PWM on PB0 and PB1
  TCCR0A = 3<<COM0A0 | 3<<COM0B0 | 3<<WGM00;
  TCCR0B = 0<<WGM02 | 3<<CS00; // Optional; already set
  // Configure counter/timer1 for fast PWM on PB4
  TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 7<<CS10;
  GTCCR = 1<<PWM1B | 3<<COM1B0;
  // Interrupts on OC1A match and overflow
  TIMSK = TIMSK | 1<<OCIE1A | 1<<TOIE1;

ISR(TIMER1_OVF_vect) {
  bitClear(PORTB, White);
// Sets colour Red=0 Green=1 Blue=2 White=3
// to specified intensity 0 (off) to 255 (max)
void SetColour (int colour, int intensity) {
  *Port[colour] = 255 - intensity;
void loop()
  for(int i=0;i<10;i++)  //play scene 1 multiple times
  if (random(2) == 1)  //Possibly call scene 2
  if (random(2) == 1)  //Possibly call scene 3
  if (random(2) == 1)  //Possibly call scene 4
  if (random(4) == 1)  //Possibly do a commercial break
// These are the main scene algorithms
void scene1()
// Changes random light levels and linger-times
// of all colors to simulate "normal" TV action
  randpwm = random(20,255);
  randpwm = random(20,255);
  SetColour(Blue, randpwm);
void scene2()
// Increases intensity of wht,blu (fade-in)
  for(int i=2;i<255;i++)
    // analogWrite(blu,i);
    // analogWrite(wht,i);
void scene3()
// Flickers wht,blu for a flickeriing scene effect
  //  Serial.println("Scene 3");
  boolean sw = HIGH;
  for(int i=0;i<30;i++)
    // digitalWrite(3,sw);
    sw = !sw;
void scene4()
// Changes red/grn light levels only
// wht/blu are off
  //don't use wht/blu
  for(int i=0;i<12;i++)
    randpwm = random(20,255);
    randpwm = random(20,255);
void commercial()
// Simulates a switch to or from a commercial break

Step 4: The Fake TV: Thoughts

The proper placement for a Fake TV is such that the device itself cannot be seen but the light should be projected on say a curtain or the ceiling.

The FakeTV can be switched with a normal timer. In making burglars think that someone is home, it is best to not start and stop the TV at exactly the same moment each day. There are several ways to do that:
I use it in a 433 MHz operated security system and I send an on code at a variable time to a switch in which the PSU of the fakeTV is plugged.
Because of that I do not need the phototransistor in the circuit, but the code can easily be adapted to switch on at dusk and still off by the timer.

Although the code for the Attiny functionally is the same as for the Arduino, I had the feeling the effect of the Arduino was a bit better. Behind a curtain though the Attiny operated device functioned well.

Magazine 'Elektor' April 2013, has published a 'TV simulator' based on an Atmega8. They only use 3 colors (including white) as they omitted green (So, white, blue and red).
Another fake-TV based on an Atmega8 can be found here. (German language)

Step 5: The 85 Code on Codebender

2 People Made This Project!


  • Game Design: Student Design Challenge

    Game Design: Student Design Challenge
  • Cold Challenge

    Cold Challenge
  • Block Code Contest

    Block Code Contest



3 years ago

I am trying to run this o Arduino 1.8.21 and get the error message,
Arduino: 1.8.9 (Windows Store (Windows 10), Board: "Arduino/Genuino Uno"
Build options changed, rebuilding all
fake_TV:16:1: error: cannot convert 'volatile uint16_t* {aka volatile unsigned int*}' to 'volatile uint8_t* {aka volatile unsigned char*}' in initialization
fake_TV:16:1: error: cannot convert 'volatile uint16_t* {aka volatile unsigned int*}' to 'volatile uint8_t* {aka volatile unsigned char*}' in initialization
C:\Users\Robert M\Documents\Arduino\fake_TV\fake_TV.ino: In function 'void setup()':
fake_TV:29:3: error: 'TCCR1' was not declared in this scope
TCCR1 = 1 << CTC1 | 1 << PWM1A | 3 << COM1A0 | 7 << CS10;
fake_TV:29:16: error: 'CTC1' was not declared in this scope
TCCR1 = 1 << CTC1 | 1 << PWM1A | 3 << COM1A0 | 7 << CS10;
fake_TV:29:28: error: 'PWM1A' was not declared in this scope
TCCR1 = 1 << CTC1 | 1 << PWM1A | 3 << COM1A0 | 7 << CS10;
fake_TV:30:16: error: 'PWM1B' was not declared in this scope
GTCCR = 1 << PWM1B | 3 << COM1B0;
fake_TV:32:3: error: 'TIMSK' was not declared in this scope
TIMSK = TIMSK | 1 << OCIE1A | 1 << TOIE1;
In file included from sketch\fake_TV.ino.cpp:1:0:
C:\Users\Robert M\Documents\Arduino\fake_TV\fake_TV.ino: In function 'void __vector_11()':
fake_TV:37:16: error: 'TIFR' was not declared in this scope
if (!bitRead(TIFR, TOV1)) bitSet(PORTB, White);
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\arduino\avr\cores\arduino/Arduino.h:111:32: note: in definition of macro 'bitRead'
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
exit status 1
cannot convert 'volatile uint16_t* {aka volatile unsigned int*}' to 'volatile uint8_t* {aka volatile unsigned char*}' in initialization
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.


Reply 3 years ago

Sorry to hear that. Are you sure you have picked the right code? I provide two" 1 for attiny and one for the arduino


Reply 3 years ago

Ahh I see, I had downloaded the code bender one that did not work on arduino. Thanks Anyhow I supplied a circuit board for anyone to download, order or make on a CNC.


Reply 3 years ago

Good. Happy you got it fixed and thanks for supplying the board design


7 years ago on Introduction


This is a great instructable! Very usefull.

I made the Arduino version and it worked very good.

I think the AtTiny version has a mistake in the code:

Line 20 should not read:

TCCR0A = 3<

it has to be:

TCCR0A = 3<<COM0A0 | 3<<COM0B0 | 3<<WGM00;

TCCR0B = 0<<WGM02 | 3<<CS00; // Optional; already set

// Configure counter/timer1 for fast PWM on PB4

TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 7<<CS10;

GTCCR = 1<<PWM1B | 3<<COM1B0;

// Interrupts on OC1A match and overflow




if (!bitRead(TIFR,TOV1)) bitSet(PORTB, White);


Maybe you made a copy/paste mistake.

Could you add the code as a text file?

PS My TV is not that big, so I wil not be needing all the LED,

2 RGB and 2 white LED will do for me ;)


Reply 7 years ago on Introduction

You are very right. Not really a copy/paste mistake but the fact that the website tends to be poor at handling the 'fishooks' as it sees them as html code, even if preceded by the 'pre' html code.
I always try to check it after putting the code but sometimes if you re-open the instructable for editing, prior corrections of the html foul up get fouled up again. I will attach the code as textfile or put it in codebender