As in the last example tutorial, we will use infrared light to send data. But the signal in taht tutorial was encoded. In this tutorial, we will build our own IR remote and receiver. We will sue the UART port to send data and some IR LEDs to send the signal to the receiver. The receiver will eb made out of a phototransisitor that will detect the infrared light pulses and with an Arduino we can read the data and control stuff with it.
by: ELECTRONOOBS on 2026-08-11
- 2 x Arduino NANO eBay LINK
- 1 x infrared module eBay LINK
- 6 x push buttons eBay LINK
- 6 x LEDs eBay LINK
- 6 x 1k ohms resistors eBay LINK
- 2 x 100 ohms resistors eBay LINK
- 2 x drilled PCB eBay LINK
First, let's see how the phototransistor works. It is jsut like a BJT transistor but the base is exposed to light. A certain material makes this component only sensible to infrared rays. When IR light touches the base, the transistor will let current pass. If the emmiter is connected to ground, as we can see below, the output will be low in thisc case. But, when no light touches the base, current can't pass so the output is pulled up witk a resistor of 1k for example. That's is, with this setup we can detect pulses of IR light. All we have to do is to connect the output to an Arduino.

Below we have the transmitter schematic. I've used 6 buttons but you could add more up to the limit of the Arduino inputs. Each push button needs a pullsdown do GND so when is not pressed the output will be low. When pressed will be high. To send signals, I've used two IR LEDs to increase power and a 100 ohms resistor to limit the current. To supply the circuit you could add a battery to the Vin pin or use the USB cable. Also, the jumper is used to open the TX circuit when uploading the code. If the UART port is used when uplaoding the code, might give errors.


Below we have the receiver scheamtic. As you can see I've used the infrared sensor module but without the IR LED, only the phototransistor. Alos, you can see I've placed an extra BJT transistor between the module output and the RX input of the UART port. Why? Well, the output from the sensor is always low and high when it receives light. But the UART communications is just the oposite. It has to be always high and low when receiving data. That's why I've placed the BJT with a pullup of 1k, to invert the signal that goes to the RX pin. Then, I have 6 LEDs, each for one pressed push button from the transmitter. Once again, we have the jumper for when we upload the code.


The code is more than easy. We define out inputs and outputs. Very important, the baud rate has to be low, 300 in this case. That's because the phototransistor will not work for frequencies below 450Hz. Then, if one of the push buttons is pressed, we send a different byte with the Serial.write function. The communications is UART, so the signal will be high, then the falling edge is the start bit, then we have 8 bits of data and finally the stop bit. In my case I send the numbers 4, 8, 12, 16 and 20 in hexadecimal. You can change those numbers with a range from 0 to 255 as you can see below. But make sure you put the same values in the receiver.
/* IR remote. It uses and IR led to send data. It is made for
* 6 push buttons with pullodonw to GND of 1k.
* Schematic: http://www.electronoobs.com/eng_arduino_tut35_sch1.php */
//i/O
int left_top = 2;
int left_mid = 3;
int left_bot = 4;
int right_top = 5;
int right_mid = 6;
int right_bot = 7;
//Codes to send. Change if you want. Up to 8 bits so 0-255
byte LEFT_TOP_CODE = 0x04;
byte LEFT_MID_CODE = 0x08;
byte LEFT_BOT_CODE = 0x0C;
byte RIGHT_TOP_CODE = 0x10;
byte RIGHT_MID_CODE = 0x14;
byte RIGHT_BOT_CODE = 0x18;
void setup() {
Serial.begin(300);
pinMode(left_top,INPUT);
pinMode(left_mid,INPUT);
pinMode(left_bot,INPUT);
pinMode(right_top,INPUT);
pinMode(right_mid,INPUT);
pinMode(right_bot,INPUT);
//Turn OFF the TX pin so the IR LED will be OFF
pinMode(0,OUTPUT);
}
void loop() {
//If one button is pressed, we send one byte corresponding to that button
if(digitalRead(left_top))
{
Serial.write(LEFT_TOP_CODE);
delay(500);//Small delay, we make sure we won't send it twice
}
if(digitalRead(left_mid))
{
Serial.write(LEFT_MID_CODE);
delay(500);//Small delay, we make sure we won't send it twice
}
if(digitalRead(left_bot))
{
Serial.write(LEFT_BOT_CODE);
delay(500);//Small delay, we make sure we won't send it twice
}
if(digitalRead(right_top))
{
Serial.write(RIGHT_TOP_CODE);
delay(500);//Small delay, we make sure we won't send it twice
}
if(digitalRead(right_mid))
{
Serial.write(RIGHT_MID_CODE);
delay(500);//Small delay, we make sure we won't send it twice
}
if(digitalRead(right_bot))
{
Serial.write(RIGHT_BOT_CODE);
delay(500);//Small delay, we make sure we won't send it twice
}
//Turn OFF the TX pin after each data send, sod the IR LED will be OFF
digitalWrite(0,LOW);
}
Upload the code to the transmitter Arduino and put back the jumper. Now, each time I press a button, a different UART 8 bit data is sent as we can see below on my oscilloscope where I ahve both the raw data and the inverted one.

