Universal IR Remote using Arduino

Hello

I am just a beginner programer and need guidance.

I have successfully built an IR remote using arduino Nano to control my T.V with 15 buttons.

My issue is it possible to control different appliances such as (A.C, Subwoofer, Fan, another T.V ...etc) with the same remote that I built?

I mean as example if mode 1 selected, then I can control the tv using the 15 buttons, if mode 2 selected, I can use the Subwoofer with the 15 buttons, if mode 3 selected .. etc.

Like the universal remote.

I do think it's a coding issue, and my programming skills are very basic, so is there anyone successfully made this project can share the code with me?

Thank you so much.

Depending on how you have configured the buttons, you may be able to press 2 different buttons simultaneously to select a mode. You could also dedicate one button for mode selection, then toggle through the modes. Different devices may use different IR coding schemes and carrier frequencies. Some devices, especially air conditioners, can have very long code sequences.

Yes thats what I need to do, just to dedicate a button for mode, and toggle to other modes using it, but unfortunately I don't know how to write the code for it, I just used one of the tutorials and edit it to make the remote.
Is there any code example that I can follow that you suggest?

Post the code you have already written to make it easier to suggest something.
However, in principle, one button simply controls a counter. The counter determines what mode the device is in. Once the maximum number of modes has been reached, the counter then starts again from zero. The effect of the other buttons is conditioned by the mode.

Here is the code that I used, just need the modification for modes as you kindly said.

#include <IRremote.h>
#include “LowPower.h”

IRsend irsend;

const int b1 = 1; //Power
const int b2 = 15; //function
const int b3 = 2; //vol down
const int b4 = 4; //vol up
const int b5 = 5; //up
const int b6 = 6; //Folder Next
const int b7 = 7; //Enter
const int b8 = 8; //right
const int b9 = 9; //down
const int b10 = 17; //Display
const int b11 = 11; //Play
const int b12 = 12; //Stop
const int b13 = 16; //Prev
const int b14 = 14; //Next

int timer;
int modeCounter = 0;

void wakeUp() {
timer = 0;
}

void setup() {
pinMode(LED_BUILTIN, OUTPUT);
pinMode(b1, INPUT);
pinMode(b2, INPUT);
pinMode(b3, INPUT);
pinMode(b4, INPUT);
pinMode(b5, INPUT);
pinMode(b6, INPUT);
pinMode(b7, INPUT);
pinMode(b8, INPUT);
pinMode(b9, INPUT);
pinMode(b10, INPUT);
pinMode(b11, INPUT);
pinMode(b12, INPUT);
pinMode(b13, INPUT);
pinMode(b14, INPUT);

}

void loop() {
attachInterrupt(0, wakeUp, HIGH);
while (timer < 10000) {
if (digitalRead(b1) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0xA81, 12); //Power
}

if (digitalRead(b2) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0x4B09, 15); //Function
}

if (digitalRead(b3) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0xC81, 12); //Vol_Down
}

if (digitalRead(b4) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0x481, 12); //Vol_Up
}

if (digitalRead(b5) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0x1EB9C, 20); //up
}

if (digitalRead(b6) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0xF4B9C, 20); //Folder Next
}

if (digitalRead(b7) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0x3EB9C, 20); //Enter
}

if (digitalRead(b8) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0xDEB9C, 20); //right
}

if (digitalRead(b9) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0x9EB9C, 20); //down
}
if (digitalRead(b10) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0x18B9C, 20); //Display
}
if (digitalRead(b11) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0x4CB9C, 20); //Play
}
if (digitalRead(b12) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0x1CB9C, 20); //Stop
}
if (digitalRead(b13) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0xCB9C, 20); //Prev
}
if (digitalRead(b14) == HIGH) {
timer = 0;
delay(50);
irsend.sendSony(0x8CB9C, 20); //Next
}

delay(1);
timer = timer + 1;

}
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
}

Any suggestions?

Select one of the buttons to be dedicated to the mode switch. Let's say button b2 (pin 15) but choose anyone you like.

Set up the global variable:

bool modeChange = false ;   // global

In the loop(), add the following

if (digitalRead(b2) == HIGH) {
   modeChange = ! modeChange ; // toggle
   delay( 50 ) ;  // crude de-bounce
}

You'll also have to remove (or alter) the original code which used button b2.

Now, taking button b5 code in the loop() as an example, we can change its function to
depend on the state of modeChange.

 if (digitalRead(b5) == HIGH) {
      timer = 0;
      delay(50);
      if ( modeChange == false ) {
          irsend.sendSony(0x1EB9C, 20); //up  - original code
      }
      else {
          irsend.xxxxxxxx  ;  //  new code
      }
    }

Note: I'm assuming that everything worked before and that the buttons are wired on the high side, that is pressing a button forces the pin high.

Thank you so much, will try that out and get back to you for results.

THANK YOU, it worked like a charm, but what if i would like more modes?

hanynaeem:
THANK YOU, it worked like a charm, but what if i would like more modes?

int modeChange = 0 ;   // global
const int NUMBEROFMODES = 3;
...
if (digitalRead(b2) == HIGH) {
   modeChange++; // increment
   if (modeChange > NUMBEROFMODES) modeChange = 0;
   delay( 50 ) ;  // crude de-bounce
}

And what about this part of the code, is it will be the same?
Where to add the new send code?
Thanks.

if (digitalRead(b5) == HIGH) {
timer = 0;
delay(50);
if ( modeChange == false ) {
irsend.sendSony(0x1EB9C, 20); //up - original code
}
else {
irsend.xxxxxxxx ; // new code
}
}

hanynaeem:
And what about this part of the code, is it will be the same?
Where to add the new send code?
Thanks.

if (digitalRead(b5) == HIGH) {
timer = 0;
delay(50);
if ( modeChange == false ) {
irsend.sendSony(0x1EB9C, 20); //up - original code
}
else {
irsend.xxxxxxxx ; // new code
}
}

Sorry, I forgot that you will have to change modeChange from a bool to an int. Then you would have something like

if (digitalRead(b5) == HIGH) {
      timer = 0;
      delay(50);
      if ( modeChange == 0 ) {      // or 1, 2, 3...
          irsend.sendSony(0x1EB9C, 20); //up - original code
      }
      else {
          irsend.xxxxxxxx ; // new code
      }
    }

Where to add the new send code?

What new send code? I have no idea what you're talking about.

I added the code like so, but it keeps pulling the modes randomly

