# Arduino IRremote: sending and receiving infrared codes on an Arduino

> The Arduino IRremote library decodes and reproduces infrared remote control signals across dozens of protocols, and its README works less as a guide than as a map of the reference manual behind it.

**Arduino-IRremote/Arduino-IRremote** — Infrared remote library for Arduino: send and receive infrared signals with multiple protocols

- Repository: https://github.com/Arduino-IRremote/Arduino-IRremote
- Stars: 5,044 · Forks: 1,815
- Language: C++
- License: NOASSERTION
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/arduino-irremote-arduino-irremote

## Installing through the Arduino library manager rather than by cloning

IRremote is packaged as a standard Arduino library. The README states it is available as Arduino library IRremote, links the library manager listing on arduino-libraries.info, and carries an install badge pointing at arduino-badge.com/IRremote. So the install path is the Arduino IDE library manager or a `libraries/IRremote` directory in your sketchbook, not a compile-from-source step.

The repository tree confirms it is a proper Arduino library rather than a sketch collection. `library.properties` and `library.json` are the manifest files the IDE reads to show the library in the manager, and `keywords.txt` is the file that drives syntax highlighting in the editor. `src/` holds the sources, `examples/` holds the sketches, `pictures/` holds the images the README embeds, and `Doxyfile` at the top level is the Doxygen configuration.

That Doxyfile matters, because it is where the real manual is produced. The API badge in the README points at arduino-irremote.github.io/Arduino-IRremote/classIRrecv.html, which is generated Doxygen output for the `IRrecv` class. If you want the class members, the parameter lists or the inheritance diagram, that page has them, and the README is the signpost rather than the source.

One badge deserves attention if you are deciding whether to pin a version. Alongside the release badge and the MIT licence badge there is a badge counting commits since the latest release. It exists because master does not sit still between releases, so a sketch that behaves differently from the version you expected is often a master-versus-release difference rather than a bug in your wiring.

## The README is a table of contents for a reference manual

Most of the README is navigation. It opens with a centred logo block, badges for licence, version, commits since release and the library build workflow, then a table of contents that runs to some forty entries. There is no tutorial in it and no example code. That is a deliberate division of labour, and reading it as an incomplete README is a mistake.

What the table of contents does tell you is the shape of the library's problem space. Under receiving there are sections on IR receiver pinouts, the `decodedIRData` structure, callback functionality, ambiguous protocols, RAM usage of different protocols, and handling unknown protocols, with nested subsections for a disclaimer, other libraries which may cover those protocols, `Protocol=PULSE_DISTANCE`, `Protocol=UNKNOWN`, and how to deal with protocols IRremote does not support. Under sending there are sections on sending codes, sending the UNKNOWN protocol, sending from a description, sending IRDB codes, Flipper Zero codes, the send pin, the polarity of the send pin, simulating an IR receiver module for sending, increasing the strength of the sent output signal, and multiple IR sender instances.

The remaining entries are about scope control rather than protocol coverage: a tiny NEC receiver and sender, the FAST protocol, a feedback LED, and the `IRCommandDispatcher` class.

Two structural points sit alongside them. There is a section on migrating legacy projects to the latest version, with its own subsection for new features and changes in version 4.6, and a separate `Migrating.md` file in the tree. And there is a section on why the library uses `.hpp` instead of `.cpp` files, with a companion section on using the new `.hpp` files. Version 4 was a file-layout change, which is why an old sketch can fail to compile against a current install for reasons that have nothing to do with wiring.

## Three ways to name an IR code and what each one commits you to

The README has a section called 3 ways to specify an IR code, and the choice matters more than it sounds, because each way ties your code to a different level of detail about the signal.

The first way is a protocol call. You name the protocol, NEC for instance, and pass the code value, so the library reconstructs the timing for you. This is the compact option and it is what you want for a device you already know the code for. The cost is that you are trusting the library's model of that protocol, and the release history shows that model being corrected: v4.7.0 records a fix for a bug in sending RC6A, and v4.6.1 records a fix for a bug in RC5 and RC6 autorepeat bit handling.

The second way is a raw description, which is the `Protocol=PULSE_DISTANCE` path. You supply mark and space durations yourself rather than declaring a protocol, which is the honest way to handle a device the library does not recognise.

The third way is to capture and replay. The `examples/` tree shows the shapes this takes: `SendRawDemo` for raw timings, `SendProntoDemo` for Pronto hex strings, and `SimpleReceiverForHashCodes` for the hash-code path where the library identifies a signal by a numeric fingerprint instead of a protocol. There is also a Flipper Zero Codes section, which covers codes lifted from a Flipper Zero capture.

The `Protocol=UNKNOWN` case is the one to understand before you start. When IRremote receives a signal it cannot name, it decodes it as timing data and hands you raw marks and spaces. That is a feature rather than a failure, since it means an unsupported device is still usable, but it moves the work onto you: you now own the transmission format.

## Receiving: pinouts, the decoded data structure, and RAM per protocol

The receiving side is documented with the care you would want, because getting reception wrong is the most common way this library is blamed for not working. There is a dedicated IRReceiver pinouts section, which is where the supported receiver hardware is listed, and the tree includes `examples/ReceiverTimingAnalysis` for anyone who needs to measure rather than guess.

The core result type is documented as a `decodedIRData` structure, with its own section in the table of contents. The examples that touch it are numerous: `ReceiveDemo`, `ReceiveDump`, `SimpleReceiver`, `SendAndReceive`, `ReceiveAndSend`, and `ReceiveAndSendDistanceWidth`, which suggests the width of the received signal is treated as a first-class property rather than an implementation detail.

Two sections handle the hard cases honestly. Ambiguous protocols covers signals where more than one protocol fits, and RAM usage of different protocols covers what each protocol costs you in RAM to decode. On a microcontroller with a few kilobytes of free memory, that second section is the difference between a sketch that compiles and one that does not, and it is unusual to find that information stated plainly.

There is also a Multiple IR receivers section, and the tree has `examples/MultipleReceivers` and `examples/MultipleSendPins` beside it. Callback functionality has its own section and `examples/CallbackDemo` and `examples/IRDispatcherDemo` demonstrate two different ways of reacting to a decoded code, the latter pairing with the `IRCommandDispatcher` class entry in the README.

What is missing from the README is the wiring itself. Pin assignments, receiver model compatibility and level shifting all live in the linked documentation, so a first session with this library means reading the pinouts page before writing the sketch rather than after.

## Sending: pin choice, polarity, and why a real remote aims better

The sending half has its own set of practical entries, and they cluster around one hardware problem: getting a strong enough signal from a pin to reach the target device.

A Send pin section and a Polarity of send pin section together mean the library treats output driving as configurable rather than fixed, which is what you need when your LED or transistor expects the opposite logic level. Increase strength of sent output signal is a separate entry, so the library has a way to change how aggressively it drives, and that matters because a cheap transistor and a genuine remote control are not equally strong. Multiple IR sender instances covers the case where you need to cover more than one direction or room.

There is also an entry called simulate an IR receiver module for sending, which is the answer to a common testing problem: you can develop the sending half of a project without the device in the room, by feeding your own signal back in.

The examples map the use cases. `SendDemo` is the baseline. `SendRawDemo` sends captured timings, `SendProntoDemo` sends Pronto strings, and `SendLGAirConditionerDemo` and `SendBoseWaveDemo` are device-specific cases for two appliances whose remotes are known to be awkward. `ReceiveAndSend`, `SendAndReceive`, `ReceiveOneAndSendMultiple`, `ControlRelay` and `ReceiveAndSendHob2Hood` are the round-trip and device-control shapes, and `AllProtocolsOnLCD` and `MicroGirs` are the demonstration sketches.

Reading the list together with the protocol removals in the release notes is the useful exercise. v4.7.0 removed the LG2 protocol and updated the LG protocol, which is a signal about how much of this library's value lives in per-device protocol work rather than in generic signal handling.

## What the 4.6 and 4.7 releases say about maintenance and licensing

Three releases tell the story. v4.6.1, published on 2026-02-28, fixed a bug in RC5 and RC6 autorepeat bit handling, credited to Craig Leres, and added `setToggleBitValueForRC5AndRC6()`. v4.7.0 on 2026-04-02 is the substantial one: it removed the `LG2` protocol as useless, updated the LG protocol, fixed the RC6A sending bug, added a `match*WithGreaterRange()` family of functions with `matchMarkWithGreaterRange()` as the named example, and improved B&O decoding.

