Skip to content

Belal-Elshinnawey/IR_Remote_Universal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

IR Remote Universal - Plain C IR Library

A plain-C port of the IRremoteESP8266 library, designed to compile and run on multiple platforms including Zephyr RTOS and standard Linux.

License

This library is licensed under the GNU Lesser General Public License v2.1 (LGPL-2.1), the same license as the original IRremoteESP8266 project.

Repository Structure

IR_Remote_Universal/
├── src/                          # Core library source
│   ├── ir_Send.h / ir_Send.c    # IR signal encoding & burst generation
│   ├── ir_receive.h / ir_receive.c  # IR signal decoding
│   ├── ir_ac.h / ir_ac.c        # AC protocol state machine & common interface
│   ├── ir_Class.h               # Protocol enums, structs, and type definitions
│   ├── ir_utils.h / ir_utils.c  # Bit manipulation, matching, and helpers
│   ├── ir_protocol.h            # Protocol constants and feature flags
│   ├── irtext.h / irtext.c      # Human-readable string output
│   ├── IRmacros.h               # Shared macros
│   ├── i18n.h                   # Internationalization support
│   ├── locale/                  # 13 locale variants (en-US, de-DE, fr-FR, etc.)
│   └── ir_*.h / ir_*.c          # Per-protocol encoder/decoder modules (60+)
├── test_apps/
│   ├── ir_test_ubuntu/           # Linux host test application
│   └── zephy_ir_test/            # Zephyr RTOS test application (ESP32-S3)
├── LICENSE.txt
├── .gitignore
└── README.md

Supported Protocols

The library supports 59 AC protocols and many additional IR protocols including:

Samsung, Gree, Daikin (7 variants), Mitsubishi (4 variants), Fujitsu, Hitachi (3 variants), Panasonic, LG, Electra, Haier (3 variants), Whirlpool, Toshiba, Sharp, Coolix, Midea, Voltas, Rhoss, Bosch, Argo, Carrier, Corona, Kelvinator, Neoclima, Vestel, Teco, TCL, Transcold, Truma, Ecoclim, Mirage, Airton, Airwell, Amcor, Delonghi, Goodweather, Kelon, Teknopoint, Trotec, and more.

Usage

1. Setting Up the Send Context

The library uses an ir_send_ctx_t context struct that holds the burst buffer and HAL callback. You provide a buffer for IR timing data and a hardware-specific function to actually drive the IR LED:

#include "ir_Class.h"
#include "ir_Send.h"
#include "ir_receive.h"
#include "ir_ac.h"

#define IR_BURST_CAP  1024

static ir_data_t ir_burst_buf[IR_BURST_CAP];
static ir_ac_protocol_t ir_ac = {0};

static ir_send_ctx_t ir_send_ctx = {
    .pin        = 0,
    .modulation = true,
    .dutycycle  = 50,
    .carrier_hz = 38000,
    .burst_buf  = ir_burst_buf,
    .burst_cap  = IR_BURST_CAP,
    .burst_idx  = 0,
    .send_hal   = my_ir_send_hal,   // your platform HAL function
    .hal_ctx    = NULL,
    .outputOn   = 1,
    .outputOff  = 0,
};

2. Sending an AC Command

Use sendAcFromValues() to encode and transmit an AC command in a single call:

// Send: Samsung AC, Cool mode, 24C, Auto fan
bool ok = sendAcFromValues(
    &ir_send_ctx, &ir_ac,
    SAMSUNG_AC,         // protocol
    -1,                 // model (-1 = default)
    true,               // power on
    kCool,              // mode
    24.0f,              // temperature (Celsius)
    true,               // celsius
    kAutoFanSpeed,      // fan speed
    kAutoSwingV,        // vertical swing
    kAutoSwingH,        // horizontal swing
    false,              // quiet
    false,              // turbo
    false,              // econo
    false,              // light
    false,              // filter
    false,              // clean
    false,              // beep
    -1,                 // sleep (-1 = off)
    -1                  // clock (-1 = off)
);

3. Decoding a Received IR Signal

After capturing raw IR timing data into a rawbuf array (mark/space ticks), decode it:

ir_recv_ctx_t recv_ctx = {
    .tolerance = 25,
    .unknown_threshold = 12,
    .recv_hal = NULL,
    .hal_ctx  = NULL,
};
recv_ctx.params.rawbuf   = rawbuf;
recv_ctx.params.rawlen   = rawlen;
recv_ctx.params.bufsize  = 2048;
recv_ctx.params.overflow = 0;
recv_ctx.params.rcvstate = 5;  // kStopState

decode_results results;
memset(&results, 0, sizeof(results));
results.rawbuf = rawbuf;
results.rawlen = rawlen;

irparams_t save;
uint16_t save_rawbuf[2048];
save.rawbuf  = save_rawbuf;
save.bufsize = 2048;

if (decode(&recv_ctx, &results, &save, 0, 0)) {
    // Successfully decoded
    char proto_name[32];
    typeToString(proto_name, sizeof(proto_name), results.decode_type, false);
    printf("Protocol: %s\n", proto_name);
}

4. Converting Decoded Results to Common AC State

state_t common;
initStateObj(&common);

if (decodeToState(&ir_ac, &results, &common, NULL)) {
    printf("Power: %s\n", common.power ? "ON" : "OFF");
    printf("Temp:  %.0fC\n", common.degrees);
    printf("Mode:  %d\n", common.mode);
    printf("Fan:   %d\n", common.fanspeed);
}

5. Implementing the Send HAL (Platform-Specific)

On Zephyr/ESP32, a typical HAL drives the IR LED with a carrier wave:

static int ir_send_hal(const ir_data_t *buffer, uint32_t length,
                       uint32_t carrier_hz, uint8_t duty_percent,
                       void *user_ctx) {
    uint32_t period_us = 1000000 / carrier_hz;
    uint32_t on_us  = period_us * duty_percent / 100;
    uint32_t off_us = period_us - on_us;

    for (uint32_t i = 0; i < length; i++) {
        if (buffer[i].duty_cycle_us == 0) continue;
        if (i % 2 == 0) {
            // Mark: modulate carrier
            ir_carrier_mark(buffer[i].duty_cycle_us, on_us, off_us);
        } else {
            // Space: LED off
            k_busy_wait(buffer[i].duty_cycle_us);
        }
    }
    return 0;
}

Test Applications

Linux Host Test (test_apps/ir_test_ubuntu/)

A self-contained test that runs on any Linux host (no hardware required). It performs an encode-decode round-trip for all 59 supported AC protocols:

  1. Encodes an AC command into a burst buffer using the library's send path
  2. Converts the burst buffer into a simulated rawbuf (as if captured by an IR receiver)
  3. Decodes the rawbuf back and verifies the protocol, temperature, mode, and fan speed match

Building and running:

cd test_apps/ir_test_ubuntu
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)
./build/ir_test

Expected output: 58 of 59 protocols pass. TEKNOPOINT is the one expected failure because its encoding is identical to TCL112AC, which the decoder matches first.

The test also supports locale testing via test_locales.sh to verify all 13 locale variants produce identical results.

Zephyr RTOS Test (test_apps/zephy_ir_test/)

A full hardware test for ESP32-S3 running Zephyr RTOS. Features:

  • WiFi connectivity with a TCP command server on port 7001
  • Real IR LED transmission via GPIO with carrier modulation
  • IR receiver with ISR-based capture into rawbuf
  • Companion Python script (send_ir_server.py) for sending AC commands over the network

Building for ESP32-S3:

west build -b esp32s3_devkitc/esp32s3/procpu test_apps/zephy_ir_test
west flash

Unique Features

  1. No hardware dependency inside the library, so cross compiling for any platform is simple.

  2. All the library state is managed by a context owned by the user's code, so no dynamic memory allocation, unless the user decides to use it.

Library History

This library was originally based on Ken Shirriff's work (https://github.com/shirriff/Arduino-IRremote/).

Mark Szabo updated the IRsend class to work on ESP8266 and Sebastien Warin updated the receiving and decoding part (IRrecv class).

As of v2.0, the library was almost entirely re-written with the ESP8266's resources in mind. The project grew to support a huge number of AC protocols under the stewardship of David Conran (crankyoldgit) at https://github.com/crankyoldgit/IRremoteESP8266.

This variant is a refactor of v2.8.4, rewritten from C++ to plain C to be compilable on multiple platforms such as Zephyr RTOS and standard Linux.

About

A cross platform IR Library

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages