Multiple LIRC Drivers

From MythTV Official Wiki
Jump to: navigation, search

Setup

When a system has multiple transmitters and each needs a separate instance of an lirc driver, there are two options:

  1. Download the lirc source code, edit the package to compile another instance of the driver for you
  2. Use this method to quickly create a new instance of an lirc driver from your existing driver

This process will work for lirc_serial and should work for other lirc drivers as well. The setup for this is multiple IR transmitters connected to separate serial ports.

Installation

First, find the existing lirc_serial driver and cd to that directory:

$ find /lib/modules/`uname -r` -name lirc_serial.ko
/lib/modules/2.6.31-21-generic/kernel/ubuntu/lirc/lirc_serial/lirc_serial.ko
$ cd /lib/modules/2.6.31-21-generic/kernel/ubuntu/lirc/lirc_serial

Next, create the new lirc_serial.ko driver, this must be done as root. This new driver can be loaded separately from lirc_serial to perhaps listen on a different port:

$ su
# cat lirc_serial.ko | sed -e 's/lirc_serial/lirc_ser_01/g' > lirc_ser_01.ko
# depmod -a
# exit
$

That's it! Now load the new driver:

$ sudo modprobe lirc_ser_01
$ dmesg | tail
lirc_ser_01: auto-detected active high receiver
lirc_dev: lirc_register_driver: sample_rate: 0
lirc_ser_01 $Revision: 5.104 $ registered

This process can be repeated for every device connected to a serial port on the system by replacing lirc_ser_01 with lirc_ser_02, lirc_ser_03, etc.

Setting up dkms

However, this process must be repeated when the kernel is upgraded to a new version. To have the dkms system do this automatically, first create a 'source' directory for the driver:

$ sudo mkdir -p /usr/src/mylirc-1.0
$ sudo touch /usr/src/mylirc-1.0/makefile

Then create a file named dkms.conf in /usr/src/mylirc-1.0 with a text editor that contains:

# This is /usr/src/mylirc-1.0/dkms.conf
PACKAGE_NAME="mylirc"
PACKAGE_VERSION="1.0"
CLEAN="rm -f lirc_ser_*.ko"
BUILT_MODULE_NAME[0]="lirc_ser_01"
MAKE[0]="cat `find /lib/modules/$kernelver -name lirc_serial.ko` | sed -e 's/lirc_serial/lirc_ser_01/g' > lirc_ser_01.ko"
DEST_MODULE_LOCATION[0]="/kernel/custom"
AUTOINSTALL="yes"

This dkms.conf file can be easily modified with additional lines for lirc_ser_02, lirc_ser_03, etc, with lines that follow the format:

BUILT_MODULE_NAME[1]="lirc_ser_02"
MAKE[1]="cat `find /lib/modules/$kernelver -name lirc_serial.ko` | sed -e 's/lirc_serial/lirc_ser_02/g' > lirc_ser_02.ko"
DEST_MODULE_LOCATION[1]="/kernel/custom"
#  ... etc

Now add mylirc to dkms:

dkms add -m mylirc -v 1.0

Attempting to build and install this module right now will succeed, but not actually copy anything into the modules directory since lirc_ser_01 was already created earlier:

dkms build -m mylirc -v 1.0
dkms install -m mylirc -v 1.0

Setting up modprobe.conf

The newly created driver can be easily setup separately from your lirc_serial in your /etc/modprobe.d/lirc-serial.conf:

#COM1 equivalent, /dev/ttyS0
options lirc_serial irq=4 io=0x3f8
#COM2 equivalent, /dev/ttyS1
#options lirc_serial irq=3 io=0x2f8
# This is for my PCI-E card with two additional serial ports
options lirc_ser_01 irq=17 io=0xb800 share_irq=1
install lirc_serial setserial /dev/ttyS0 uart none; /sbin/modprobe --ignore-install lirc_serial
install lirc_ser_01 setserial /dev/ttyS1 uart none; /sbin/modprobe --ignore-install lirc_ser_01

Background

The reason this whole process works is because the new name of the driver is the exact same length as the previous driver name. Doing this with another lirc driver (e.g. lirc_sir) would have to use a new name that is the exact same length so lirc_s01 would work, but lirc_sir1 would not.

Sample configuration

This setup was successfully used in the following configuration:

  • Single Mythtvbackend
  • One PVR-350, and one PVR-150
  • Hauppauge remote from the PVR-350 using the lirc_i2c driver
  • IR Blaster on COM1 (the only COM port on the motherboard) using lirc_serial
  • IR Blaster on COM2 (from the SYBA PCI-E RS232 SD-PEX15022 card) using lirc_ser_01
  • Two Pace DC50x (one on the PVR-350, the other on the PVR-350)

This configuration has two transmitters communicating with the same type of receiver, and thus required two lirc instances running for the transmitters and one running for the receiver. Usually, only one instance of lirc is needed just with each remote configured since there are usually different devices, but in this case they are the same type of device and each one has to be controlled independently.

Setting up lirc

This unique setup requires some additional work to setup lirc properly, namely it needs the lirc files for each transmitter with a different remote name. This file should be placed in /usr/share/lirc/extras/transmitters/pace which may need to be created:

# This is /usr/share/lirc/extras/transmitters/pace/general.conf
# contributed by Mike Silliman
#
# brand: Pace
# supported devices: Pace DC50X (Comcast Digital Transport Adapter)
#
# Protocol: XMP-R
# Device: 62.16

begin remote
name DC50X
flags RAW_CODES
eps 30
aeps 100
gap 80412
begin raw_codes

name 1
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 2656 210 763
210 763 210 763 210 894
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1578 210 1841
210 763 210 763 210 894
210 763 210 763 210

name 2
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 2524 210 763
210 763 210 763 210 1026
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1446 210 1841
210 763 210 763 210 1026
210 763 210 763 210

name 3
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 2393 210 763
210 763 210 763 210 1157
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1315 210 1841
210 763 210 763 210 1157
210 763 210 763 210

name 4
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 2261 210 763
210 763 210 763 210 1315
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1157 210 1841
210 763 210 763 210 1315
210 763 210 763 210

name 5
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 2130 210 763
210 763 210 763 210 1446
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1026 210 1841
210 763 210 763 210 1446
210 763 210 763 210

name 6
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1972 210 763
210 763 210 763 210 1578
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 894 210 1841
210 763 210 763 210 1578
210 763 210 763 210

name 7
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1841 210 763
210 763 210 763 210 1709
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 763 210 1841
210 763 210 763 210 1709
210 763 210 763 210

name 8
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1709 210 763
210 763 210 763 210 1841
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 2787 210 1841
210 763 210 763 210 1841
210 763 210 763 210

name 9
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1578 210 763
210 763 210 763 210 1972
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 2656 210 1841
210 763 210 763 210 1972
210 763 210 763 210

name 0
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 2787 210 763
210 763 210 763 210 763
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1709 210 1841
210 763 210 763 210 763
210 763 210 763 210

name Enter
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 1841 210 763
210 763 210 1026 210 1446
210 763 210 763 210 80413
210 894 210 1709 210 763
210 2787 210 1315 210 1315
210 1157 210 2656 210 13805
210 894 210 763 210 1841
210 763 210 1026 210 1446
210 763 210 763 210

end raw_codes
end remote 

Now to create the config for the second remote, simply do (as root):

# cat general.conf | sed -e 's/DC50X/DC50X_2/g' > general2.conf

Setup /etc/lirc/lircd.conf to have:

# /etc/lirc/lircd.conf
# Note: Transmitters _must_ come before the receiver!
include "/usr/share/lirc/extras/transmitters/pace/general.conf"
include "/usr/share/lirc/extras/transmitters/pace/general2.conf"

#Configuration for the Hauppauge TV card remote:
include "/usr/share/lirc/extras/more_remotes/hauppauge/lircd.conf.hauppauge"

Setup /etc/lirc/hardware.conf

