Abraxas3dPaul Williamson
Published © CC BY-NC-SA

Vader Vambrace

Hello. I am 9. I love Darth Vader. I want to turn a photon into a Vader Vambrace. This Vambrace turns off TVs!

BeginnerShowcase (no instructions)499
Vader Vambrace

Things used in this project

Hardware components

Photon
Particle Photon
×1
infrared LED
×1
Resistor 100 ohm
Resistor 100 ohm
×1
5 mm LED: Red
5 mm LED: Red
×1

Story

Read more

Schematics

How to hook up the parts for this project.

You put the infrared LED on the output pin. You put the red LED on another output pin. You can choose the pins in the program.

Code

allcodes.ino

C/C++
This is a program that translates the TVBGone database to be transmitted on an infrared LED by the UART PWM method demonstrated on Particle Photons by AnalysIR. With an IR LED, you can turn your Particle Photon into a TVBGone. This code allows you to use the TVBGone code database, so if codes are added to that, then this can read and transmit them.
// Vader Vambrace Code is based on example code from AnalysIR, and code from
// TVBGone. Additional code was written to interpret the TVBGone database
// entries into the same type of code that the Particle Photon PWM
// transmitter code from AnalysIR uses.
//
// The Vader Vambrace turns the Particle Photon into a TVBGone.
// Plus there are some buttons and LEDs.


/*
* Author: AnalysIR via http://www.AnalysIR.com/
*
* Date: 1st October 2015 V1.0
*
* License: Creative Commons, Attribution-NonCommercial-ShareAlike 4.0 International
*			http://creativecommons.org/licenses/by-nc-sa/4.0/
*
* For Commercial use or alternative License: Please contact the Author, via the website above
*
* Attribution: Please credit the Author on all media and provide a link to http://www.AnalysIR.com/
*
* Feedback: We would love to hear about how you use this software & suggestions for improvement.
*
*/


// Mostly taken from main.h in TVBGONE code version 1.2
#include <stdint.h>

#define	BIGGEST_NUMPAIRS	136

// Lets us calculate the size of the NA/EU databases
#define NUM_ELEM(x) (sizeof (x) / sizeof (*(x)));

// The structure of compressed code entries
struct IrCode {
  uint16_t timer_val;		// now just the frequency in Hz
  uint8_t numpairs;
  uint8_t bitcompression;
  uint16_t const *times;
  uint8_t codes[BIGGEST_NUMPAIRS];
};








//#include "sendcodes.c"
// Adapt TVbGone compressed data structures to Photon IR transmitting routine.
//
// 2016-01-28 ptw

// This is the function that sends an infrared code on the Photon.
//
//		sigArray is an array of durations in microseconds. Even indexed entries
//				are marks (carrier transmitted) and odd indexed entries are
//				spaces (delay with no transmission).
//		sizeArray is the length of sigArray
//		khz is the carrier frequency in kilohertz, which must be one of
//				30, 33, 36, 38, 40, 56 kHz. Any other value defaults to 38kHz.
extern void sendRawBuf(unsigned int *sigArray, unsigned int sizeArray, unsigned char kHz);

// The Photon IR sending routines use the UART for transmitting the carrier
// frequency. Unfortunately, that seems to limit the possible carrier
// frequencies to specific values. These are the supported values in kHz.
unsigned char valid_freqs[] = {30, 33, 36, 38, 40, 56};

// Given a precise frequency in Hertz, return the value from valid_freqs[]
// that is closest (in kilohertz).
unsigned char nearest_valid_carrier_frequency_to(unsigned int hz)
{
	int i;

	// Compare the precise value to the halfway point between valid frequencies.
	for (i=0; i < sizeof(valid_freqs)-1; i++) {
		if (hz < (valid_freqs[i]+valid_freqs[i+1])*1000/2)
			return valid_freqs[i];
	}

	return valid_freqs[i];
}


// This array of pointers to structures is the key to the TVbGone database.
extern const struct IrCode *NApowerCodes[];
extern const uint8_t num_NAcodes;

// Unpacking routines for the compressed format. Call init_unpacker() at
// the beginning of each signal, then call unpack_next_value() to get each successive
// value. The two routines share these global variables to maintain state.
int bits_per_pair;
uint8_t const *next_byte_to_unpack;
uint8_t this_byte;
int bits_left_in_this_byte;
void init_unpacker(uint8_t bitcompression, uint8_t const *compressed_codes)
{
	bits_per_pair = bitcompression;
	next_byte_to_unpack = compressed_codes;
	bits_left_in_this_byte = 0;
}

int unpack_next_value(void)
{
	int	value = 0;

	for (int i=0; i < bits_per_pair; i++) {
		// Get a new byte to unpack if we're out of bits in this_byte
		if (bits_left_in_this_byte <= 0) {
			this_byte = *next_byte_to_unpack++;
			bits_left_in_this_byte = 8;
		}

		// Grab a bit from this_byte
		int bit = !! (this_byte & 0x80);
		this_byte = this_byte << 1;
		bits_left_in_this_byte--;

		// Pack the bit into our output value
		value = (value << 1) | bit;
	}

	return value;
}


// Translate an infrared control signal from the TVbGone compressed format
// to the raw format we use.
//
// In compressed format, each entry is a few bits, packed into the bytes
// of the codes array. Those few bits index a table (provided as the array
// called times) which gives mark and space durations for that signal.
//
// In the raw format, we just list the durations: mark, space, mark, space, ...
//
// We are guaranteed that raw_durations is long enough to hold the results.
void translate_signal(  unsigned int *raw_durations,	// output array buffer
						uint8_t numpairs,				// number of mark+space pairs
						uint8_t bitcompression,			// number of bits per pair
						uint16_t const *times_table,	// table of duration values
						uint8_t	const compressed_codes[]		// packed code indices
						)
{
	init_unpacker(bitcompression, compressed_codes);

	for (int i=0; i < numpairs; i++) {
		int pair_index = unpack_next_value();
		unsigned int mark_duration = 10 * times_table[pair_index * 2];
		unsigned int space_duration = 10 * times_table[pair_index * 2 + 1];
			// TVbGone encodes durations in units of 10us!

		*raw_durations++ = mark_duration;
		*raw_durations++ = space_duration;
	}
}

// Send a code from the TVbGone database
void send_one_code(const struct IrCode *code)
{
	unsigned char khz = nearest_valid_carrier_frequency_to(code->timer_val);
	unsigned int sizeArray = code->numpairs * 2;
	unsigned int sigArray[BIGGEST_NUMPAIRS * 2];

	translate_signal(sigArray, code->numpairs, code->bitcompression, code->times, code->codes);

	sendRawBuf(sigArray, sizeArray, khz);
}

// Here is the main entry point to send all the infrared control codes.
void send_all_codes(unsigned int ms_delay_between_codes)
{
	for (int i=0; i < num_NAcodes; i++) {
		send_one_code(NApowerCodes[i]);
		delay(ms_delay_between_codes);
	}
}










// File taken from TVBGONE kit code version 1.2 and adapted for
// use on non-memory-constrained processor.

//#include "codes.h" //testing particle.ignore



// We want the North American codes only
#define NA_CODES

// PROGMEM keeps the data in ROM (flash) instead of copying it to RAM.
// This is important if RAM is scarce. Here, we don't need it, so define
// the macro to do nothing.
#define PROGMEM

// Originally the data structure stored a hardware-specific register value
// for the carrier frequency. We need to just store the frequency instead.
#define freq_to_timerval(x) x


//Codes captured from Generation 3 TV-B-Gone by Limor Fried & Mitch Altman
// table of POWER codes

#ifdef NA_CODES
const uint16_t code_na000Times[] PROGMEM = {
        60, 60,
        60, 2700,
        120, 60,
        240, 60,
};
const struct IrCode code_na000Code PROGMEM = {
        freq_to_timerval(38400),
        26,             // # of pairs
        2,              // # of bits per index
        code_na000Times,
        {
                0xE2,
                0x20,
                0x80,
                0x78,
                0x88,
                0x20,
                0x10,
        }
};






const uint16_t code_na001Times[] PROGMEM = {
	50, 100,
	50, 200,
	50, 800,
	400, 400,
};
const struct IrCode code_na001Code PROGMEM = {
	freq_to_timerval(57143),
	52,		// # of pairs
	2,		// # of bits per index
	code_na001Times,
	{
		0xD5,
		0x41,
		0x11,
		0x00,
		0x14,
		0x44,
		0x6D,
		0x54,
		0x11,
		0x10,
		0x01,
		0x44,
		0x45,
	}
};






const uint16_t code_na002Times[] PROGMEM = {
	42, 46,
	42, 133,
	42, 7519,
	347, 176,
	347, 177,
};
const struct IrCode code_na002Code PROGMEM = {
	freq_to_timerval(37037),
	100,		// # of pairs
	3,		// # of bits per index
	code_na002Times,
	{
		0x60,
		0x80,
		0x00,
		0x00,
		0x00,
		0x08,
		0x00,
		0x00,
		0x00,
		0x20,
		0x00,
		0x00,
		0x04,
		0x12,
		0x48,
		0x04,
		0x12,
		0x48,
		0x2A,
		0x02,
		0x00,
		0x00,
		0x00,
		0x00,
		0x20,
		0x00,
		0x00,
		0x00,
		0x80,
		0x00,
		0x00,
		0x10,
		0x49,
		0x20,
		0x10,
		0x49,
		0x20,
		0x80,
	}
};






const uint16_t code_na003Times[] PROGMEM = {
	26, 185,
	27, 80,
	27, 185,
	27, 4549,
};
const struct IrCode code_na003Code PROGMEM = {
	freq_to_timerval(38610),
	64,		// # of pairs
	2,		// # of bits per index
	code_na003Times,
	{
		0x15,
		0x5A,
		0x65,
		0x67,
		0x95,
		0x65,
		0x9A,
		0x9B,
		0x95,
		0x5A,
		0x65,
		0x67,
		0x95,
		0x65,
		0x9A,
		0x99,
	}
};








const uint16_t code_na004Times[] PROGMEM = {
	55, 57,
	55, 170,
	55, 3949,
	55, 9623,
	56, 0,
	898, 453,
	900, 226,
};
const struct IrCode code_na004Code PROGMEM = {
	freq_to_timerval(38610),
	38,		// # of pairs
	3,		// # of bits per index
	code_na004Times,
	{
		0xA0,
		0x00,
		0x01,
		0x04,
		0x92,
		0x48,
		0x20,
		0x80,
		0x40,
		0x04,
		0x12,
		0x09,
		0x2B,
		0x3D,
		0x00,
	}
};


const uint16_t code_na005Times[] PROGMEM = {
	88, 90,
	88, 91,
	88, 181,
	88, 8976,
	177, 91,
};
const struct IrCode code_na005Code PROGMEM = {
	freq_to_timerval(35714),
	24,		// # of pairs
	3,		// # of bits per index
	code_na005Times,
	{
		0x10,
		0x92,
		0x49,
		0x46,
		0x33,
		0x09,
		0x24,
		0x94,
		0x60,
	}
};
const uint16_t code_na006Times[] PROGMEM = {
	50, 62,
	50, 172,
	50, 4541,
	448, 466,
	450, 465,
};
const struct IrCode code_na006Code PROGMEM = {
	freq_to_timerval(38462),
	68,		// # of pairs
	3,		// # of bits per index
	code_na006Times,
	{
		0x64,
		0x90,
		0x00,
		0x04,
		0x90,
		0x00,
		0x00,
		0x80,
		0x00,
		0x04,
		0x12,
		0x49,
		0x2A,
		0x12,
		0x40,
		0x00,
		0x12,
		0x40,
		0x00,
		0x02,
		0x00,
		0x00,
		0x10,
		0x49,
		0x24,
		0x90,
	}
};
const uint16_t code_na007Times[] PROGMEM = {
	49, 49,
	49, 50,
	49, 410,
	49, 510,
	49, 12107,
};
const struct IrCode code_na007Code PROGMEM = {
	freq_to_timerval(39216),
	34,		// # of pairs
	3,		// # of bits per index
	code_na007Times,
	{
		0x09,
		0x94,
		0x53,
		0x29,
		0x94,
		0xD9,
		0x85,
		0x32,
		0x8A,
		0x65,
		0x32,
		0x9B,
		0x20,
	}
};
const uint16_t code_na008Times[] PROGMEM = {
	56, 58,
	56, 170,
	56, 4011,
	898, 450,
	900, 449,
};
const struct IrCode code_na008Code PROGMEM = {
	freq_to_timerval(38462),
	68,		// # of pairs
	3,		// # of bits per index
	code_na008Times,
	{
		0x64,
		0x00,
		0x49,
		0x00,
		0x92,
		0x00,
		0x20,
		0x82,
		0x01,
		0x04,
		0x10,
		0x48,
		0x2A,
		0x10,
		0x01,
		0x24,
		0x02,
		0x48,
		0x00,
		0x82,
		0x08,
		0x04,
		0x10,
		0x41,
		0x20,
		0x90,
	}
};
const uint16_t code_na009Times[] PROGMEM = {
	53, 56,
	53, 171,
	53, 3950,
	53, 9599,
	898, 451,
	900, 226,
};
const struct IrCode code_na009Code PROGMEM = {
	freq_to_timerval(38462),
	38,		// # of pairs
	3,		// # of bits per index
	code_na009Times,
	{
		0x84,
		0x90,
		0x00,
		0x20,
		0x80,
		0x08,
		0x00,
		0x00,
		0x09,
		0x24,
		0x92,
		0x40,
		0x0A,
		0xBA,
		0x40,
	}
};
const uint16_t code_na010Times[] PROGMEM = {
	51, 55,
	51, 158,
	51, 2286,
	841, 419,
};
const struct IrCode code_na010Code PROGMEM = {
	freq_to_timerval(38462),
	52,		// # of pairs
	2,		// # of bits per index
	code_na010Times,
	{
		0xD4,
		0x00,
		0x15,
		0x10,
		0x25,
		0x00,
		0x05,
		0x44,
		0x09,
		0x40,
		0x01,
		0x51,
		0x01,
	}
};
const uint16_t code_na011Times[] PROGMEM = {
	55, 55,
	55, 172,
	55, 4039,
	55, 9348,
	56, 0,
	884, 442,
	885, 225,
};
const struct IrCode code_na011Code PROGMEM = {
	freq_to_timerval(38462),
	38,		// # of pairs
	3,		// # of bits per index
	code_na011Times,
	{
		0xA0,
		0x00,
		0x41,
		0x04,
		0x92,
		0x08,
		0x24,
		0x90,
		0x40,
		0x00,
		0x02,
		0x09,
		0x2B,
		0x3D,
		0x00,
	}
};
const uint16_t code_na012Times[] PROGMEM = {
	81, 87,
	81, 254,
	81, 3280,
	331, 336,
	331, 337,
};
const struct IrCode code_na012Code PROGMEM = {
	freq_to_timerval(38462),
	52,		// # of pairs
	3,		// # of bits per index
	code_na012Times,
	{
		0x64,
		0x12,
		0x08,
		0x24,
		0x00,
		0x08,
		0x20,
		0x10,
		0x09,
		0x2A,
		0x10,
		0x48,
		0x20,
		0x90,
		0x00,
		0x20,
		0x80,
		0x40,
		0x24,
		0x90,
	}
};
const uint16_t code_na013Times[] PROGMEM = {
	53, 55,
	53, 167,
	53, 2304,
	53, 9369,
	893, 448,
	895, 447,
};
const struct IrCode code_na013Code PROGMEM = {
	freq_to_timerval(38462),
	48,		// # of pairs
	3,		// # of bits per index
	code_na013Times,
	{
		0x80,
		0x12,
		0x40,
		0x04,
		0x00,
		0x09,
		0x00,
		0x12,
		0x41,
		0x24,
		0x82,
		0x01,
		0x00,
		0x10,
		0x48,
		0x24,
		0xAA,
		0xE8,
	}
};

/* Duplicate timing table, same as na004 !
const uint16_t code_na014Times[] PROGMEM = {
	55, 57,
	55, 170,
	55, 3949,
	55, 9623,
	56, 0,
	898, 453,
	900, 226,
};
*/
const struct IrCode code_na014Code PROGMEM = {
	freq_to_timerval(38462),
	38,		// # of pairs
	3,		// # of bits per index
	code_na004Times,
	{
		0xA0,
		0x00,
		0x09,
		0x04,
		0x92,
		0x40,
		0x24,
		0x80,
		0x00,
		0x00,
		0x12,
		0x49,
		0x2B,
		0x3D,
		0x00,
	}
};

/* Duplicate timing table, same as na004 !
const uint16_t code_na015Times[] PROGMEM = {
	55, 57,
	55, 170,
	55, 3949,
	55, 9623,
	56, 0,
	898, 453,
	900, 226,
};
*/
const struct IrCode code_na015Code PROGMEM = {
	freq_to_timerval(38462),
	38,		// # of pairs
	3,		// # of bits per index
	code_na004Times,
	{
		0xA0,
		0x80,
		0x01,
		0x04,
		0x12,
		0x48,
		0x24,
		0x00,
		0x00,
		0x00,
		0x92,
		0x49,
		0x2B,
		0x3D,
		0x00,
	}
};
const uint16_t code_na016Times[] PROGMEM = {
	28, 90,
	28, 211,
	28, 2507,
};
const struct IrCode code_na016Code PROGMEM = {
	freq_to_timerval(34483),
	34,		// # of pairs
	2,		// # of bits per index
	code_na016Times,
	{
		0x54,
		0x04,
		0x10,
		0x00,
		0x95,
		0x01,
		0x04,
		0x00,
		0x10,
	}
};
const uint16_t code_na017Times[] PROGMEM = {
	56, 57,
	56, 175,
	56, 4150,
	56, 9499,
	898, 227,
	898, 449,
};
const struct IrCode code_na017Code PROGMEM = {
	freq_to_timerval(40000),
	38,		// # of pairs
	3,		// # of bits per index
	code_na017Times,
	{
		0xA0,
		0x02,
		0x48,
		0x04,
		0x90,
		0x01,
		0x20,
		0x80,
		0x40,
		0x04,
		0x12,
		0x09,
		0x2A,
		0x38,
		0x00,
	}
};
const uint16_t code_na018Times[] PROGMEM = {
	51, 55,
	51, 161,
	51, 2566,
	849, 429,
	849, 430,
};
const struct IrCode code_na018Code PROGMEM = {
	freq_to_timerval(38462),
	136,		// # of pairs
	3,		// # of bits per index
	code_na018Times,
	{
		0x60,
		0x82,
		0x08,
		0x24,
		0x10,
		0x41,
		0x00,
		0x12,
		0x40,
		0x04,
		0x80,
		0x09,
		0x2A,
		0x02,
		0x08,
		0x20,
		0x90,
		0x41,
		0x04,
		0x00,
		0x49,
		0x00,
		0x12,
		0x00,
		0x24,
		0xA8,
		0x08,
		0x20,
		0x82,
		0x41,
		0x04,
		0x10,
		0x01,
		0x24,
		0x00,
		0x48,
		0x00,
		0x92,
		0xA0,
		0x20,
		0x82,
		0x09,
		0x04,
		0x10,
		0x40,
		0x04,
		0x90,
		0x01,
		0x20,
		0x02,
		0x48,
	}
};
const uint16_t code_na019Times[] PROGMEM = {
	40, 42,
	40, 124,
	40, 4601,
	325, 163,
	326, 163,
};
const struct IrCode code_na019Code PROGMEM = {
	freq_to_timerval(38462),
	100,		// # of pairs
	3,		// # of bits per index
	code_na019Times,
	{
		0x60,
		0x10,
		0x40,
		0x04,
		0x80,
		0x09,
		0x00,
		0x00,
		0x00,
		0x00,
		0x10,
		0x00,
		0x20,
		0x10,
		0x00,
		0x20,
		0x80,
		0x00,
		0x0A,
		0x00,
		0x41,
		0x00,
		0x12,
		0x00,
		0x24,
		0x00,
		0x00,
		0x00,
		0x00,
		0x40,
		0x00,
		0x80,
		0x40,
		0x00,
		0x82,
		0x00,
		0x00,
		0x00,
	}
};
const uint16_t code_na020Times[] PROGMEM = {
	60, 55,
	60, 163,
	60, 4099,
	60, 9698,
	61, 0,
	898, 461,
	900, 230,
};
const struct IrCode code_na020Code PROGMEM = {
	freq_to_timerval(38462),
	38,		// # of pairs
	3,		// # of bits per index
	code_na020Times,
	{
		0xA0,
		0x10,
		0x00,
		0x04,
		0x82,
		0x49,
		0x20,
		0x02,
		0x00,
		0x04,
		0x90,
		0x49,
		0x2B,
		0x3D,
		0x00,
	}
};
const uint16_t code_na021Times[] PROGMEM = {
	48, 52,
	48, 160,
	48, 400,
	48, 2335,
	799, 400,
};
const struct IrCode code_na021Code PROGMEM = {
	freq_to_timerval(38462),
	38,		// # of pairs
	3,		// # of bits per index
	code_na021Times,
	{
		0x80,
		0x10,
		0x40,
		0x08,
		0x82,
		0x08,
		0x01,
		0xC0,
		0x08,
		0x20,
		0x04,
		0x41,
		0x04,
		0x00,
		0x00,
	}
};
...

This file has been truncated, please download it to see its full contents.

Credits

Abraxas3d

Abraxas3d

1 project • 7 followers
I enjoy thinking and doing. Not necessarily in that order.
Paul Williamson

Paul Williamson

1 project • 2 followers
if there's no other explanation, it must be art.
Thanks to Analysis IR and TVBGone.

Comments