Infrared RCU Capture & Playback with Arduino-Girs and LIRC ( with both hardware and software reproducibility ).
See this blog post for my adventure with IrDroid-USB and Iguanaworks USB-IR with LIRC here.
I wanted to have a LIRC compatible hardware that I can reproduce by myself. I have found perfect one in the past ( IrDroid-USB) but it was not possible to buy it anymore since the developer is not accessible.
As you may see from above blog post, I was interested in this for long time: Original blog post on harctoolbox for arduino
I followed the tutorial and created following hardware:
This blog post has mainly two sections:
As you may have noticed, original blog post has slightly different hardware components than mine. The reason is, I could only find these equipments in the local market.
One example is non-demodulating sensor: I couldn’t find it, and for my simple IR RCU learning purposes, I think it wasn’t needed.
Another critical point is, original blog post used a very small resistor to avoid huge currents to flow across the IR Transmitter LEDs, but I tried even a 10ohm resistor , which has reduced signal intensity ( power ) of my IR LEDs dramatically. So I decided to connect two IR Transmitter LEDs directy to the GPIO output of Arduino-Nano, and I am happy with the performance so far.
Current setup is still not as powerful as IrDroid-USB, but I think it is enough for my purposes.
Maybe in future, I can consider adding a (fast) transistor to drive the IR Transmitter LEDS to increase the power even more.
I think currently my arduinos are pushing 40mA to the GPIO D3 pin, so if we check the datasheet of TSAL6400 or TSAL6200 , they can happily work at 100mA.
The rest of the circuit is exactly same as the original post.
For some hardware configuration details, read part-2 of the original post.
When you insert your Arduino-Nano to your USB port of your PC, it is detected as a USB-Serial (USBTTY)device:
[ 5095.574091] usb 1-2: new full-speed USB device number 5 using xhci_hcd
[ 5095.876218] usb 1-2: New USB device found, idVendor=1a86, idProduct=7523, bcdDevice= 2.54
[ 5095.876224] usb 1-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 5095.876227] usb 1-2: Product: USB2.0-Ser!
[ 5095.917538] usbcore: registered new interface driver ch341
[ 5095.917556] usbserial: USB Serial support registered for ch341-uart
[ 5095.917578] ch341 1-2:1.0: ch341-uart converter detected
[ 5095.929202] ch341-uart ttyUSB1: break control not supported, using simulated break
[ 5095.929276] usb 1-2: ch341-uart converter now attached to ttyUSB1
So it is detected at /dev/ttyUSB1 !!
https://github.com/bengtmartensson/AGirs/releases
I downloaded this one: https://github.com/bengtmartensson/AGirs/releases/download/Version-1.0.5/GirsLite-1.0.5-nano-flasher.sh
stulluk amdpc ~/Downloads $ ./GirsLite-1.0.5-nano-flasher.sh /dev/ttyUSB1
./GirsLite-1.0.5-nano-flasher.sh: 32: [: Linux: unexpected operator
avrdude: Version 6.3-20171130
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "/etc/avrdude.conf"
User configuration file is "/home/stulluk/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : /dev/ttyUSB1
Using Programmer : arduino
Overriding Baud Rate : 115200
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : Arduino
Description : Arduino
Hardware Version: 3
Firmware Version: 4.4
Vtarget : 0.3 V
Varef : 0.3 V
Oscillator : 28.800 kHz
SCK period : 3.3 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: reading input file "/tmp/flasher11385"
avrdude: writing flash (11448 bytes):
Writing | ################################################## | 100% 2.16s
avrdude: 11448 bytes of flash written
avrdude: verifying flash memory against /tmp/flasher11385:
avrdude: load data flash data from input file /tmp/flasher11385:
avrdude: input file /tmp/flasher11385 contains 11448 bytes
avrdude: reading on-chip flash data:
Reading | ## | 3% 0.05s
avrdude: stk500_paged_load(): (a) protocol error, expect=0x10, resp=0x47
Reading | ## | 4% 1.34savrdude: stk500_cmd(): programmer is out of sync
avr_read(): error reading address 0x0000
read operation not supported for memory "flash"
avrdude: failed to read all of flash memory, rc=-2
avrdude: stk500_cmd(): programmer is out of sync
avrdude: stk500_cmd(): programmer is out of sync
avrdude: stk500_cmd(): programmer is out of sync
avrdude: stk500_cmd(): programmer is out of sync
avrdude: safemode: Sorry, reading back fuses was unreliable. I have given up and exited programming mode
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x74
avrdude done. Thank you.
stulluk amdpc ~/Downloads $ ./GirsLite-1.0.5-nano-flasher.sh /dev/ttyUSB1
./GirsLite-1.0.5-nano-flasher.sh: 32: [: Linux: unexpected operator
avrdude: Version 6.3-20171130
Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
Copyright (c) 2007-2014 Joerg Wunsch
System wide configuration file is "/etc/avrdude.conf"
User configuration file is "/home/stulluk/.avrduderc"
User configuration file does not exist or is not a regular file, skipping
Using Port : /dev/ttyUSB1
Using Programmer : arduino
Overriding Baud Rate : 115200
AVR Part : ATmega328P
Chip Erase delay : 9000 us
PAGEL : PD7
BS2 : PC2
RESET disposition : dedicated
RETRY pulse : SCK
serial program mode : yes
parallel program mode : yes
Timeout : 200
StabDelay : 100
CmdexeDelay : 25
SyncLoops : 32
ByteDelay : 0
PollIndex : 3
PollValue : 0x53
Memory Detail :
Block Poll Page Polled
Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack
----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
eeprom 65 20 4 0 no 1024 4 0 3600 3600 0xff 0xff
flash 65 6 128 0 yes 32768 128 256 4500 4500 0xff 0xff
lfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
hfuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
efuse 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
lock 0 0 0 0 no 1 0 0 4500 4500 0x00 0x00
calibration 0 0 0 0 no 1 0 0 0 0 0x00 0x00
signature 0 0 0 0 no 3 0 0 0 0 0x00 0x00
Programmer Type : Arduino
Description : Arduino
Hardware Version: 3
Firmware Version: 4.4
Vtarget : 0.3 V
Varef : 0.3 V
Oscillator : 28.800 kHz
SCK period : 3.3 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: reading input file "/tmp/flasher11581"
avrdude: writing flash (11448 bytes):
Writing | ################################################## | 100% 2.16s
avrdude: 11448 bytes of flash written
avrdude: verifying flash memory against /tmp/flasher11581:
avrdude: load data flash data from input file /tmp/flasher11581:
avrdude: input file /tmp/flasher11581 contains 11448 bytes
avrdude: reading on-chip flash data:
Reading | ################################################## | 100% 1.62s
avrdude: verifying ...
avrdude: 11448 bytes of flash verified
avrdude: safemode: lfuse reads as 0
avrdude: safemode: hfuse reads as 0
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK (E:00, H:00, L:00)
avrdude done. Thank you.
stulluk amdpc ~/Downloads $
As you noticed above, programming Atmega328p microcontroller didn’t went well on the 1st try, but it succeeded in my 2nd test.
Please pay attention to this situation.
https://github.com/bengtmartensson/IrScrutinizer/releases
As you see from the picture:
Now we can use IrScrunitizer to “learn” our IR Remote keycodes and create a “LIRC compatible” configuration file here as follows:
Here, when you press a remote contol button, the protocol ( “NEC” here ) and corresponding keycodes are printed ina new line.
On the “Name” tab, you need to enter your key names: I suggest to prefix them with “KEY_” , so that lirc server won’t complain about namespace
When you finish your work, press “Export” button, so it will save your LIRC compliant config file under your Documents/IrScrunitizer/lirc_…conf file.
Now you can copy this file to /etc/lirc/lircd.conf.d/ directory with a proper name.
Please note that, sometimes I see that IrScrunitizer messes up the file, so you need to check the file consistency / correctness via manually checking the lines. Especially, IrScrunitizer sometimes adds a keycode line without a KEY_XXX line.. This causes LIRCD to crash.
Here are some more screenshots from IrScrunitizer:
Each remote control configuration should reside in /etc/lirc/lircd.conf.d directory. So you can just copy your newly created lircd_your_fancy_remote.conf file to this directory.
stulluk amdpc /etc/lirc $ diff lirc_options.conf lirc_options.conf.orig
11,12c11,12
< driver = girs
< device = /dev/arduino_nano_qinheng
---
> driver = default
> device = auto
stulluk amdpc /etc/lirc $
I hope this is clear. Where did the “/dev/arduino_nano_qinheng” came from ? See below.
Here is my single line udev rule, that triggers when I insert my Arduino-Girs to one of my USB ports of my PC:
stulluk amdpc /etc/lirc $ cat /etc/udev/rules.d/96-arduino.rules
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idProduct}=="7523", ATTRS{idVendor}=="1a86", SYMLINK+="arduino_nano_qinheng", RUN+="/usr/bin/kill_lircd.sh"
stulluk amdpc /etc/lirc $
Here is some explanation:
stulluk amdpc /etc/lirc $ cat /usr/bin/kill_lircd.sh
#!/bin/bash
logger "[UDEV] Killing lircd process..."
/usr/bin/kill -9 $(/usr/bin/pidof lircd) | true
logger "[UDEV] lircd killed successfully."
exit 0
stulluk amdpc /etc/lirc $
Why I needed to kill lircd? See below:
I guess this is a bug in lircd. Somehow, if I insert my arduino for the 1st time, lircd systemd service was working perfectly. But if I disconnect my arduino and reinsert again, the irsend command was just hanging, and even systemctl restart lircd was hanging too.
So I ended up killing the process totally.
After this, when you execute irsend , it automatically triggers the socket, which in turn triggers the lircd service to restart the lircd daemon.
IIUC, upstream lircd remote files should be committed to this repo:
https://sourceforge.net/projects/lirc-remotes/
However, I saw this repo wasn’t maintained for a while, and there are pending merge requests for more than 3 years.
So I decided to push my configurations to this public repo:
https://gitlab.com/stulluk/my-lirc-configs
Feel free to use it at your will.
I achieved a fully reproducible way to create a hardware and software to both capture & play infrared remote signals with very cheap hardware & software configuration.