void loop() {
{
if (digitalRead(b2) == HIGH) {
modeChange++; // increment
if (modeChange > NUMBEROFMODES) modeChange = 0;
delay( 100 ) ; // crude de-bounce
}

if (digitalRead(b1) == HIGH) {
timer = 0;
delay(100);
if ( modeChange == 0 ) { // or 1, 2, 3...
timer = 0;
delay(100);
irsend.sendNEC(0x20202FD, 32); //Menu
}
else if ( modeChange == 1 ) { // or 1, 2, 3...
timer = 0;
delay(100);
irsend.sendNEC(0x202A857, 32); //Vup
}
else if ( modeChange == 2 ) { // or 1, 2, 3...
timer = 0;
delay(100);
irsend.sendNEC(0x202F00F, 32); //Mute
}
else if ( modeChange == 3 ) { // or 1, 2, 3...
timer = 0;
delay(100);
irsend.sendNEC(0x202827D, 32); //Source
}

}

Any help?

I guess the problem may be that you are not able to keep track of the current mode.
Ideally, you'd use Serial.print() for debugging but it looks like you've used all the pins.

How have you defined modeChange ? Post all you latest code.

I am using a breadboard now with 2 buttons only

#include <IRremote.h>

IRsend irsend;

const int b1  = 4;  //Power
const int b2  = 5;  //mode

int timer;
int modeCounter = 0;
int modeChange = 0 ;   // global
const int NUMBEROFMODES = 3;


void wakeUp() {
  timer = 0;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(b1, INPUT);
  pinMode(b2, INPUT);

}

void loop() {
             {
    if (digitalRead(b2) == HIGH) {
   modeChange++; // increment
   if (modeChange > NUMBEROFMODES) modeChange = 0;
   delay(100) ;  // crude de-bounce
             }

    if (digitalRead(b1) == HIGH) {
      timer = 0;
      delay(100);
      if ( modeChange == 0 ) {      // or 1, 2, 3...
      timer = 0;
      delay(100);
      irsend.sendNEC(0x20202FD, 32); //Menu
    }
      else if ( modeChange == 1 ) {      // or 1, 2, 3...
      timer = 0;
      delay(100);
      irsend.sendNEC(0x202A857, 32); //Vup
      }
       else if ( modeChange == 2 ) {      // or 1, 2, 3...
      timer = 0;
      delay(100);
      irsend.sendNEC(0x202F00F, 32); //Mute
      }
        else if ( modeChange == 3 ) {      // or 1, 2, 3...
      timer = 0;
      delay(100);
      irsend.sendNEC(0x202827D, 32); //Source
      }
        
    }
  
    delay(1);
    timer = timer + 1;

  }
}

The buttons have pull down resistors (say 10k) ?

This is without so much repetition

#include <IRremote.h>

IRsend irsend;

const int b1  = 4;  //Power
const int b2  = 5;  //mode

int timer;
int modeCounter = 0;
int modeChange = 0 ;   // global
const int NUMBEROFMODES = 3;


void wakeUp() {
  timer = 0;
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(b1, INPUT);
  pinMode(b2, INPUT);
}

void loop() {

  if (digitalRead(b2) == HIGH) {
    modeChange++; // increment
    if (modeChange > NUMBEROFMODES) modeChange = 0;
    delay(100) ;  // crude de-bounce
  }

  if (digitalRead(b1) == HIGH) {
    timer = 0;
    delay(100);

    switch ( modeChange ) {

      case 0 : {
          irsend.sendNEC(0x20202FD, 32); //Menu
          break ;
        }
      case 1 : {
          irsend.sendNEC(0x202A857, 32); //Vup
          break ;
        }
      case 2 : {
          irsend.sendNEC(0x202F00F, 32); //Mute
          break ;
        }
      case 3 : {
          irsend.sendNEC(0x202827D, 32); //Source
          break ;
        }
    }
    delay(1);
    timer = timer + 1;  
  }
}

6v6gt:
The buttons have pull down resistors (say 10k) ?

This is without so much repetition

#include <IRremote.h>

IRsend irsend;

const int b1  = 4;  //Power
const int b2  = 5;  //mode

int timer;
int modeCounter = 0;
int modeChange = 0 ;   // global
const int NUMBEROFMODES = 3;

void wakeUp() {
 timer = 0;
}

void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 pinMode(b1, INPUT);
 pinMode(b2, INPUT);
}

void loop() {

if (digitalRead(b2) == HIGH) {
   modeChange++; // increment
   if (modeChange > NUMBEROFMODES) modeChange = 0;
   delay(100) ;  // crude de-bounce
 }

if (digitalRead(b1) == HIGH) {
   timer = 0;
   delay(100);

switch ( modeChange ) {

case 0 : {
         irsend.sendNEC(0x20202FD, 32); //Menu
         break ;
       }
     case 1 : {
         irsend.sendNEC(0x202A857, 32); //Vup
         break ;
       }
     case 2 : {
         irsend.sendNEC(0x202F00F, 32); //Mute
         break ;
       }
     case 3 : {
         irsend.sendNEC(0x202827D, 32); //Source
         break ;
       }
   }
   delay(1);
   timer = timer + 1;  
 }
}

Thank you so much guys, it’s now working without any problems.
I just changed the delay in b2 to be 1000 and that was fine.

void loop() {

  if (digitalRead(b2) == HIGH) {
    modeChange++; // increment
    if (modeChange > NUMBEROFMODES) modeChange = 0;
    delay(1000) ;  // crude de-bounce
  }

One last thing, is there a possible way to add LEDs to mark the modes which one is selected?

This is extreme:

delay(1000) ; // crude de-bounce

You have not answered the question about the button pull down resistors and your problem appears to be one of floating pins.

Anyway, good is that it appears to work.