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

Picture of Four Channel 'Fake TV' With Arduino or Attiny

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.

BOM
4x330 Ohm Resistor
5x150 Ohm resistor
1x 10k Ohm Resistor
1x 470kOhm Resistor (optional)
6x RED LED
6x Green LED
6x Blue LED
9x white LED
1x phototranistor, photodiode or LDR (optional)
4x BC547 (or other NPN switching transistor)
7805
7812 (optional)
1x Attiny85
1x 8 pin DIL socket
OR
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

Picture of 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 */
//http://www.technoblogy.com/show?LE0
// 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);
  //digitalWrite(3,HIGH);
  // 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
  {
    scene1();
  }
  if (random(2) == 1)  //Possibly call scene 2
  {
    scene2();
  }
  if (random(2) == 1)  //Possibly call scene 3
  {
    scene3();
  }
  if (random(2) == 1)  //Possibly call scene 4
  {
    scene4();
  }
  if (random(4) == 1)  //Possibly do a commercial break
  {
    commercial();
  }
}
// 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);
  SetColour(Red,randpwm);
  randpwm = random(20,255);
  SetColour(Green,randpwm);
  randpwm=random(10,225);
  SetColour(Blue, randpwm);
  randpwm=random(10,175);
  SetColour(White,randpwm);
  delay(random(500,2000));
}
void scene2()
// Increases intensity of wht,blu (fade-in)
{
  delay(1000);
  for(int i=2;i<255;i++)
  {
    // analogWrite(blu,i);
    // analogWrite(wht,i);
    SetColour(Blue,i);
    SetColour(White,i);
    delay(20);
  }
}
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);
    digitalWrite(BluePin,sw);
    digitalWrite(White,sw);
    sw = !sw;
    delay(random(50,300));
  }
}
void scene4()
// Changes red/grn light levels only
// wht/blu are off
{
  //don't use wht/blu
  digitalWrite(White,LOW);
  digitalWrite(BluePin,LOW);
  for(int i=0;i<12;i++)
  {
    randpwm = random(20,255);
    SetColour(Red,randpwm);
    randpwm = random(20,255);
    SetColour(Green,randpwm);
    delay(random(200,2000));
  }
}
void commercial()
// Simulates a switch to or from a commercial break
{
  SetColour(Red,2);
  SetColour(Green,2);
  SetColour(Blue,0);
  SetColour(White,0);
  delay(random(1000,2500));
}

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

Comments

tzikis (author)2015-09-28

Hey diy_bloke, and congrats on the very nice instructable.

just thought I'd let you know, you can include your codebender code straight in your instructables, like this: https://www.instructables.com/id/Include-your-codeb...

This will make it so much easier for people to read your code, and even program their Arduino straight from you instructable

Vasilis

P.S. Disclosure: I'm the founder of codebender

diy_bloke (author)tzikis2016-02-08

Still extremely happy with codebender, I hardly use my IDE anymore

tzikis (author)diy_bloke2016-02-08

that's great to hear! let me know how we can make it even better

by the way, i did manage to figure out the issue with the tutorial. we had beefed up our security and the instructables backend wasn't fine with that, so we worked with them to figure out the issues and get a working solution. it should work now :)

diy_bloke made it! (author)tzikis2016-02-09

actually there is a small nuisance. The down arrow of the scroll bar in codebender is covered by the formatting and print window. Not a big disaster, just a small nuisance
Other than that quite happy with codebender

tzikis (author)diy_bloke2016-02-09

oh yeah, you're right! i can't believe we hadn't noticed. alright, i'll keep that in mind for our next ui update

diy_bloke made it! (author)tzikis2016-02-09

actually there is a small nuisance. The down arrow of the scroll bar in codebender is covered by the formatting and print window. Not a big disaster, just a small nuisance
Other than that quite happy with codebender

diy_bloke (author)tzikis2015-09-28

Ok sorry for the many replies, but your instructable didnt work in my case, so I did it differently: you say get codebender link and embed in instructables. Doesnt work for me.
I got codebender embed code and just pasted that as html. That seems to work

tzikis (author)diy_bloke2015-09-28

glad to know it worked fine in the end! I'll check it out to see what's wrong with the way my Instructable mentioned

diy_bloke (author)tzikis2015-09-28

thanks. success

diy_bloke (author)tzikis2015-09-28

Bummer!!

diy_bloke (author)tzikis2015-09-28

Thanks. I am an avid user of codebender and though it still has some small bugs (that I am trying to work out with yr support team), I am very happy with it. it is a great project

hougaarden (author)2015-09-06

Hi,

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

TIMSK = TIMSK | 1<<OCIE1A | 1<<TOIE1;

}

ISR(TIMER1_COMPA_vect) {

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 ;)

diy_bloke (author)hougaarden2015-09-07

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

About This Instructable

3,208views

18favorites

License:

Bio: 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 ... More »
More by diy_bloke:Working With the Funduino W5100 Ethernet Module.Uploading Data to ThingSpeak With MQTTAdding an MCP23017 I/O Extender to Arduino or ESP8266
Add instructable to: