Universal Remote DIY with ATmega8

Here's a simple idea, to get a very small universal remote and replace its IC with an ATmega8 running a special Arduino code. But I wonder, has anybody does this before? Just checking so I don't reinvent things.

Here's one remote I got to test already:


Inside the main IC is hidden with the classic black-blob thingy. Not sure if I could just yank it out. ;-)

My main question is how to handle power. Will it always run, or I could use interrupts or whatever to know when a key was pressed?

Its still in the pre-building stage.

Thanks for any advice.


I can't see e-bay from here - is that an IR, or an RF remote?

I made an RF remote, it uses keypad press to interrupt ATMega from power down sleep mode, reads the key, transmits the key, goes back to sleep. Suppose same could be done for IR remote. Built up from 8 MHz promini, I should redo as standalone to reclaim the promini and cut down on components. Probably go to lower frequency too. With 1000mAH LiPo and MAX1811 battery charger chip, lasts over a month/charge with intermittent use 3 times a week.

Oh, nice to know that its possible. Its a Infrared, sorry I forgot to mention.

Please, let me know how do you read multiple keys and interrupt the chip to wake it up? I'm reading the datasheet and trying to understand a few things, but so far I couldn't figure out how to read, for instance, 6 buttons, and have each one wake up the chip.

Thanks again, Wk

I used 4x4 keypad, keypad.h library, Diode AND gate.

Do an advanced search for RF Remote & Crossroads, the schematic has been posted several times. I can send you the code from home tonight, remind me if you don't see anything by 11:30pm. I don't know if I ever posted that, or just portions of it, like interrupts, or sleep mode, when I answered queries about those. Anyway, was based on "simple remote for granny" that a Brit posted last summer in the old forum when I started Arduino-ing,with more pieces added as I figured stuff out. That was infrared for a TV remote, I wanted RF for use without worrying about line of sight blocking.

Thanks! I took a look at your schematics, but so far I can't understand how this will work. :blush: Tomorrow I will read more and see what I can figure from the diodes.


Ach, pullups, I get it now. So voltage is always running those wires. So when you press a button, any button, at least one wire will activate the interrupt pin, thanks to the diodes. 8) Nice!!!

Sorry for the dumb question now, but what kind of diodes I will need? Here's the ones I got in-house. ;-)

5 x 1N4148 - signal diode 200mA 5 x 1N4001 - 50V 1A

Got to order more different types of diodes, specially SMD ones if I want it to fit on the current tiny remote...


And I should receive this by next week: 3.6V Zener Diode 0.5W 500mW 1/2W DO35 RoHS

Its funny, from all the crap I got here, diodes are the least components I got. :blush:


You need the code to with it. While entering Sleep mode, the column outputs are written Low. Then when a key is pressed the cathode on the diode for that row is pulled low, creating a low on the interrupt pin (which has internal pullup enabled). Upon exiting Sleep mode, the column outputs are written High and the Keypad library is called to read the pin.

Writing the columns Low and High took me a bit to figure out - was not getting any interrupt while sleeping because the columns were all high.

I don' think the diodes matter much, I just used some small unmarked 25 year old small signal diodes I had in a drawer.

Makes total sense, thank you so much, again. :drooling_face: Takes me a while to figure things out... I got a DVD board that I could also take some SMD Diodes from it. :grin:


Here's the code William. http://www.crossroadsfencing.com/transmitter_Weapon_March2.pde right-click, save-target-as, rename to .pde

Thank you so much! I will report back once I have things working. 8)


Yes, it works, and its great! My Multitester doesn’t even show the amount of mA used (uA actually) during Power-Down, its really impressive. During usage is 25mA, not bad, since it lasts a few ms before it powers-down again.

I had to do some changes to the Infrared code to work on my ATmega8 chip, the one I’m using. Tests were done with a 3V battery and no external crystal. (just the chip actually) Question: do I need a capacitor for this? I see the U.Remote I got has a kinda big one inside.

Here’s my first DRAFT TEST code, just to keep things in motion. :wink:

Main file

// Power Saving based on code by CrossRoads - http://www.crossroadsfencing.com/BobuinoRev17

#include <avr/sleep.h>      // powerdown library
#include <avr/interrupt.h>  // interrupts library

void pin2Interrupt() { ; } // brings back from sleep.
int sleep_count = 0;      // flag/counter to tell us to go sleep
int pin2 = 2;               // Int0 interrupt pin
uint8_t pressedButton = 0;
uint8_t ligthsOnOff = 0;

void enterSleep()
  attachInterrupt(0, pin2Interrupt, LOW);
  pressedButton = 0;
  ADCSRA &= ~(1 << ADEN); // Disable ADC
  pinMode(10, INPUT);
  sleep_mode(); // now goes to Sleep and waits for the interrupt

  // The program will continue from here after the interrupt.
  detachInterrupt(0); //disable interrupts while we get ready to read the keypad 

void setup() 
  pinMode(13, INPUT);     
  digitalWrite(13, LOW);
  pinMode(5, INPUT);     
  digitalWrite(5, HIGH);
  pinMode(4, INPUT);     
  digitalWrite(4, HIGH);
  pinMode(pin2, INPUT);                 // our sleep interrupt pin
  digitalWrite(pin2, HIGH);

  // define all the unused pins as inputs with internal pullups for lower power state
  pinMode(0, INPUT);
  digitalWrite(0, HIGH);
  pinMode(1, INPUT);
  digitalWrite(1, HIGH);

void loop() 
  if (sleep_count>=1)
  if (!digitalRead(5)) pressedButton = 5;
    else if (!digitalRead(4)) pressedButton = 4;  

  if (pressedButton == 5)
    digitalWrite(13, HIGH);
      if (ligthsOnOff == 0) sendNEC(16236607, 32); else sendNEC(16203967, 32);
      ligthsOnOff = !ligthsOnOff;
  else if (pressedButton == 4)
    digitalWrite(13, HIGH);    delay(50);      digitalWrite(13, LOW);    delay(50);    digitalWrite(13, HIGH);    delay(50);      digitalWrite(13, LOW);    delay(50);    digitalWrite(13, HIGH);    delay(50);  
  else // Couldn't detect which button was pressed
    digitalWrite(13, HIGH);   delay(1000);      
  digitalWrite(13, LOW);

Infrasend code

// Based on the Infrared Lib by Ken Shirriff - http://arcfn.com/2009/08/multi-protocol-infrared-remote-library.html //
// WilliamK @ Beat707.com - Updated to work with the ATmega8 using Timer1 instead of Timer2

#define NEC_HDR_MARK	9000
#define NEC_HDR_SPACE	4500
#define NEC_BIT_MARK	560
#define NEC_ONE_SPACE	1600
#define NEC_ZERO_SPACE	560
#define NEC_RPT_SPACE	2250
#define TOPBIT 0x80000000

void mark(int time) 
  TCCR1A |= _BV(COM1B1); // Enable pin 10 PWM output

void space(int time) 
  TCCR1A &= ~(_BV(COM1B1)); // Disable pin 10 PWM output

void enableIROut(int khz) 
  pinMode(10, OUTPUT);
  digitalWrite(10, LOW);

  TCCR1A = _BV(WGM11) | _BV(WGM10);
  TCCR1B = _BV(WGM13) | _BV(CS10);
  OCR1A = F_CPU / 2 / khz / 1000;
  OCR1B = OCR1A / 3; // 33% duty cycle

void sendNEC(unsigned long data, int nbits)
  for (int i = 0; i < nbits; i++) {
    if (data & TOPBIT) {
    else {
    data <<= 1;


Timer 1 Details

  OC1A = Pin 9
  OC1B = Pin 10

  7      6      5      4      3     2     1     0 

  7      6      5      4      3     2     1     0 
  ICNC1  ICES1  -      WGM13  WGM12 CS12  CS11  CS10

  Timer 1 for Infrared Settings
  phase-correct PWM with OCRA as top = WGM13 WGM11 WGM10
  No Prescalar = CS10


The capacitor helps with power surges during high current draws. Try a smaller one, if operaion looks less steatd then before, keep the higher one.

Well, the Red mini-remote didn't work, its just too darn small. Once I started wiring things up, there was not much room left. I even replaced the 3V battery with a 0.333F super-capacitor (5.5V) to leave more empty space, but since I also needed some sort of programming + recharge header, space was gone too fast. This is my first case-mod, so I don't have the right tools and I'm not very good at this. :blush: I will receive another remote later this week which I will try again.

Another solution is to make a remote-translator instead, and put inside a bigger remote. The translator would "read" the original remote IR and just translate into whatever the Arduino code tells and output to the real IR LED. But there are some questions/tests before I can make this work:

1) can I remove the original IR LED from the big remote and connect the wires directly to the Arduino board and use the IR lib to read it just like I had a IR sensor attached to it? Or will I have to use a IR sensor instead?

2) can I power-down the ATmega chip and have it wake up when there's something happening in the IR sensor? If I connect things directly I don't see why it wouldn't work, right?

Them I could make a much easier "board" to put inside the big remote, where the batteries would normally go, and use a SuperCapacitor instead of 2x AA batteries.

Its a crazy idea, I know. ;-)


Hi, don’t you need some resistors between the digital output pins of the arduino and the keypad? usually when you have switches you have to put some resistor to make things “better”. I know that way will work but usually I have always seen the circuit with resistors.

Thanks for all

Did you have to do anything special to get the AtMega8 in and out of sleep mode? I have it working with an AtMega168, but the AtMega8 refuses to work. My code is at : https://github.com/ulrichard/jungleroom/blob/master/globe_board/globe_board.ino

Never mind. I had a flaky crystal. After finding out and replacing, sleep and waking works.