Enable Javascript

User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active

Short but sweet and hopefully understandable!

Use this Emitter module and you don't need a IR-library or ESP32 RMT-pulsing programming.

What we don't want is to simply send a large series of numbers, but we want: IR commands as a few of bytes in our own applications. We can also do without an IR library, a 38KHz module is a simple but very good solution. Port LOW-µs-delay and HIGH-µs-delay, that's all.
My receiverIR.ino software reads and analyzes the data stream from a remote control. I can't make it any easier.
In the Satellite Receiver remote control example (see below by MONITOR OUTPUT): 68 received 16bits values are decoded to 2 START values, 8 COMMAND bytes and 2 END values.
You get the various control commands by changing one or more bits in the command bytes. Repeat all remote commands and you have all the necessary bits. With my emitterIR.ino software you can test the result and use the emitterIR.ino code as the basis for your own application.
Maybe also interesting my article: MIDEA AC IR PROTOCOL
On my website you will also find: myMidea.ino: split AC IR control with an Web Browser interface

You can download my simple and very minor solutions:
    receiverIR.ino   to read and decoded your own remote control(s).
    emitterIR.ino    whit this example you can simple test and developed your own solution.
Choose an OPEN-SMART 38KHz IR LED module and you don't need a IR-library or ESP32 RMT-pulsing programming.

I bought by aliexpress 3x ESP32-DevKitC V4 and 3x OPEN-SMART IR SETS for less than € 25.= (including shipping).
 2    Arduino.../ESP... boards (from UNO to ESP32 or any other type board)
 1*  OPEN-SMART IR receiver (VCC 3.3V or 5V pin)
 1*  OPEN-SMART 38KHz IR Emitter (VCC 5V pin  -  Look out! There are also modules without 38KHz pulses)
 6   DuPont female to female jumper wires (2xVCC, 2xGND, 2xIR)
   * buy it as a set!
And free software from my site. No need for third-party IR libraries.

Learning and testing
Left emitterIR.ino and your remote control, right receiverIR.ino

After learning and testing you can develop your own applications, by example ...
Applied as a repeater

And optional with a WebSocket to control it with a Web Browser or WebView (smartphone APP).
Applied as an independent applicationon

And optional with a WebSocket to control it with a Web Browser or WebView.

I use this last proposal for my Midea Comfee AC with a DS18B20 temperature sensor and get the outside temperature from openweathermap (free subscription). My AC now switches ON and OFF automatically according to the set times, temperatures and anti yo-yo delay times.

IR modulation 38KHz is 26.31579µs(p).
We use T as a theoretical time/pulse unit.
Suppose one T is 555µs that's ~21 pulses (we see later that T can vary quite a bit, ~±50µs).
Timing has been analyzed by examining the received signals. (see bellow by: MONITOR OUTPUT)

Theoretically we can work with multiplied T times (T, 3T, <n>T) but later on we see that we can better take separate values. By example T combined with a L(ow-line) label and an P(ulsed-line) label (TnL and TnP).
1T, 3T and <n>T provides sufficient space to accommodate time/pulse differences.
1T and 3T are often used as logic 0 and logic 1.

  LOW      T1L: 555            (µs)
  PULSED   T1P: 555, T3P: 1665 (µs)
Send a Logic 0 Bit: T1L + T1P
Send a Logic 1 Bit: T1L + T3P

stream: T1L,T3P,T1L,T1P,T1L,T3P,T1L,T1P
       |     1 |     0 |     1 |     0 |  duration send 0xA: ~6660µs/6.7ms

In a test with 10x the same command  (use my receiverIR.ino, see below by MONITOR OUTPUT):
   the times measured differ a bit, so we take the average of the values found.
Change the T<n>L and/or T<n>P values as desired.

Average signal measured from a Satellite Receiver remote control (using my receiverIR.ino, see below by MONITOR OUTPUT)
The remote control values in this example:

(example)    µs:  1T-L/P     3T    4T    8T   15T
Theoretical    :  555/555  1665  2220  4440  8325
Measured values:  597/532  1635  2185  4427  9044
Usable values  :  595/530  1635  2185  4430  9040
Use TnL(ow) and TnP(ulse) values so that you could adjust them independently
LOW : T1L=595, T15L=9040
PULS: T1P=530, T3P =1635, T4P=2185, T8P=4430
(A simple Satellite Receiver remote control example, see below by MONITOR OUTPUT)
//              This ultra short demonstration code:              //
//      Switch my SAB satellite receiver EPG-list ON and OFF      //
// WE DO NOT USE AN INFRARED LIBRARY or other third-party library // 
const byte irPin = 4,
           nbytes = 8;
const uint16_t T1L = 595, T15L = 9040, // LOW times
               T1P = 530, T3P = 1635, T4P = 2185, T8P = 4430; // PULSED times 
byte cmdBytes[nbytes] = {0x8, 0x0, 0xB, 0xF, 0x7, 0x3, 0x8, 0xC}; // 0x80BF738C my OK/LIST button code
void sendCmd(); // public
void _sendIt(uint16_t t1, uint16_t t2); // private
void setup() {
  pinMode(irPin, OUTPUT);
  digitalWrite(irPin, LOW);
void loop() { // change the cmdBytes[n] bytes as needed for other commands
  sendCmd();  // now, my SAB satellite receiver EPG-list switch ON and OFF ;=)
void sendCmd() {
  _sendIt(T15L, T8P); // START stream
  for (byte i = 0; i < nbytes; i++) { // get bits, stream a Logic 1 or 0 pulsed time 
    for (byte j = 0; j < 4; j++) _sendIt(T1L, ((cmdBytes[i] << j) & 0x8 ? T3P : T1P));
  _sendIt(T15L, T4P); // END stream
  _sendIt(T15L, T4P); // extra: dummy time values
void _sendIt(uint16_t t1, uint16_t t2) { // 38KHz PULSED by the OPEN-SMART Infrared Emitter
  digitalWrite(irPin, HIGH); // HIGH? yes!
  digitalWrite(irPin, LOW);  // LOW? yes!

MONITOR OUTPUT (using my receiveIR.ino)
List time values as a list and as a table.
Calculate the command bytes and the averages T1L, T1P and T3P in µs.
With the help of this data you can read all commands from a 38KHz IR remote control.
The list values: Copy multiple equal commands list-values horizontally in a worksheet and calculate the mean values even better as shown below.