We are going to use both the IRLib and Keyboard libraries for this project, so let's figure out how to combine them. This section is self-guided, as in we are going to give you the code piece-by-piece and you can follow along.

First, we want to include both the IRLibAll and Keyboard Libraries: 

#include <IRLibAll.h>
#include <Keyboard.h>

Then, we are going to include the button codes. Since these are long numbers, they are encoded as hexadecimal values - Colin has a great video about this topic here.

/* Remote Codes */
#define VOLUMEUP      0xfd40bf
#define VOLUMEDOWN    0xfd00ff
#define RIGHT_ARROW   0xfd50af
#define LEFT_ARROW    0xfd10ef
#define PLAYPAUSE     0xfd807f
#define SELECT_BUTTON 0xfd906f

We are going to define NEC as the protocol used by the Adafruit Mini remote, then create a receiver on digital pin 2. After that, create a decoder object and an integer to hold the previous code for NEC repeat codes.

// Adafruit Mini-Remote uses NEC, change this if you're using a different remote
#define MY_PROTOCOL NEC
// receiver on pin 2
IRrecv myReceiver(2);
// Decoder object
IRdecode myDecoder;
// NEC repeat codes for Adafruit Mini-Remote
uint32_t Previous;

Lastly, we are going to create a LED object on Pin #13, which is the builtin LED. We are going to use this a way to visually debug our circuit without printing out to the serial monitor. 

const int ledPin = 13;

In the setup() loop, we are going to tell the Metro to begin control over the keyboard, start the IR Receiver, and configure the led as an output. 

void setup() {
  // initialize control over the keyboard
  Keyboard.begin();
  // start the IR receiver
  myReceiver.enableIRIn();
  // configure status LED
  pinMode(LED_BUILTIN, OUTPUT);
}

The loop() is quite complicated, but we'll break it down to make it easier. We are going to first detect if the receiver gets an input from the remote with myReceiver.getResults(). Then, we are going to decode it with a call to myDecoder.decode()

Next, we want to check if the protocol is the same as what's used by the Mini Remote, NEC, by checking if(myDecoder.protocolNum==MY_PROTOCOL). Finally, we are going to detect the repeat codes, and set the current value to the previous decoded value if(myDecoder.value==0xFFFFFFFF {myDecoder.value=Previous;}