v4.7.1 followed on 2026-04-08 with a change whose name says all of it: Changed wrong `&Serial` to `aSerial` at 2 places. Two small fixes, named as two small fixes.

Two of those entries are worth reading as design signals rather than bug reports. The `match*WithGreaterRange()` additions are about tolerating signals that deviate from a protocol's nominal timing, which is what you need for cheap remotes and long-range interference. And the RC5 and RC6 autorepeat fix is about sustained presses: getting the toggle-bit convention right across repeated frames is exactly the kind of protocol bookkeeping that separates a library that works with one remote from one that works with a household.

There is a versioning pattern here too. The `IRRawDataType` typedef in v4.7.0 was added back for backward compatibility, and the README keeps a migrating document. Version 4 moved the library to `.hpp` headers, which is a breaking change for any sketch written against 3.x.

On licensing, the README badge says MIT and there is a `LICENSE` file in the tree, while the repository's own license metadata reads NOASSERTION. The README also asks for a star if the program is useful, which is worth noting as a sign of where the project's attention goes. The last commit to master was on 2026-08-12, more than four months after the v4.7.1 tag, so the commits-since-release badge is not decoration.

## Conclusion

IRremote is the library to reach for when you want an Arduino to read a remote control or impersonate one, and it earns that position by covering the awkward cases as first-class documentation rather than footnotes: unknown protocols, ambiguous protocols, RAM cost per protocol, hash codes, Pronto strings and Flipper Zero captures each have their own section. The cost is that this repository is a library, not a tutorial, so almost every question is answered on the generated API pages or in `examples/` rather than in the README. If you are upgrading an old sketch, `Migrating.md` is the file to read first, since the move from 3.x to 4.x replaced `.cpp` includes with `.hpp` files and renamed several `send*` calls. The last commit was on 2026-08-12 and the newest tag is v4.7.1 from 2026-04-08, so master carries fixes past the release badge. Start by flashing `examples/SimpleReceiver`, then move to `examples/ReceiveDump` to capture raw timings before you write any sending code.

## FAQ

### How to use irremote?

Install it as Arduino library IRremote through the library manager, then read `Migrating.md` before you start, because version 4 replaced the `.cpp` includes with `.hpp` files and renamed several calls. For learning the shape of the API, open `examples/SimpleReceiver` first, then `examples/ReceiveDump` to see raw timings. The README itself is a table of contents pointing at the generated Doxygen pages for the `IRrecv` class.

### How can I use an Arduino as an IR remote?

That is the sending half of the library, and it has dedicated documentation: a Send pin section, a Polarity of send pin section, a section on increasing the strength of the sent output signal, and one on simulating a receiver module so you can develop without the target device. `examples/SendDemo` is the baseline, with `SendRawDemo`, `SendProntoDemo` and `SendLGAirConditionerDemo` covering the device-specific cases.

### How to test if an IR remote is working?

Use the receive side and read the output rather than guessing at the wiring. `examples/SimpleReceiver` is the minimum test, `examples/ReceiveDump` prints the decoded data for inspection, and `examples/ReceiverTimingAnalysis` exists to measure timing directly. The README also documents IR receiver pinouts in their own section, which is the first thing to check when nothing is decoded at all.

### Does IR remote really work?

The library treats reception as a problem with documented causes rather than a yes-or-no question. Its table of contents carries sections on common issues, IR receiver pinouts, ambiguous protocols, RAM usage per protocol, and handling unknown protocols, where an unrecognised signal is still decoded as raw mark and space timings you can replay. Hardware compatibility is the part you verify yourself, against the documented receiver pinouts.

## Sources

- [Arduino-IRremote/Arduino-IRremote on GitHub](https://github.com/Arduino-IRremote/Arduino-IRremote)
- [Issues](https://github.com/Arduino-IRremote/Arduino-IRremote/issues)
- [README](https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/README.md)
- [Releases](https://github.com/Arduino-IRremote/Arduino-IRremote/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/arduino-irremote-arduino-irremote
