How to

A DIY Remote Control Arduino Recording Sign for OBS!

Arduino OBS remote recording sign
A little rough around the edges, but it gets the job done!

In the lesson I teach this semester, I have 50 minutes to take a group of around 14 fourth-graders that I haven’t seen since last semester and produce a video of them making a weather forecast. Due to the layout of the room, last year when I taught this lesson I was constantly running from the control section of our green screen studio to the recording area. So, this year I decided to make a remote controller.

In the beginning, I wanted to make a display that would show which scene was being recorded. I spent many frustrating hours trying to get that done with a Pi Zero and a P10 LED panel. But, as the time for classes to start was creeping up I decided to ditch that and just make a simple recording sign with an Arduino Leonardo.

Check it out in this video. If you want to try it yourself, detailed instructions are below!

Table of Contents

Materials needed

  • 1 Arduino Leonardo
  • 1 IR sensor
  • 1 remote control
  • 1 relay module
  • 1 small USB desk lamp
  • 3 – 6 male to female jumper wires
  • 3 – 6 male to male jumper wires
  • 1 micro-USB cable
  • 1 20K Ohm 1/4 watt resistor
  • 1 small (170 holes or smaller) breadboard (optional)
  • 1 cardboard box or other enclosure
  • Various arts and crafts supplies

Notes for materials:

Arduino Leonardo IR relay
A rare pic of an Arduino Leo in the wild

Board: Any development board using the ATmega32u4 microcontroller can be used for this project. That particular chip has a USB transceiver that can emulate keyboard keypress signals. The Arduino Leonardo is a common board that uses this controller. Other boards with the same chip include the Yun and the Micro. An Arduino Uno will not work for this project!

TSOP382838 Arduino
Many parts of this project follow the ancient Taiwanese philosophy of Cha-bu-duo

IR sensor: I used a TSOP38238 for this project, but any similar IR receiver will do. If you use a sensor that is part of a module, you may or may not still need the 20K resistor.

ELEGOO remote IR
Easily fits into a breast pocket for the teacher on the go

Remote control: Theoretically you could use any remote control you have lying around. I recommend using one of the little guys that come with most Arduino starter kits for two reasons. One, the Arduino will be able to decode its signal without having to mess around the IR library options. Two, you probably won’t have to make any changes to the button values in the code I supplied below.

5V relay made in China will probably set your house on fire
This relay was made in a country other than Taiwan

Relay module: There are many packages similar to Keyes SRly on the market and they are all pretty much the same. You do need to pay attention to whether or not the relay closes when it receives a high signal or low signal. Also, make sure the relay control is made for 5 volts (there are a few 3.3-volt models out there).

I regret using this relay a little because they are LOUD. But, in the end, the click the relay makes when it is powered on never made it into the video recordings. If you are concerned about the noise, you can opt to use a transistor instead.

LED lamp recording sign Arduino
Pay attention to wire placement BEFORE you hot glue everything in

Desk lamp: I chose a USB lamp because I knew I could use a computer as a power supply. A development board will not supply enough juice for the amount of light needed for this project. You can use any kind of low DC voltage lamp.

Do NOT use a lamp that uses AC power from your household mains unless you know what you are doing! The type of relay I used is generally not considered safe enough for mains voltage even though they are rated for it.

Also, consider how much heat the light you choose will generate and whether or not the enclosure you are using can handle it.

breadboard Arduino recording sign where's the butter
You can use a wooden one if you want to keep it old school

Breadboard: If you are not comfortable using a soldering iron, you can use a breadboard to connect everything.

Nobody will ever see this side

Enclosure and art supplies: I used the cardboard box an old router I of mine came in. For the front of the box, I used some really thick card stock with a red-tinted plastic document folder taped behind the letters. Use your imagination!

Back to top

Wiring diagram

You”ll need a bigger light! Diagram thanks to Fritzing

Wiring everything up is pretty straight-forward, but there are a few things to note. First, you should confirm the pinouts for the particular relay and IR sensor you use. Every component is a little bit different.

Second, your set-up may vary a little based on the type of lamp you use. If you are using a USB lamp, then you just need to carefully skin off a little bit of the outer insulation on the cord. I would do this on a spot on the wire about 10 inches away from the lamp. You should see a red wire and a black wire, and possibly a green and white one too. Red is 5 volts and black is negative. Cut either of these two and attach them to the relay as shown.

