The Girs driver

The Arduino platform has gained an incredible popularity the last few years. For simple applications using IR signaling, it is more than adequate. One of the main reasons is the availability of "far-east" clones, often to the price of a hamburger or less. LEDs (for IR or for visible light), as well as IR detectors and receivers, can be soldered directly to these PCBs.

Up until now, usage of the Arduino platform was not supported in Lirc.

The present document requires a fair amount of prerequisite knowledge both on soft- and hardware. Easier to read documents are planned.

Girs (General InfraRed Server Command Language) is the attempt to specify a general communication language for IR servers, in a wide sense. AGirs is an implementation of Girs for the Arduino. (The name "ArduinoGirs" or such was avoided for legal reasons.) It consists of a library, GirsLib, with which different "programs" ("sketches") can be written. As in the Girs specification, there is a number of different, optional modules. These are selected at compile time through defining certain C preprocessor symbols in a configuration file. Also the hardware layout is defined in configuration files.

The AGirs package is available on Github. For the time being, the user is supposed to clone that repository and to compile the Girs4Lirc sketch himself/herself. See the Arduino site for instructions on how to do this.

For the convenience of the user, this guide covers both the firmware and the driver. The next chapter covers the firmware; in Arduino lingo, the "sketch" Girs4Lirc. The chapter following deals with the Lirc driver.

The firmware: Girs4Lirc

Girs4Lirc is a version of AGirs, optimized for usage with Lirc using the Lirc driver girs. It can also be used with IrScrutinizer, however, using a decoding receiver (TSOP-*) only, it cannot determine the modulation frequency of a measured signal, nor can it capture signals with a modulation frequency different from the nominal frequency of the demodulator. (A 38kHz demodulator TSOP-*38 in practice works well for the commonly used frequencies 36--40 kHz though.)

Hardware requirements and configuration

All components are optional. The sketch can be configured for sending and/or receiving, optionally supporting signaling LEDs and an I2C-connected LCD display. Sending of non-modulated signals, e.g. using an RF sender, is supported. Thanks to the module command of Girs, the girs driver at run-time informs itself about the capacities of the current device, and informs Lirc in its turn.

Configuration is done by adapting the file config.h, selecting the desired components and their parameters. By convention, it includes a hardware configuration file, where the actual pin configuration is defined. Either use an existing one, or create your own.

A more detailed configuration guide for AGirs is in the planning stage.

Sending

For sending, define the C preprocessor symbol TRANSMIT. Connect a suitable IR LED to the sending pin (pin 9 on Mega2560 and Leonardo/Mini, pin 3 on most others), using suitable resistor and/or driver transistor.

Sending non-demodulating signals

If NON_MOD is defined, and a suitable sender is connected to pin NON_MOD_PIN, it will be possible to send non-modulated signals. This can be another IR LED, but more interestingly, it can be an RF sender, used for controlling e.g. remotely controlled power outlets etc. (Signals can be generated by IrScrutinizer, using e.g. the arctech protocol.) If (and only if) the frequency of a signal is 0, the signal is sent to the non modulating receiver at NON_MOD_PIN, otherwise the normal, modulating, sender will be used.

Having the user select transmitter manually (e.g. irsend SET_TRANSMITTERS ...) might have been a cleaner solution than the auto-routing -- but definitely less convenient. Opinions are welcome.

Current lircd parses remotes having no explicit frequency as having frequency 0 (ticket). To avoid problems, make sure that all used remotes have explicit frequencies in their lircd.conf. (If unsure, just add "frequency 38000" to the preamble of each remote.)

Receiving

For receiving, define RECEIVE. Use a demodulating receiver, TSOP*, the data pin connected to IRSENSOR_1_PIN. (Warning: Different receivers look similar, but have different pin-outs. Check the data sheet.)

LEDs (for visible light)

For using attached LEDs, define the symbol LED. If desired, define one as COMMANDLED, another as RECEIVELED, and a third one as TRANSMITLED.

This behavior is roughly the same as in IrScrutinizer.

LEDs with build-in resistor are recommended. Otherwise, be sure to include a resistor of a few hundred ohms up to a few kilo-ohms (depending to desired brightness and the type of the LED) in series with the LED. Also note that "multicolored" LEDs (which is nothing but several LEDs within one package), can be used in creative ways.

LCD

If the use of an I2C connected LCD display is desired, define I2C_LCD. This will allow the Lirc driver to send message to it for display. Also, it is used during start-up to signalize the current firmware version.

As an extra feature, a received signal will be decoded using the decoder of Girs. This currently identifies NEC and RC5 signals. The outcome of the decoding is displayed, but (at least currently) not sent to Lirc.

Self test

As a simple self test, when starting the sketch, all the LEDs come on and the name and version of the firmware is displayed on the LCD display, if configured.

