IRBlaster is a Linux kernel driver for transmitting IR signals on Raspberry Pi using hardware PWM.
- Hardware PWM for maximum accuracy and low CPU overhead
- Implemented as Linux kernel driver
- All the heavy lifting done within the driver (High-precision, time-constrained operations)
- Holds the scheduler with spinlock and disables interrupts for duration of the transmission
- Bypasses GPIO root requirements by creating character device:
/dev/irblaster
- Comes with header-only usermode library for simple access as well as usage examples (Go & C)
- Supports all Raspberry Pi devices from zero to 4 (Only tested with 3B+)
- Currently only GPIO 18 supported.
- Should work with any "modern" Raspbian installation
- Should also work on other distributions (not tested)
First make sure you are up-to-date:
$ apt-get update -y
$ apt-get upgrade -y
In order to build linux kernel modules, you'll have to have matching kernel headers to the kernel you are running.
If you are on Raspbian, you can just run:
$ sudo apt-get install raspberrypi-kernel-headers
On Debian-based platforms:
$ sudo apt-get install linux-headers-$(uname -r)
On other distributions, you'll have to figure this out yourself.
You can check that the header are successfully installed by running:
$ ls /lib/modules/$(uname -r)/build
If the build
folder is not found or is empty, headers have not been properly installed for your kernel version.
The driver will create a character device at /dev/irblaster
, which by default requires root privileges.
You can make it accessible to non-root users without sudo
by creating udev
rule file:
$ sudo touch /etc/udev/rules.d/99-irblaster.rules
and writing inside the file:
KERNEL=="irblaster", SUBSYSTEM=="ir", MODE="0666"
Build the driver (and example):
$ make # build the driver for rpi 2/3 (most common target) and usage examples (Go & C)
$ make rpi# # replace the # with anything from 0-4 depending on your Raspberry Pi model.
$ make example # build only the usage examples (Go & C)
$ sudo insmod kernel/irblaster.ko
You can check from /var/log/kern.log
whether the driver was successfully loaded.
Make sure your IR led or controlling transistor is plugged into (BCM#) GPIO 18.
You can send IR transmissions by writing to the device.
NEC-protocol implementation in the example/test.c
:
#include "../user/ib.h"
int main() {
char *buffer;
unsigned lpw = 9000; // leading pulse width
unsigned lgw = 4500; // leading gap width
unsigned opw = 560; // one pulse width
unsigned ogw = 1680; // one gap width
unsigned zpw = 560; // zero pulse width
unsigned zgw = 560; // zero gap width
unsigned utp = 560; // trailing pulse width
unsigned f = 38000; // frequency in hz (NEC: 38 kHz)
unsigned dc_n = 50; // Pulse within duty cycle period
unsigned dc_m = 100; // Duty cycle period
char *binary = "11001101001100100000111111110000"; // actual payload to be transmitted
sendIR(lpw, lgw, opw, ogw, zpw, zgw, utp, f, dc_n, dc_m, binary);
return 0;
}
For detailed example of writing to the device see user/ib.h
user mode library.
All the variables are 32-bit unsigned integers except the data string which can be up to 200 bytes.
- Pull requests are welcome.
- For major changes, please open an issue first to discuss what you would like to change.
- Project uses Google C style. You can use the
clang-format
bash script to automatically format all the.h
and.c
files in the project.
- Support for different GPIOs and PWM channels
- Direct Memory Access (DMA) support to transmit on any GPIO