By default lirc is setup to work with one remote and one transmitter, but this setup requires another transmitter. This can be accomplished through MultiLIRC or by the following setup:

# Add these lines to /etc/init.d/hardware.conf for the second transmitter
TRANSMITTER2="Serial Port (UART) : Comcast Pace DC50X box"
TRANSMITTER2_MODULES="lirc_dev lirc_ser_01"
TRANSMITTER2_DRIVER=""
TRANSMITTER2_DEVICE="/dev/lirc2"
TRANSMITTER2_SOCKET=""
TRANSMITTER2_LIRCD_CONF="pace/general2.conf"
TRANSMITTER2_LIRCD_ARGS=""

Setup /etc/init.d/lirc

By default the /etc/init.d/lirc will only setup one remote and one transmitter, so it needs to be modified to support another transmitter. Use the following /etc/init.d/lirc instead of the default:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          lirc
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Starts LIRC daemon.
# Description:       LIRC is used to control different
#                    infrared receivers and transceivers.
### END INIT INFO

load_modules ()
{
	 MODULES_MISSING=false

	 log_daemon_msg "Loading LIRC modules"
	 for mod in $*; do
		 if [ $mod = "udev" ]; then
			 log_end_msg 0
			 log_success_msg "Restarted via udev, don't reload modules"
			 break
		 else
			 modprobe $mod 2> /dev/null || MODULES_MISSING=true
		 fi
	 done
	 log_end_msg $?

	 if $MODULES_MISSING; then
		 log_failure_msg "Unable to load LIRC kernel modules. Verify your"
		 log_failure_msg "selected kernel modules in /etc/lirc/hardware.conf"
		 START_LIRCMD=false
		 START_LIRCD=false
	 fi
}

build_remote_args ()
{
	 REMOTE_ARGS="$*"

	 #For remote only detection support, we need
	 #both REMOTE_DEVICE and TRANSMITTER_DEVICE undefined
	 if [ -z "$REMOTE_DEVICE" ] && [ -z "$TRANSMITTER_DEVICE" ] && [ -c $dev ]; then
		 REMOTE_DEVICE="$dev"
	 fi

	 #If we have a REMOTE_DEVICE or REMOTE_DRIVER defined (either because no devices
	 #were defined, OR if we explicitly did), then populate REMOTE_ARGS
	 if [ ! -z "$REMOTE_DEVICE" ] || [ ! -z "$REMOTE_DRIVER" ]; then
		 if [ -n "$REMOTE_DEVICE" ] && [ "$REMOTE_DEVICE" != "none" ]; then
			 REMOTE_ARGS="--device=$REMOTE_DEVICE $REMOTE_ARGS"
		 fi
		 if [ -n "$REMOTE_DRIVER" ] && [ "$REMOTE_DRIVER" != "none" ]; then
			 REMOTE_ARGS="--driver=$REMOTE_DRIVER $REMOTE_ARGS"
		 fi

		 #Now, if we ALSO have a transmitter defined, add some args
		 #To make the first lircd listen up
		 if [ ! -z "$TRANSMITTER_DEVICE" ] || [ ! -z "$TRANSMITTER_DRIVER" ]; then
			 REMOTE_ARGS="$REMOTE_ARGS --listen"
		 fi
		 REMOTE_ARGS="--output=$REMOTE_SOCKET $REMOTE_ARGS"
	 fi
	 echo $REMOTE_ARGS
}

build_transmitter_args ()
{
	 TRANSMITTER_ARGS="$*"

	 #Transmitters must be explicitly be defined
	 if [ ! -z "$TRANSMITTER_DEVICE" ] || [ ! -z "$TRANSMITTER_DRIVER" ]; then
		 if [ -n "$TRANSMITTER_DEVICE" ] && [ "$TRANSMITTER_DEVICE" != "none" ]; then
			 TRANSMITTER_ARGS="--device=$TRANSMITTER_DEVICE $TRANSMITTER_ARGS"
		 fi
		 if [ -n "$TRANSMITTER_DRIVER" ] && [ "$TRANSMITTER_DRIVER" != "none" ]; then
			 TRANSMITTER_ARGS="--driver=$TRANSMITTER_DRIVER $TRANSMITTER_ARGS"
		 fi

		 #Now, if we ALSO have a remote defined, add some args
		 #To make the second lircd connect
		 if [ ! -z "$REMOTE_DEVICE" ] || [ ! -z "$REMOTE_DRIVER" ]; then
			 TRANSMITTER_SOCKET="${TRANSMITTER_SOCKET}1"
			 TRANSMITTER_ARGS="$TRANSMITTER_ARGS --connect=localhost:8765 --pidfile=/var/run/lirc/lircd1.pid"
		 fi
		 TRANSMITTER_ARGS="--output=$TRANSMITTER_SOCKET $TRANSMITTER_ARGS"
	 fi
	 echo $TRANSMITTER_ARGS
}

build_transmitter2_args ()
{
	 TRANSMITTER2_ARGS="$*"

	 #Transmitters must be explicitly be defined
	 if [ ! -z "$TRANSMITTER2_DEVICE" ] || [ ! -z "$TRANSMITTER2_DRIVER" ]; then
		 if [ -n "$TRANSMITTER2_DEVICE" ] && [ "$TRANSMITTER2_DEVICE" != "none" ]; then
			 TRANSMITTER2_ARGS="--device=$TRANSMITTER2_DEVICE $TRANSMITTER2_ARGS"
		 fi
		 if [ -n "$TRANSMITTER2_DRIVER" ] && [ "$TRANSMITTER2_DRIVER" != "none" ]; then
			 TRANSMITTER2_ARGS="--driver=$TRANSMITTER2_DRIVER $TRANSMITTER2_ARGS"
		 fi

		 #Now, if we ALSO have a remote defined, add some args
		 #To make the second lircd connect
		 if [ ! -z "$REMOTE_DEVICE" ] || [ ! -z "$REMOTE_DRIVER" ]; then
			 TRANSMITTER2_SOCKET="${TRANSMITTER2_SOCKET}2"
			 TRANSMITTER2_ARGS="$TRANSMITTER2_ARGS --connect=localhost:8765 --pidfile=/var/run/lirc/lircd2.pid"
		 fi
		 TRANSMITTER2_ARGS="--output=$TRANSMITTER2_SOCKET $TRANSMITTER2_ARGS"
	 fi
	 echo $TRANSMITTER2_ARGS
}

. /lib/lsb/init-functions

test -f /usr/sbin/lircd || exit 0
test -f /usr/sbin/lircmd || exit 0

START_LIRCMD=true
START_LIRCD=true
START_IREXEC=true


if [ -f /etc/lirc/hardware.conf ];then
	 . /etc/lirc/hardware.conf
fi

if [ ! -f /etc/lirc/lircd.conf ] || grep -q "^#UNCONFIGURED" /etc/lirc/lircd.conf; then
	 if [ "$1" = "start" ]; then
		 log_success_msg "No valid /etc/lirc/lircd.conf has been found."
		 log_success_msg "Remote control support has been disabled."
		 log_success_msg "Reconfigure LIRC or manually replace /etc/lirc/lircd.conf to enable."
	 fi

	 START_LIRCD=false
	 START_LIRCMD=false
	 START_IREXEC=false
fi

if [ ! -f /etc/lirc/lircmd.conf ] || grep -q "^#UNCONFIGURED" /etc/lirc/lircmd.conf; then
	 START_LIRCMD=false
fi

if [ ! -f /etc/lirc/lircrc ] || grep -q "^#UNCONFIGURED" /etc/lirc/lircrc; then
	 START_IREXEC=false
fi

#We need default socket locations
OLD_SOCKET="/dev/lircd"
if [ -z "$REMOTE_SOCKET" ]; then
	 REMOTE_SOCKET="/var/run/lirc/lircd"
fi
if [ -z "$TRANSMITTER_SOCKET" ]; then
	 TRANSMITTER_SOCKET="/var/run/lirc/lircd"