Third, you can use a breadboard to insert the resistor between the signal wire and the voltage wire going to the IR receiver. This resistor may not be necessary at all, depending on the IR sensor that you use. However I find that these sensors will often work fine for a minute or two, but then start sending faulty data once they heat up a little. Adding a connection to the voltage wire via a resistor smooths out the signal somehow (magic?).

Back to top

Installation

OBS LED remote control recording sign
Looks good from my house!

Installation is as easy and wiring everything up was. Again, though, a few points.

  • The IR receiver needs to be exposed! It won’t work inside the box.
  • Just cut a slit to slide the sensor into, no need to do anything fancy.
  • Some say hot glue can damage PCBs. I used it anyway
  • Before you secure the Leo, make sure you will be able to plug the USB line in
  • I probably should have thrown some tape or nail polish on those resistor leads

Back to top

Remote settings

**** If while uploading you’re getting an error about the programmer not responding, kick your Leo in the butt.

If you are using a remote similar to the one I recommended you can probably just go ahead and skip to the main code. But if you trying to repurpose a clicker or if the recording sign isn’t responding to your remote, the code below will help you see what the IR sensor is receiving.

If this is your first time uploading a sketch to an Arduino board, this official how-to can help you out. If you’ve been playing around with Arduino for a while but still using the official Arduino IDE, may I ask you, have you tried PlatformIO with Atom or VS Code? It’s dreamy. Anyways, upload this to your board:

#include <Arduino.h>
#include <IRremote.h>

const int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup(){
  Serial.begin(9600);
  irrecv.enableIRIn();
  irrecv.blink13(true);
}

void loop(){
  if (irrecv.decode(&results)){
        Serial.println(results.value, HEX);
        irrecv.resume();
  }
}

After uploading the sketch, keep your board connected and open the serial monitor with Ctrl+Shift+M. If everything is going according to plan, you should see a code every time you hit a button on your remote. If that’s the case, record each button’s value and move on to the next section.

Back to top

Code

There’s nothing complex in the code or logic for this project, so I’ll just briefly explain a few things. First, we need to include a library for the IR sensor and one to send keypresses over USB with:

#include <IRremote.h>
#include <Keyboard.h>

Next, some variables to hold pin numbers for the IR receiver and relay, and one variable to hold the value of the last IR signal received:

int RECV_PIN = 11;
int RELAY_PIN = 10;
unsigned long key_value = 0;

Finally, for the last declarations before we get to the setup block, we initialize a couple of objects from the IRremote library, a receiver and a decoder:

IRrecv irrecv(RECV_PIN);
decode_results results;

There are only two things to set up. Using enableIRIn function from the IRremote library to set up the IR sensor, and the basic function Arduino function pinMode, set the relay pin to output mode:

irrecv.enableIRIn();
pinMode(RELAY_PIN, OUTPUT);

On the main loop. Use a conditional to listen for a signal coming from the IR receiver:

if (irrecv.decode(&results))

If there is a hex value coming from the receiver, the loop will then use a series of conditionals to figure out which button is being pushed, and then send a corresponding keypress over USB. For example, the value transmitted by my remote control is FA857. To mark this as a hex value, we add the prefix ‘0XF’. If the signal being received matches 0XFFA857, then we can assume that somebody’s sausage finger is pressing the volume down button, and can carry out an action. I chose to simulate someone pressing the I key on the PC’s keyboard with the following code:

if (results.value == 0XFFA857){
          Keyboard.press('I');
          delay(100);
          Keyboard.releaseAll();
}

Note that if you don’t include some kind of key press release function, the Leonardo will send the keypress indefinitely. Keyboard.releaseAll() will stop all keypress simulations.

For the buttons that will start and stop the recording, we also need to send a high or low signal to the relay control. A high signal will close the circuit and keep it closed until the signal is switched to low. This is what my code looks like:

if (results.value == 0XFFA25D){
    digitalWrite(RELAY_PIN, HIGH);
    Keyboard.press('Q');
    delay(100);
    Keyboard.releaseAll();
}

else if (results.value == 0XFF629D){
    Keyboard.press('W');
    delay(100);
    Keyboard.releaseAll();
    digitalWrite(RELAY_PIN, LOW);
}

You can, and should, assign a keypress for every button on the remote. I used a very long chain of if-else statements. There may be some slick way to make the code shorter by using an array and converting an integer to a character, but I didn’t see the need.

You can find the complete sketch below. From here you can either jump to how to set up OBS or go back to the top of the page to review.