void loop()
{
    if (myReceiver.getResults()) {
       myDecoder.decode();
       if(myDecoder.protocolNum==MY_PROTOCOL) {
         if(myDecoder.value==0xFFFFFFFF)
           myDecoder.value=Previous;

            // handle everything in here

Phew, now the fun part begins. We are going to use a programming concept called a SwitchCase. This will let us take in one value (the value decoded by the decoder -myDecode.value) and perform different actions depending on what the value is. 

In our case, we are going to switch based on myDecoder.value. The first case will be if the PLAYPAUSE button is detected (already #define'd above). We want to send the spacebar key to pause VLC playback.

  switch(myDecoder.value) {
           case PLAYPAUSE:
            // key-play-pause
            // send the spacebar key

We are going to send 0x20, the spacebar ascii value, to the keyboard with Keyboard.write(). Then, we are going to turn the LED to signal the key was sent (a really easy way to visually debug your code). Next, we are going to delay, then call Keyboard.releaseAll(); to release the key(s) pressed. Then, we are going to break; out of that case and finish execution.

            Keyboard.write((char)0x20);
            digitalWrite(LED_BUILTIN, HIGH);
            delay(100);
            // release the keys pressed
            Keyboard.releaseAll();
            break;

Now that you get the idea, we are going to provide you with the code. Try the Make It Better section if you'd like to try your hand at understanding this project better.

/* PROJ05: Metro Media Remote
*  Desc: Control VLC with your Adafruit Metro M0 Express!
* by Brent Rubell and Asher Liber for Adafruit Industries
* Requires IRLib2.x Library
*/

#include <IRLibAll.h>
#include <Keyboard.h>

/* Remote Codes */
#define VOLUMEUP      0xfd40bf
#define VOLUMEDOWN    0xfd00ff
#define RIGHT_ARROW   0xfd50af
#define LEFT_ARROW    0xfd10ef
#define PLAYPAUSE     0xfd807f
#define SELECT_BUTTON 0xfd906f
// These are some extra button codes...not used in the PROJ.
// if you want to create more functions in VLC or any other app, use these!
#define UP_ARROW      0xfda05f
#define DOWN_ARROW    0xfdb04f
#define BUTTON_0      0xfd30cf
#define BUTTON_1      0xfd08f7
#define BUTTON_2      0xfd8877
#define BUTTON_3      0xfd48b7
#define BUTTON_4      0xfd28d7
#define BUTTON_5      0xfda857
#define BUTTON_6      0xfd6897
#define BUTTON_7      0xfd18e7
#define BUTTON_8      0xfd9867
#define BUTTON_9      0xfd58a7
// Adafruit Mini-Remote uses NEC, change this if you're using a different remote
#define MY_PROTOCOL NEC

// receiver on pin 2
IRrecv myReceiver(2);
// Decoder object
IRdecode myDecoder;

// NEC repeat codes for Adafruit Mini-Remote
uint32_t Previous;

// use this option for OSX:
char ctrlKey = KEY_LEFT_GUI;
// use this option for Windows and Linux:
//  char ctrlKey = KEY_LEFT_CTRL;

const int ledPin = 13;

void setup() {
  // monitor the serial at 9600baud
  Serial.begin(9600);
  // initialize control over the keyboard
  Keyboard.begin();
  // start the IR receiver
  myReceiver.enableIRIn();
  // configure status LED
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("Listening to IR...");
}

void loop()
{
    if (myReceiver.getResults()) {
       myDecoder.decode();
       if(myDecoder.protocolNum==MY_PROTOCOL) {
         if(myDecoder.value==0xFFFFFFFF)
           myDecoder.value=Previous;
         // We used VLC for this example, but you can use any keyboard shortcuts!
         // (src: https://wiki.videolan.org/Hotkeys_table/)
         switch(myDecoder.value) {
           case PLAYPAUSE:
            // key-play-pause
            // send the spacebar key
            Keyboard.write((char)0x20);
            digitalWrite(LED_BUILTIN, HIGH);
            delay(100);
            // release the keys pressed
            Keyboard.releaseAll();
            break;
           case VOLUMEUP:
            // key-vol-up
            // vlc shortcut: ctrl + up arrow
            Keyboard.press(ctrlKey);
            Keyboard.press(KEY_UP_ARROW);
            digitalWrite(LED_BUILTIN, HIGH);
            delay(100);
            Keyboard.releaseAll();
            break;
          case VOLUMEDOWN:
            // key-vol-down
            // vlc shortcut: ctrl + down arrow
            Keyboard.press(ctrlKey);
            Keyboard.press(KEY_DOWN_ARROW);
            digitalWrite(LED_BUILTIN, HIGH);
            delay(100);
            Keyboard.releaseAll();
            break;
          case RIGHT_ARROW:
            // key-faster
            // vlc shortcut: +
            Keyboard.press('+');
            digitalWrite(LED_BUILTIN, HIGH);
            delay(100);
            Keyboard.releaseAll();
            break;
          case LEFT_ARROW:
            // key-faster
            // vlc shortcut: -
            Keyboard.press('-');
            digitalWrite(LED_BUILTIN, HIGH);
            delay(100);
            Keyboard.releaseAll();
            break;
          default:
            // if nothing else matches, do the default
            // default is optional
            break;
         }
         Previous=myDecoder.value;
       }
       digitalWrite(LED_BUILTIN, LOW);
       myReceiver.enableIRIn();
    }
}

I'm having trouble with this Project

Fatal error: IRLibAll.h: No such file or directory #include

The IRLib 2.x library was improperly installed. Check CIRC16's "Installing the IR Library" page for correct installation instructions.

My computer isn't responding to the remote

If you're using the Adafruit Mini-Remote, make sure you un-comment (remove the slashes) the char ctrlKey variable for which operating system you're using:

// use this option for OSX:
char ctrlKey = KEY_LEFT_GUI;
// use this option for Windows and Linux:
// char ctrlKey = KEY_LEFT_CTRL;

If you're using your own remote control, you'll need to make modifications to the code. Check out this guide on Sending IR Codes for more info.  

This guide was first published on Aug 18, 2017. It was last updated on Aug 18, 2017.

This page (Code) was last updated on Oct 18, 2021.

Text editor powered by tinymce.