fi
if [ -z "$TRANSMITTER2_SOCKET" ]; then
	 TRANSMITTER2_SOCKET="/var/run/lirc/lircd"
fi

case "$1" in
	 start)
		 if [ "$LOAD_MODULES" = "true" ] && [ "$START_LIRCD" = "true" ]; then
			 load_modules $2 $REMOTE_MODULES $TRANSMITTER_MODULES $TRANSMITTER2_MODULES $MODULES
		 fi

		 if [ "$START_LIRCD" = "true" ]; then
			 [ -d "/var/run/lirc" ] || mkdir -p "/var/run/lirc"
			 log_daemon_msg "Starting remote control daemon(s) : LIRC "
			 REMOTE_LIRCD_ARGS=`build_remote_args $REMOTE_LIRCD_ARGS`
			 TRANSMITTER_LIRCD_ARGS=`build_transmitter_args $TRANSMITTER_LIRCD_ARGS`
			 TRANSMITTER2_LIRCD_ARGS=`build_transmitter2_args $TRANSMITTER2_LIRCD_ARGS`

			 #if we have a remote defined, it is primary process
			 if [ ! -z "$REMOTE_LIRCD_ARGS" ]; then
				 start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/lircd -- $REMOTE_LIRCD_ARGS < /dev/null
				 log_end_msg $?
				 if [ -S "$REMOTE_SOCKET" -a "$OLD_SOCKET" != "$REMOTE_SOCKET" ]; then
					 rm -f $OLD_SOCKET && ln -s $REMOTE_SOCKET $OLD_SOCKET
				 fi 

				 #now if we additionally have a transmitter defined, it is secondary process
				 if [ ! -z "$TRANSMITTER_LIRCD_ARGS" ]; then
					 /usr/sbin/lircd $TRANSMITTER_LIRCD_ARGS < /dev/null
					 if [ -S "$TRANSMITTER_SOCKET" ]; then
						 rm -f ${OLD_SOCKET}1 && ln -s $TRANSMITTER_SOCKET ${OLD_SOCKET}1
					 fi 
				 fi
				 #now if we additionally have a second transmitter defined, it is secondary process
				 if [ ! -z "$TRANSMITTER2_LIRCD_ARGS" ]; then
					 /usr/sbin/lircd $TRANSMITTER2_LIRCD_ARGS < /dev/null
					 if [ -S "$TRANSMITTER2_SOCKET" ]; then
						 rm -f ${OLD_SOCKET}2 && ln -s $TRANSMITTER2_SOCKET ${OLD_SOCKET}2
					 fi 
				 fi
			 elif [ ! -z "$TRANSMITTER_LIRCD_ARGS" ]; then
				 start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/lircd -- $TRANSMITTER_LIRCD_ARGS < /dev/null
				 log_end_msg $?
				 if [ -S "$TRANSMITTER_SOCKET" -a "$OLD_SOCKET" != "$TRANSMITTER_SOCKET" ]; then
					 rm -f $OLD_SOCKET && ln -s $TRANSMITTER_SOCKET $OLD_SOCKET
				 fi 
			 elif [ ! -z "$TRANSMITTER2_LIRCD_ARGS" ]; then
				 start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/lircd -- $TRANSMITTER2_LIRCD_ARGS < /dev/null
				 log_end_msg $?
				 if [ -S "$TRANSMITTER2_SOCKET" -a "$OLD_SOCKET" != "$TRANSMITTER2_SOCKET" ]; then
					 rm -f $OLD_SOCKET && ln -s $TRANSMITTER2_SOCKET $OLD_SOCKET
				 fi 
			 else
				 log_end_msg 1
			 fi
		 fi

		 if [ "$START_LIRCMD" = "true" ]; then
			 [ -d "/var/run/lirc" ] || mkdir -p "/var/run/lirc"
			 log_daemon_msg "Starting remote control mouse daemon : LIRCMD "
			 start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/lircmd < /dev/null
			 log_end_msg $?
		 fi

		 if [ "$START_IREXEC" = "true" ]; then
			 [ -d "/var/run/lirc" ] || mkdir -p "/var/run/lirc"
			 log_daemon_msg "Starting execution daemon: irexec"
			 start-stop-daemon --start --quiet --oknodo --exec /usr/bin/irexec -- -d /etc/lirc/lircrc < /dev/null
			 log_end_msg $?
		 fi
		 ;;
	 stop)
		 if [ "$START_IREXEC" = "true" ]; then
			 log_daemon_msg "Stopping execution daemon: irexec"
			 start-stop-daemon --stop --quiet --exec /usr/bin/irexec
			 log_end_msg $?
		 fi

		 if [ "$START_LIRCMD" = "true" ]; then
			 log_daemon_msg "Stopping remote control mouse daemon: LIRCMD"
			 start-stop-daemon --stop --quiet --exec /usr/sbin/lircmd
			 log_end_msg $?
		 fi

		 if [ "$START_LIRCD" = "true" ]; then
			 log_daemon_msg "Stopping remote control daemon(s): LIRC"
			 start-stop-daemon --stop --quiet --exec /usr/sbin/lircd
			 log_end_msg $?
			 [ -h "$OLD_SOCKET" ] && rm -f $OLD_SOCKET
			 [ -h "${OLD_SOCKET}1" ] && rm -f ${OLD_SOCKET}1
			 [ -h "${OLD_SOCKET}2" ] && rm -f ${OLD_SOCKET}2
		 fi
		 ;;
	 reload|force-reload)
		 if [ "$START_IREXEC" = "true" ]; then
			 start-stop-daemon --stop --quiet --signal 1 --exec /usr/bin/irexec
		 fi

		 if [ "$START_LIRCD" = "true" ]; then
			 start-stop-daemon --stop --quiet --signal 1 --exec /usr/sbin/lircd
		 fi

		 if [ "$START_LIRCMD" = "true" ]; then
			 start-stop-daemon --stop --quiet --signal 1 --exec /usr/sbin/lircmd
		 fi
		 ;;
	 restart)
		 $0 stop
		 #passes parameter $2 which is possibly our udev paramater
		 $0 start $2
		 ;;
	 *)
		 echo "Usage: /etc/init.d/lircd {start|stop|reload|restart|force-reload}"
	 exit 1