#include <IRremote.h>
#include <Keyboard.h>

int RECV_PIN = 11;
int RELAY_PIN = 10;
unsigned long key_value = 0;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  irrecv.enableIRIn();
  pinMode(RELAY_PIN, OUTPUT);
}

void loop() {
  if (irrecv.decode(&results)){
        if (results.value == 0XFFFFFFFF){
          results.value = key_value;
        }

        else if (results.value == 0XFFA25D){
          Keyboard.press('Q');
          delay(100);
          Keyboard.releaseAll();
          digitalWrite(RELAY_PIN, HIGH);
        }

        else if (results.value == 0XFF629D){
          Keyboard.press('W');
          delay(100);
          Keyboard.releaseAll();
          digitalWrite(RELAY_PIN, LOW);
        }

        else if (results.value == 0XFFE21D){
          Keyboard.press('E');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF22DD){
          Keyboard.press('R');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF02FD){
          Keyboard.press('T');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFFC23D){
          Keyboard.press('Y');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFFE01F){
          Keyboard.press('U');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFFA857){
          Keyboard.press('I');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF906F){
          Keyboard.press('O');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF6897){
          Keyboard.press('P');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF9867){
          Keyboard.press('A');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFFB04F){
          Keyboard.press('S');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF30CF){
          Keyboard.press('D');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF18E7){
          Keyboard.press('F');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF7A85){
          Keyboard.press('G');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF10EF){
          Keyboard.press('H');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF38C7){
          Keyboard.press('J');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF5AA5){
          Keyboard.press('K');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF42BD){
          Keyboard.press('L');
          delay(100);
          Keyboard.releaseAll();
        }

        else if (results.value == 0XFF4AB5){
          Keyboard.press('Z');
          delay(100);
          Keyboard.releaseAll();
        }
        
        else if (results.value == 0XFF52AD){
          Keyboard.press('X');
          delay(100);
          Keyboard.releaseAll();
        }

        key_value = results.value;
        
        irrecv.resume(); 
    }
}

Back to top

Configuring OBS

OK, I have a confession to make. You can get 90% of the functionality of this recording by plugging a wireless keyboard to your PC. But you wouldn’t get the recording light and that is lame.

In OBS settings, there is a section for setting up hotkeys. That’s what we will use to turn the keypresses coming from our Leo into an action in OBS. So, first, click on settings (in the cluster of buttons in the lower-left corner).

OBS settings button
Click it. I dare you.

Then, find the ‘Hotkeys’ tab on the left and give that a click.

OBS Hotkeys tab
Spicy.

Finally, click in the text field next to the action you want to assign a hotkey to, and press the desired key. I like to use the power button on my remote to start recording, and the key next to it to stop recording. The key values assigned to those buttons per our Arduino sketch are Q and W respectively. You could use the same letter to start and stop recording and it will act as a toggle, but I prefer to use two separate buttons.

OBS start stop hotkey
Assign some hot keys

Besides start and stop, you have nineteen other buttons to play with. I used mine to change scenes, but you can also use them to hide elements within a scene.

Assign some more hot keys. What are you waiting for?

Back to top

A few (very) minor quirks

I have been using this setup for four classes a day, four days a week for a few months now, and it has performed almost flawlessly. I’ve only noticed one unexpected behavior and another separate glitch with OBS or the remote that I cannot figure out.

First, the power button on the remote control for the studio’s air conditioner is the same as one of the values on the recording sign remote. I would have thought there were so many available codes that overlap would be unlikely, but I guess not?

Second, for some reason when I push the stop recording button, OBS will change the scene to the second one in my queue. It doesn’t show up in the recording, so it’s not a big deal. I’ve tried changing the button and hotkey for the second scene, but it still jumps there regardless of which scene I started from. The only way to squash the behavior is to make sure OBS is not the window in focus.

Back to top

Kick your Leo in the butt (programmer not responding)

Leonardo is a great board but sometimes it just refuses to be programmed. It’s gotten to the point where I thought that I had a defective board. I did a little research, and it turns out that sometimes the last sketch you uploaded does some to block the on-board programmer.

To fix this, you have to tap the reset button on the board near when you see the “Uploading” in the console window at the bottom of whichever IDE you are using. I’ve seen a few descriptions of the correct timing of the button press on various forums, but all I can say is it takes some practice.

That’s it! If you have any problems, please post them in the comment section.