arduino tvbgone

does anybody know where I can get the code for an arduino based tvbgone ? thanks ~Matt

Picture of arduino tvbgone
sort by: active | newest | oldest
joehudy6 years ago
can some one just post the code so other people can copy and past it in to your arduino
kenshirriff7 years ago
 I've ported the TV-B-Gone code to run on the Arduino.  The timer code in particular required changes to work with the ATmega328 and the different clock speed.  See details at arcfn.com/2009/12/tv-b-gone-for-arduino.html.
arduino-tv-b-gone1.jpg
iman (author)  kenshirriff7 years ago
Friggin Sweet ! thanks man , I'm gonna try this out tonight  =D
iman (author) 9 years ago
ok I am going to get in contact with the tvbgone peeps and get all the tv codes and write the code myself :) unless I can find another way
guyfrom7up iman9 years ago
well, the original code is probably written in C since it's for an avr. You'd probably have to reprogram the whole thing so that it works for the arduino software, and arduino hardware.
iman (author)  guyfrom7up9 years ago
well I saw someone made a remote for a philips tv here is the code brand(PHILIPSTV) ; button(POWER,2) ; // hello world delay(15000) ; button(ZERO,2) ; // change channel to 03 delay(100) ; button(THREE,2) ; delay(100) ; button(MUTE,2) ; // mute the TV delay(15000) ; button(POWER,2) ; // over and out It doesn't look too hard.
iman (author)  iman9 years ago
oops sry missed the code

// RC5 Infrared Transmitter for Arduino Diecimila
//
// Two timers are used, TIMER2 and TIMER1. TIMER1 is used as the RC5 state machine clock,
// with tick length of irparams.t (e.g., 889 microseconds), the basic RC5 time unit.
// The on/off state of the IR LED carrier (pulse clock) may change on any given tick of
// this clock.
//
// TIMER2 is used to generate a square wave on OC2A (pin 11) at the frequency of the RC5
// pulse clock (e.g., 36 kHz). The pulse clock is modulated (turned on and off) by setting
// or clearing the COM2A0 bit of register TCCR2A. Therefore, an IR LED connected between
// pin 11 and ground is the only external circuitry needed to implement the basic IR
// transmitter.
//
// Using a high power IR LED (Vishay TSAL6100) connected this way (without a current-
// limiting resistor) results in an "on" current of about 80ma. This is within spec of
// that device (100ma max). The Arduino output pins are specced at 40ma max, so the
// current of 80ma exceeds the Arduino spec, but the duty cycle is low (50% max),
// so it's probably OK.
//
// RC5 encoding:
//
// START + TOGGLEBIT + UNITCODE + BUTTONCODE
//
// where:
// START is a two-bit code, always 11
// TOGGLEBIT is a one-bit code which toggles on each successive button
// UNITCODE is a five-bit code specifying the unit being commanded (TV, VCR, etc.)
// BUTTONCODE is a six-bit code for the button command
//
// Each bit, 0 or 1, is transmitted according to "Manchester" encoding:
//
// 0: MARK followed by SPACE, each of duration irparams.t
// 1: SPACE followed by MARK
//
// To adapt this code to use another RC5-compatible device, minimally
// the unit code needs to be set according to the device, and any
// specific button encodings need to be defined in irparams.h. Note
// the function brand() where the buttons and other parameters are
// actually loaded into the state machine structure.
//
// The demo program below simply sets the brand to PHILIPSTV,
// turns power on, waits 15 seconds, sets channel to 03, mutes the TV,
// waits 15 seconds, and turns the TV off.
//
// Note that the call to button(buttonid,retransmitcount) returns
// before the code is finished transmitting, so successive calls should
// be separted by at least some delay, e.g., 100 msec. The retransmission
// count is 2 here because that seems to be common.
//
// For more info on RC5, see: http://www.sbprojects.com/knowledge/ir/rc5.htm
//
// Joe Knapp jmknapp AT gmail DOT com 30APR08

#include "irparams.h"

#define IROUT 11 // pin 11 is OC2A output from TIMER2
#define BLINKLED 13 // mirrors the state of IROUT

#define TICKSPERUSEC ((SYSCLOCK/1000000.)/PRESCALE)
#define mark() (irparams.irledstate = 1)
#define space() (irparams.irledstate = 0)

// xmitter states
#define START 1
#define STOP 2
#define IDLE 3
#define REXMIT 4
#define CODE 5
#define MANCHONE 6
#define MANCHZERO 7
#define TOGGLE 8

// Pulse clock interrupt uses 16-bit TIMER1
#define INIT_TIMER_COUNT1 (65536 - (int)(TICKSPERUSEC*irparams.t))
#define RESET_TIMER1 TCNT1 = INIT_TIMER_COUNT1

// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

// function prototypes
void button(byte buttonid, int n) ;
void brand(byte brandcode) ;
uint8_t timer2top(unsigned int freq) ;
unsigned long buttoncode(byte buttonid) ;

// state machine variables
struct rbutton {
byte id ;
unsigned long code ; // button codes can be up to 32 bits
} ;
struct {
byte xmitstate ;
byte returnstate ;
byte timer ;
byte unitlength ;
byte buttonlength ;
byte sendflag ;
byte retransmit ;
byte codelen ;
byte bitcounter ;
byte togbit ;
byte nbuttons ;
byte blinkstate ;
byte irledstate ;
unsigned long unit ;
unsigned long button ;
unsigned long code1 ;
unsigned int mask16 ;
unsigned int t ;
unsigned int retransgap ;
struct rbutton buttons[MAXBUTTONS] ;
} irparams ;

void setup() {
Serial.begin(9600) ;
Serial.println("XMITIR 0.0.0.1a") ;

cbi(TCCR2A,COM2A1) ; // disconnect OC2A for now (COM2A0 = 0)
cbi(TCCR2A,COM2A0) ;

cbi(TCCR2B,WGM22) ; // CTC mode for TIMER2
sbi(TCCR2A,WGM21) ;
cbi(TCCR2A,WGM20) ;

TCNT2 = 0 ;

cbi(ASSR,AS2) ; // use system clock for timer 2

OCR2A = 255 ; // set TOP to 255 for now

cbi(TCCR2B,CS22) ; // TIMER2 prescale = 1
cbi(TCCR2B,CS21) ;
sbi(TCCR2B,CS20) ;

cbi(TCCR2B,FOC2A) ; // clear forced output compare bits
cbi(TCCR2B,FOC2B) ;

pinMode(IROUT, OUTPUT) ; // set OC2A to OUPUT
pinMode(BLINKLED, OUTPUT) ;
digitalWrite(BLINKLED, LOW) ;

// setup pulse clock timer interrupt
TCCR1A = 0; // normal mode

//Prescale /8 (16M/8 = 0.5 microseconds per tick)
// Therefore, the timer interval can range from 0.5 to 128 microseconds
// depending on the reset value (255 to 0)
cbi(TCCR1B,CS12) ;
sbi(TCCR1B,CS11) ;
cbi(TCCR1B,CS10) ;

//Timer1 Overflow Interrupt Enable
sbi(TIMSK1,TOIE1) ;

RESET_TIMER1;

sei(); // enable interrupts

// initialize some state machine variables
irparams.sendflag = 0 ;
irparams.togbit = 0 ;
irparams.blinkstate = HIGH ;
irparams.xmitstate = IDLE ;
}

// main loop
// Just for a demo, the code here the first time through just sets
// the brand to PHILIPSTV, turns the TV on, sets the channel to THREE,
// mutes the TV and finally turns the TV off.
void loop() {
static byte first = 1 ;
if (first) {
brand(PHILIPSTV) ;
button(POWER,2) ; // hello world
delay(15000) ;
button(ZERO,2) ;
delay(100) ;
button(THREE,2) ;
delay(100) ;
button(MUTE,2) ;
delay(15000) ;
button(POWER,2) ; // over and out
first = 0 ;
}
}

// xmit state machine
// RC5 protocol
ISR(TIMER1_OVF_vect) {
RESET_TIMER1;

switch(irparams.xmitstate) {
case START:
if (irparams.timer == 4) {
irparams.code1 = ((unsigned long)irparams.unit << irparams.buttonlength) | irparams.button ;
irparams.codelen = irparams.unitlength + irparams.buttonlength ;
irparams.mask16 = (unsigned int)0x1 << (irparams.codelen - 1) ;
}

irparams.timer-- ;
switch(irparams.timer) {
case 3:
mark() ;
break ;
case 2:
space() ;
break ;
case 1:
mark() ;
irparams.xmitstate = TOGGLE ;
break ;
}
break ;
case TOGGLE:
irparams.returnstate = CODE ; // go to CODE after toggle bit
irparams.bitcounter = 0 ;
if (irparams.togbit) {
space() ;
irparams.xmitstate = MANCHONE ;
}
else {
mark() ;
irparams.xmitstate = MANCHZERO ;
}
break ;
case CODE:
irparams.returnstate = CODE ;
if (irparams.bitcounter == irparams.codelen) {
space() ;
irparams.xmitstate = STOP ;
}
else {
if (irparams.code1 & irparams.mask16) { // send ONE
space() ;
irparams.xmitstate = MANCHONE ;
}
else {
mark() ;
irparams.xmitstate = MANCHZERO ;
}
irparams.bitcounter++ ;
irparams.mask16 >>= 1 ;
}
break ;
case STOP:
if (irparams.retransmit) {
irparams.xmitstate = REXMIT ;
irparams.timer = irparams.retransgap ;
irparams.sendflag = 0 ;
}
else {
irparams.xmitstate = IDLE ;
irparams.sendflag = 0 ;
space() ;
irparams.togbit = 0x1 ;
}
break ;
case IDLE:
if (irparams.sendflag) {
irparams.xmitstate = START ;
space() ;
irparams.timer = 4 ; // RC5 start is SPACE/MARK/SPACE/MARK
}
break ;
case MANCHONE:
mark() ;
irparams.xmitstate = irparams.returnstate ;
break ;
case MANCHZERO:
space() ;
irparams.xmitstate = irparams.returnstate ;
break ;
case REXMIT:
irparams.timer-- ;
if (irparams.timer == 0) {
irparams.sendflag = 1 ;
irparams.xmitstate = IDLE ;
irparams.retransmit-- ;
}
break ;
}

// update LEDs
if (irparams.irledstate) {
digitalWrite(BLINKLED, HIGH) ;
sbi(TCCR2A,COM2A0) ; // connect pulse clock
}
else {
digitalWrite(BLINKLED, LOW) ;
cbi(TCCR2A,COM2A0) ; // disconnect pulse clock
}
}
// end RC5 state machine

// send code for given buttonid, repeat n times
void button(byte buttonid, int n)
{
irparams.button = buttoncode(buttonid) ; // get code
irparams.retransmit = n - 1;
irparams.sendflag = 1; // flag for the ISR to send irparams.button
}

// return ir code for given buttonid
unsigned long buttoncode(byte buttonid)
{
int i ;
byte found ;

i = 0 ;
found = 0 ;
while (!found && (i < irparams.nbuttons)) {
if (buttonid == irparams.buttons[i].id) {
found = 1 ;
}
else
i++ ;
}
if (found)
return(irparams.buttons[i].code) ;
else
return(0) ; // ERROR
}

// set parameters for given brand
void brand(byte brandcode)
{
int i ;
switch(brandcode) {
case PHILIPSTV:
OCR2A = timer2top(PHILIPSTV_PULSECLOCK) ; // sets TOP value for TIMER2
irparams.unit = PHILIPSTV_UNIT ;
irparams.unitlength = PHILIPSTV_UNITLENGTH ;
irparams.buttonlength = PHILIPSTV_BUTTONLENGTH ;
irparams.t = PHILIPSTV_T ;
irparams.retransgap = PHILIPSTV_RETRANSGAP ;

// buttons
irparams.nbuttons = 0 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B01 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C01 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B02 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C02 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B03 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C03 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B04 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C04 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B05 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C05 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B06 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C06 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B07 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C07 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B08 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C08 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B09 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C09 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B10 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C10 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B11 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C11 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B12 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C12 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B13 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C13 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B14 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C14 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B15 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C15 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B16 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C16 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B17 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C17 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B18 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C18 ;
irparams.buttons[irparams.nbuttons].id = PHILIPSTV_B19 ;
irparams.buttons[irparams.nbuttons++].code = PHILIPSTV_C19 ;
break ;
default:
Serial.println("ERROR: brand not found") ;
break ;
}
}

// return TIMER2 TOP value per given desired frequency (Hz)
uint8_t timer2top(unsigned int freq)
{
return((byte)((unsigned long)SYSCLOCK/2/freq) - 1) ;
}
Wow! That is a great Idea! I am very interested in this idea. I have 2 tv-b-gone kits and the tv-b-gone pro and an arduino so this looks like a great project. Please let me know if you figure this out. Thanks Joe