esac

exit 0

Channel change scripts

The scripts below are minimal versions that are easy to understand. See Lirc Channel Change script for a feature complete script that handles multiple IR channels and other more complex situations.

Script to change the first tuner:

#!/usr/bin/perl
# Created by regx
# Simple perl script to change channels for Myth

# make sure to set this string to
# the corresponding remote in /etc/lircd.conf
$remote_name = 'DC50X';

$channel=$ARGV[0];
@channel = split(//,$channel);
foreach(@channel){
       #print $_ . "\n";
       `irsend -d /var/run/lirc/lircd1 SEND_ONCE $remote_name $_`;
}
sleep 1;
`irsend -d /var/run/lirc/lircd1 SEND_ONCE $remote_name ENTER`;

Script to change the second tuner:

#!/usr/bin/perl
# Created by regx
# Simple perl script to change channels for Myth

# make sure to set this string to
# the corresponding remote in /etc/lircd.conf
$remote_name = 'DC50X_2';

$channel=$ARGV[0];
@channel = split(//,$channel);
foreach(@channel){
       #print $_ . "\n";
       `irsend -d /var/run/lirc/lircd2 SEND_ONCE $remote_name $_`;
}
sleep 1;
`irsend -d /var/run/lirc/lircd2 SEND_ONCE $remote_name ENTER`;

Additional notes

Sometimes the setserial may fail on the insertion of the module so just add the following lines to /etc/rc.local to restart lirc twice to ensure everything works properly:

# Add these lines to /etc/rc.local
/etc/init.d/lirc restart
/etc/init.d/lirc restart

Conclusion

Thats it! Now lirc is configured to use one remote and two transmitters controlling the same type of device using multiple instances of the lirc_serial driver.