MythTV with Multiple Cable Boxes Controlled by IR Blasters


This page is obsolete. These instructions will not work with newer Linux kernels. Modern Linux kernels have security features that prevent modification of kernel modules. The ability to duplicate a kernel module is central to the support of multiple serial IR blasters. This document will work with Ubuntu versions up to 12.04, but only early kernels in that release.


1.0 Requirements
2.0 Introduction
3.0 Serial Port Drivers
4.0 LIRC Daemons
5.0 Changing TV Channels
6.0 Electronic Program Guide (EPG)
7.0 Adding New EPG Channel Lineup to MythTV
8.0 Changing Channels With MythTV
9.0 Additional LIRC Resources


1.0 Requirements

The audience for this document:
  1. You have a working MythTV backend with multiple analog tuners
  2. Your cable company is forcing you to use external cable boxes
  3. You have at least two cable boxes available for MythTV
  4. Your MythTV backend has at least two serial (COM) ports
  5. You are comfortable with the Linux command line
What this document will do:
  1. Show you how to setup multiple IR Blasters
  2. Show you how to retain at least one tuner without a cable box
  3. Make it all work seamlessly within MythTV
What this document will not do:
  1. Teach you how to install and/or setup MythTV
  2. Hold your hand through the many required Linux commands.
The specific setup upon which this document was tested:
  1. MythTV 0.24
  2. Ubuntu 11.10 (as Mythbuntu 11.10)
  3. 2 Hauppauge PVR-350s
  4. 1 Hauppauge PVR-250
  5. 2 serial IR Blasters from
  6. Two Comcast DTA cable boxes and remotes (3067BC2-R)
  7. Standard definition cable TV service (HTDV not subscribed to) EPG provided by

2.0 Introduction

My existing MythTV installation has two Hauppauge PVR-350 tuners and one Hauppauge PVR-250 tuner. The original setup was analog cable TV with an available channel range of 2-99. Comcast has converted our local cable to ‘rebuild’ status which provides analog channels in the range of 2-22 only. Access to standard definition channels 23 and above now requires installation of a DTA (Digital Transport Adapter). My home owners association negotiated to provide two of these DTAs to each home owner. I also got one additional unit capable of on-demand and on-screen TV guide. I’ll save that for watching live TV on the big screen. I don’t use the MythTV box for watching live TV anyhow.

The plan is to connect the two DTAs to the MythTV box. This leaves one of the three available tuners only capable of tuning in channels 2-22. In order to have MythTV control the DTAs I needed the support of two serial IR Blasters that I purchased from I R Blaster . Info. Luckily, my motherboard has the two required legacy COM ports. External USB to serial adapters will not work.

All of the instructions in this guide are executed at a command line. You must be logged in as the root user.

3.0 Serial Port Drivers

The first thing that needs to be done is to disable the default drivers that control the two serial ports. This can be done by issuing these commands:

/bin/setserial /dev/ttyS0 uart none
/bin/setserial /dev/ttyS1 uart none

Then we need to install replacement modules that provide IR drivers for each serial port. The name of this driver is lirc_serial.ko. Sadly, this module supports only one serial port at a time. To support two serial ports we need two copies of the driver module. A web page at:

came up with this idea of duplicating the driver by substituting all occurances of the driver name within the binary file:

cat lirc_serial.ko | sed -e 's/lirc_serial/lirc_ser_01/g' > lirc_ser_01.ko

Here we create a new driver called lirc_ser_01.ko. The author of this web page suggests doing this on the fly each time a new version of the kernel gets installed. A little less complicated way is to create the driver if it is found to not exist at the time that it is to be loaded. My script does just that, as well as uninstalling the original serial port drivers as shown above:

kernel=`uname -r`
module=$(printf "lirc_ser_%02d" $1)
if [ ! -e ${path}${module}.ko ]; then
 	cat ${path}lirc_serial.ko | \
 	sed -e "s/lirc_serial/${module}/g" > ${path}${module}.ko
 	/sbin/depmod -a
/bin/setserial /dev/ttyS${1} uart none
/sbin/modprobe --ignore-install $module

Place this script into the directory /etc/lirc and name it with executable permissions. The script is called from a new modprobe.conf file located in /etc/modprobe.d which we will name lirc-serial.conf:

#COM1 equivalent, /dev/ttyS0
options lirc_ser_00 irq=4 io=0x3f8
install lirc_ser_00 /etc/lirc/ 0

#COM2 equivalent, /dev/ttyS1
options lirc_ser_01 irq=3 io=0x2f8
install lirc_ser_01 /etc/lirc/ 1

Note that is called with a single argument representing the desired /dev/ttyS number; 0 or 1. At this point it may be a good idea to reboot to see if the modules get loaded properly. After rebooting, run “lsmod” and look for:


Actually, you will only see lirc_ser_00 at this point due to the default /etc/init.d/lirc script. Once the script has been replaced, in section 4.0 below, both modules will be loaded.

in the output. If you do not see both, check to see if the modules were properly created at:


where 3.0.0-16-generic is replaced with whatever kernel you are currently using; which you can get by running “uname -r“. If you still do not see the problem, check the /var/log/syslog and /var/log/dmesg logs for clues.

4.0 LIRC Daemons

Now that we have our IR serial port drivers installed, the next thing to do is to create lirc daemons for each of them. The daemons are started by /etc/init.d/lirc but sadly the author of this script only made it possible to start one each of a transmitter and a receiver lirc daemon. That same web page referenced above:

has a replacement for /etc/init.d/lirc that works quite well as is. It extends the code to support two IR transmitters. Save this new version in place of the default /etc/init.d/lirc.

Now we will modify the file /etc/lirc/hardware.conf so that the script /etc/init.d/lirc knows that it needs to create two lirc daemons. Add the following lines to the /etc/lirc/hardware.conf file:

TRANSMITTER_MODULES="lirc_dev lirc_ser_00"

TRANSMITTER2_MODULES="lirc_dev lirc_ser_01"

By convention of the script /etc/init.d/lirc, the IR transmitters are named TRANSMITTER and TRANSMITTER2. The configuration parameter TRANSMITTER(2), such as “IR Blaster 1”, is an arbitrary name for the IR device. The MODULES parameter indicates which kernel modules to load. The DEVICE parameter defines the name of the lirc device used to access the lirc daemon being started. And the LIRCD_CONF parameter is a path to a file containing remote specific IR code translation data.  In this case 3067BC2-R is the file containing the IR codes for the Comcast DTA box. I downloaded the 3067BC2-R file from this URL:

The data files for many different remote controls can be found here:

You can now either reboot your MythTV computer or execute the following command as root:

/etc/init.d/lirc restart

This will create the two lirc daemons we just defined. Type the following command to confirm this:

ps ax | grep lircd

There should be two items like the following:

/usr/sbin/lircd --output=/var/run/lirc/lircd1
/usr/sbin/lircd --output=/var/run/lirc/lircd2

If you do not see these daemons, check the logs /var/log/syslog and /var/log/dmesg for clues.

5.0 Changing TV Channels

The driver modules for each of our IR transmitters are now installed. We also have an lirc daemon attached to each driver. This would be a good point to do some testing. The following script will allow you to send IR remote commands from the keyboard to change the channel on each DTA:

use Getopt::Std;
use constant false => 0;
use constant true  => 1;

my $remote_name = "Comcast_3067BC2-R";
my $verbose = false;
my $device = "";
my $interval = "0.5";
my %options = ();
getopts("vhd:i:", \%options);

if (scalar(@ARGV) == 0 || defined $options{h})
        print "usage: [-d device] [-i n] [-v] [-h] channum\n\n";
        print "where:\n";
        print "\t-d device    send command to this device\n";
        print "\t-i n         seconds between ir digits (e.g. 1.25) default: 0.5\n";
        print "\t-v           enable verbose mode\n";
        print "\t-h           help (this screen)\n";
        print "\tchannum      Integer channel number.\n";

if (defined $options{v}) { $verbose = true; }
if (defined $options{d}) { $device = "-d " . $options{d}; }
if (defined $options{i}) { $interval = $options{i}; }

my $channel = $ARGV[scalar(@ARGV) - 1];
if ($verbose) { print "channel is $channel\n"; }
@channel = split(//, $channel);
foreach (@channel)
        if ($verbose) { print "Sending KEY_$_\n"; }
        `irsend $device SEND_ONCE $remote_name KEY_$_`;
        `sleepenh $interval`;

if ($verbose) { print "Sending KEY_ENTER\n"; }
`irsend $device SEND_ONCE $remote_name KEY_ENTER`;

This Perl script borrows the best design elements found in the channel change scripts from these two web pages:

This modified version permits specifying which IR transmitter will emit the IR signal. You will have to install the package sleepenh to have delays between the output of IR signals. Place this script in /etc/lirc, name it and set the executable permissions. You run the script by typing:

/etc/lirc/ -d /var/run/lirc/lircd1 channum

to send channel change command to the IR transmitter at /dev/ttyS0 and:

/etc/lirc/ -d /var/run/lirc/lircd2 channum

to send channel change command to the IR transmitter at /dev/ttyS1. The argument ‘channum‘ is the desired decimal channel number. It is necessary to use the device in /var/run/lirc rather than in /dev as the latter is write protected.

Hook a TV to the output of the Comcast DTA and give it a try. Plug each of your IR Blasters into a serial port and attach to the IR lead to the front of your DTAs. Type a command such as:

/etc/lirc/ -d /var/run/lirc/lircd1 10

to change the first DTA to channel 10. If you see channels changing on both DTAs at the same time then you have IR leakage. I find a lot of black electrical tape can cure this problem. If you get one to work, but not the other, then you probably have a cabling problem. I had the wrong type of ribbon cable bringing my serial out to the back panel. If you get no channel changes on either DTA; first did you remember to reboot your computer after you made all of those script and file changes above? If all else fails check the logs /var/log/syslog and/var/log/dmesg for clues.

6.0 Electronic Program Guide (EPG)

At this point you should be able to reliably change each DTA to any TV channel from the keyboard. If that is the case then it is nearly time to integrate this setup into the MythTV backend. But first you will have to update your subscription to

It is our intent is to provide cable box support for multiple tuners, yet still have at least one other tuner still tuning old fashioned analog cable. Your subscription provides the channel lineups for whatever service you subscribe to from your cable company.

My service was for standard analog TV with channels in the range of 2-99, and this is what schedules direct calls “Comcast – Cable”. I still see all of the channels listed, but everything over channel 22 shows just snow. This channel lineup is fine for our newly attached cable DTA boxes, but we need an abridged lineup for the remaining analog tuner(s). For Comcast, this abridged lineup is called “Comcast – Rebuild” and provides only the analog channels from 2 through 22.

You will have to log into your account and add this abridged lineup to your account. It is necessary to have both lineups so that MythTV knows what channels are supported by each installed tuner.

NOTE: After I added the new lineup to my account it took some time for it to be available via myhtfilldatabase. If you continue to have problems, you can try to readd all of your channel lineups:

or use their support page:

7.0 Adding New EPG Channel Lineup to MythTV

The command /usr/bin/mythtv-setup will be used to add the new EPG channel lineup. From the menu select the option “Video Sources”. This is where the EPG channel lineup is defined. You will have at least one existing lineup there already. In my case this was the lineup for channels 2-99. I had named it simply “Comcast”. Now you must create a new EPG channel lineup for the abridged channel set to be used with the tuner(s) not connected to a DTA. I called this lineup “Comcast Analog” and specified “Comcast – Rebuild” as its lineup.

Back at the /usr/bin/mythtv-setup main menu, select the item “Input Connections”. Here we reassign the tuner(s) without a DTA to our newly created “Comcast Analog” channel lineup. The screen item “Video Source” is used for this purpose. Then click “Fetch Channels from listing source” to get the abridged channel lineup. OK, this will not likely achieve the results you expect. The original channels may still remain in the list. The channel list may have to be cleared before fetching the new channels. One way to do this is to use the “Channel Editor” from the main menu and delete all of the channels one at a time. Then come back to “Input Connections” to fetch the channel list.

8.0 Changing Channels With MythTV

Once again, the command /usr/bin/mythtv-setup will be used, this time to reconfigure MythTV for control of the IR Blasters. From the menu, select the option “Input Connections” to connect MythTV to our channel changing script /etc/lirc/ For each tuner, there will be a screen item “External channel change command:” which will be blank by default. Set the value of this item to:

/etc/lirc/ -d /var/run/lirc/lircd1

for the tuner connected to the DTA controlled by the serial port /dev/ttyS0. Set the value of this item to:

/etc/lirc/ -d /var/run/lirc/lircd2

for the tuner connected to the DTA controlled by the serial port /dev/ttyS1. On these same screens for each tuner, set the value of “Preset tuner channel” to whatever channel the DTA uses for output. This is usually either channel 3 or 4.

That’s it for the configuration.

9.0 Additional LIRC Resources

 Posted by at 10:07 pm

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>