The receiver code is also easy. We start the serial communication with the same baud rate, 300 bauds. If the Serial.read function returns a number above 0, that means we will receive data. We store the byte. If the received data is one of the sent bytes, we invert the LEDs state and by that turn them on and off. Change the code to adapt your project if you want to do more than turning LEDs on and off.
/* Electronoobs IR receiver code. Read the AURT signal from the IR module
* Baud rate low: 300 bauds. se schematic below:
* http://www.electronoobs.com/eng_arduino_tut35_sch2.php*
*/
//I/O
int left_top = 2;
int left_mid = 3;
int left_bot = 4;
int right_top = 11;
int right_mid = 12;
int right_bot = 13;
//Received codes for each button. Make sure ar the same as in Tx code
byte LEFT_TOP_CODE = 0x04;
byte LEFT_MID_CODE = 0x08;
byte LEFT_BOT_CODE = 0x0C;
byte RIGHT_TOP_CODE = 0x10;
byte RIGHT_MID_CODE = 0x14;
byte RIGHT_BOT_CODE = 0x18;
//Digital write state of each LED; false = LED OFF
bool LEFT_TOP_STATE = false;
bool LEFT_MID_STATE = false;
bool LEFT_BOT_STATE = false;
bool RIGHT_TOP_STATE = false;
bool RIGHT_MID_STATE = false;
bool RIGHT_BOT_STATE = false;
//This is where we store the received byte
byte received = 0;
void setup() {
Serial.begin(300); //Baud rate has to be low
pinMode(left_top,OUTPUT);
pinMode(left_mid,OUTPUT);
pinMode(left_bot,OUTPUT);
pinMode(right_top,OUTPUT);
pinMode(right_mid,OUTPUT);
pinMode(right_bot,OUTPUT);
//Turn off all LEDs
digitalWrite(left_top,LOW);
digitalWrite(left_mid,LOW);
digitalWrite(left_bot,LOW);
digitalWrite(right_top,LOW);
digitalWrite(right_mid,LOW);
digitalWrite(right_bot,LOW);
}
void loop() {
//If the serial is available and with a value > 0 we read the byte in
if(Serial.available()>0)
{
received = Serial.read();
//Serial.println(received); //uncomment for debug
//If the received byte is one of the codes, we change the LED state
if(received == LEFT_TOP_CODE)
{
LEFT_TOP_STATE = !LEFT_TOP_STATE;
}
if(received == LEFT_MID_CODE)
{
LEFT_MID_STATE = !LEFT_MID_STATE;
}
if(received == LEFT_BOT_CODE)
{
LEFT_BOT_STATE = !LEFT_BOT_STATE;
}
if(received == RIGHT_TOP_CODE)
{
RIGHT_TOP_STATE = !RIGHT_TOP_STATE;
}
if(received == RIGHT_MID_CODE)
{
RIGHT_MID_STATE = !RIGHT_MID_STATE;
}
if(received == RIGHT_BOT_CODE)
{
RIGHT_BOT_STATE = !RIGHT_BOT_STATE;
}
//Turn on or off the LEDs depending on the states
digitalWrite(left_top,LEFT_TOP_STATE);
digitalWrite(left_mid,LEFT_MID_STATE);
digitalWrite(left_bot,LEFT_BOT_STATE);
digitalWrite(right_top,RIGHT_TOP_STATE);
digitalWrite(right_mid,RIGHT_MID_STATE);
digitalWrite(right_bot,RIGHT_BOT_STATE);
}
}
Upload the code to the receiver Arduino and put back the jumper. Now supply both transmitter and receiver and press the buttons. You will se that for each button, you could turn on and off the LEDs on the receiver.
Leave a comment
Please login in order to comment.