Future development

AGirs is work in development, and may change, including the interface, at any time.

As Girs is intended to be a general solution, having a separate version for Lirc is a contradiction. Girs4Lirc may therefore in the future be replaced by some other sketch.

The "girs" driver.

Using the modules command of Girs, the driver informs itself during runtime of the capacities of the firmware, and informs Lircd in its turn. For example, if TRANSMIT is not defined in the firmware, Lircd knows that it cannot send.

Driver parameters

There are a few parameter with which the user can customize the behavior of the driver. They are given at the command line to Lircd (alternatively in the file lirc_options.conf). For the syntax, see the documentation for Lircd. The parameters are:

substitute_0_frequency
Define if the problem of this ticket is present in the used lircd, and the old behavior is wanted. If the frequency is 0, and this parameters is non-zero, the frequency will be substituted by this value, typically 38000. Not needed if all your remotes have explict, non-zero frequencies. Defining this makes it impossible to send non-modulated signals.
connectled
If non-zero, the LED with this number will be turned on the first time the driver is accessed and stays on until the device is closed, normally at the end of the Lircd run.
initedled
If non-zero, the LED with this number will be turned on by the init function ("has been inited", motivating the "funny" name), and turned on by the deinit function.
transmitled
If non-zero, the LED with this number will be turned on by the send function and turned on by the deinit function. (This behavior has been selected instead of the more natural one -- having the send function turn it off when ending -- since the latter has timing penalty.)
drop_dtr_when_initing
If non-zero, the "DTR line" will be lowered for 100 ms when making the first connect, causing most Arduinos to reset (see Arduino documentaton, paragraph "Automatic (Software) Reset").

Note that the LEDs defined here are controlled from the driver, independently of the ones in the previous chapter, which are controlled directly from the firmware. Using both may look confusing in deployment.

Device file

Linux (the subsystem udev really) assigns a connected Arduino a device file name of the form /dev/ttyACMn, in some cases /dev/ttyUSBn, where n is the smallest non-negative integer not yet taken. This can cause unpredictable behavior, not only when using several Arduino, but also in context of other device using the same names, like IrToys. By using custom rules to udev this difficulty can in general be circumvented.

Since there are so many different manufacturers of "Arduino-compatible" hardware, "all" having different vendor id and product id, there is no single simple answer. Some comes with a unique serial, cheaper clones in general not. As a guide to the reader, not as a definite answer, this is my /etc/udev/rules.d/10-arduino.rules. It can be used on Fedora, and probably most other modern Linuxes.

SUBSYSTEMS=="usb", ATTRS{idProduct}=="0043", ATTRS{idVendor}=="2341", SYMLINK+="arduino arduino_uno arduino_uno_$attr{serial}"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="7523", ATTRS{idVendor}=="1a86", SYMLINK+="arduino arduino_nano_qinheng"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="2303", ATTRS{idVendor}=="067b", SYMLINK+="arduino arduino_nano_prolific"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="6001", ATTRS{idVendor}=="0403", SYMLINK+="arduino arduino_nano_ftdi arduino_nano_ftdi_$attr{serial}"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="8037", ATTRS{idVendor}=="2341", SYMLINK+="arduino arduino_micro"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="8036", ATTRS{idVendor}=="2341", SYMLINK+="arduino arduino_leonardo"
SUBSYSTEMS=="usb", ATTRS{idProduct}=="0042", ATTRS{idVendor}=="2341", SYMLINK+="arduino arduino_mega arduino_mega_$attr{serial}"

FAQs

Is there a forum for AGirs?

Unfortunately not (yet). Issues with the Arduino firmware should be raised here, while problems with the driver can be posted to the Lirc mailing list, or, (formally not before the driver is official) issued raised here.

Does this driver need to be run as root?

No, provided that the device file and the lock directory (on e.g. Fedora this is /var/run/lock/lockdev) are accessible by the current user. (On most systems, this means that the current user should be a member of the group lock.) Lircd itself may need privileges e.g. for creating lock files and pipes, but this is outside of the scope of this document.

Why is the receive LED coming on for a short time before transmitting, and when Lircd is executing commands like "version"?

Because Lirc was designed that way; ask Christoph... It is not in the driver. If Lirc was designed today, this would probably have been done differently. Having said that, if using the hardware only for sending, consider disabling the receive feature in the Arduino sketch. This might improve the total systems robustness and performance.

I am looking for a hardware guide for "dummies".

It is in the planning stage.

Why is the Arduino taking so long on its start?

Because of its bootloader. Try programming the sketch using a programmer connected to the ICSP header, removing the bootloader. (It can easily be restored from the Arduino IDE.) The self test does not add anything significant to the startup time.