Bell 9200 PVR Sucks

have been a PVR fan for quite some time. My first exposure was a TiVO series 1 on DirecTV, and then when Bell ExpressVu came out with their 5100, I immediately grabbed one. The difference between the 5100 and a TiVO series 1 is quite stunning – no name based recording or season’s passes. In spite of the shortcomings, I happily used the 5100 for a couple of years, until the hard drive started getting more and more flakey.

What a perfect opportunity to check out ExpressVu’s latest offering – the 9200. This beast offers HD, dual tuners, 180 hours of recording time, and name based recording! At least, that’s what all the advertising said. In reality, there’s no name based recording. After much hype advertising the feature as coming soon for the last six months or so, they have quietly dropped all mention of it on their website.

The second problem is that my unit ‘stutters’ when playing back recorded shows. Not just some of the time – it stutters about every two mintues or so continuously! It makes watching recorded shows unbearable. I thought I must have got a defective unit. I did some searching on the web to see if this was a known issue. Boy was I surprised. I found some good threads over at digitalhomecanada.com with people experiencing the exact same issue. In fact, these people had researched the problem enough to pinpoint the problem to a particular brand of hard drive.

This morning, I called Bell ExpressVu to ask them about the problems I was experiencing. After initially denying any knowledge, they conceded that there was a known problem with the software, and that a fix was going to come out to address the problem. They were unable to provide me with an estimated date for the fix, and they seemed to think that the stuttering was okay and wouldn’t affect my enjoyment of Bell ExpressVu. They were also unable to provide a delivery date for the promised name-based recording feature. I’m not happy with their explanation, and I’m not happy that I’m not able to watch recorded shows with this unit. I’ve escalated the problem to a manager (yeah, right) who will call me back within 48 hours. I’ll let you know what they say.

Update: 2006-04-17 20:37

Discussions on the boards seem to suggest that the 9200s that exibit problems have Maxtor hard drives in them. My son suggested that perhaps Maxtor’s ‘Acoustic Management’ feature might be enabled on the drive, which would definitely affect performance, and might be the cause of the stuttering. I might just have to break down and void the warranty to pull the drive out to verify if this is actually the case. I’ll post an update if I pull it apart.

Tech Podcasting Has Jumped The Shark

I think I’m listening to history happening. I think that podcasting is the most incredible thing to happen to online content in quite some time. I’m a big fan of tech-related podcasts – mostly from the ex-TechTV crowd. However, this week I was shocked to hear the latest from Diggnation and This Week In Tech. Diggnation episode 38 has fallen to an all-time low. This was a live podcast from Reno Nevada. Unfortunately, Kevin and Alex had already hit the bar long before taping began, and the show quickly descended into chaos. TWIT’s episode 48 was an Apple 30th anniversary special. There was none of the usual TWIT crowd there. Instead, it was Leo and Woz having a love-in reminiscing about the ‘old days’. This carried on for an hour and a half. The audio quality was terrible, with some of the guests barely audible.

I’m beginning to suspect that these people have been doing the podcast thing for too long, and now the novelty has worn off. The once-surprising level of professionalism shown by these amateur broadcasters has descended into meaningless drivel. I’m seriously hoping that this week was just a blip, and these (and other) podcasters will pull up their socks. Otherwise, this medium is doomed.

Turning RSS Feeds in to Movable Type Entries

A while ago, I created the site PsychicProgrammer.com as a place to gather up programming-related stories from various corners of the Internet. I whipped up some code to automatically gather RSS feeds from various programming-related websites and pull the stories to turn them into Movable Type postings. I’ve had a few people ask how I did this, so I thought I’d post the code with some explanation of what’s going on.

#!/usr/bin/perl

use strict;
use XML::RSS::Parser;
use RPC::XML;
use RPC::XML::Client;
use Date::Manip;
use LWP::Simple;
use DBI;

The script is written in Perl, and I’m using a few nifty Perl modules available from CPAN.
XML::RSS::Parser – a great module for dealing with RSS feeds.
RPC::XML – used to communicate with Movable Type via RPC.
LWP::Simple – used to retreive the RSS feed document.

my @info=({'url'      => "http://www.oreillynet.com/pub/feed/16?format=rss2",
           'name'     => "Perl.com",
           'category' => "Perl.com",
           'datetype' => 2},
          {'url'      => "http://www.digg.com/rss/indexprogramming.xml",
           'name'     => "Digg.com",
           'category' => "Digg.com",
           'datetype' => 1},
          {'url'      => "http://www.oreillynet.com/pub/feed/20?format=rss2",
           'name'     => "Xml.com",
           'category' => "Xml.com",
           'datetype' => 2},
          {'url'      => "http://www.dotnetjunkies.com/WebLog/saasheim/rss.aspx",
           'name'     => "Steinar Aasheim's Blog",
           'category' => "Steinar Aasheim's Blog",
           'datetype' => 1},
          {'url'      => "http://tomcopeland.blogs.com/juniordeveloper/rss.xml",
           'name'     => "Junior Developer",
           'category' => "Junior Developer",
           'datetype' => 1},
          {'url'      => "http://programming.newsforge.com/programming.rss",
           'name'     => "Newsforge.com",
           'category' => "Newsforge.com",
           'datetype' => 2});

Here, I set up a structure containing the RSS feeds that I’m going to retreive. Of course, to scale this, it would be better to store this information in a SQL table.

my $username='user';
my $password='password';
my %category;
my $i;
my $dbh;
my $sth;
my $q;
my $seencount;
my $feed;
my $site;
my $xmldoc;

Some variable definitions.

# Set up database connection
$dbh=DBI->connect("dbi:Pg:dbname=p","psy","password") or die "Can't open database";

# Set up XML-RPC interface
my $cli=RPC::XML::Client->new('http://www.psychicprogrammer.com/mt/mt-xmlrpc.cgi');

# Set up XML parser
my $p=new XML::RSS::Parser;

# Get category list
my $req=RPC::XML::request->new('mt.getCategoryList','1',$username,$password);
my $resp=$cli->simple_request($req);
foreach $i (@$resp)
{
  $category{$i->{categoryName}}=$i->{categoryId};
}

Here, we set up a database connection. The database is used to record which articles have been seen before, so that we don’t have any duplicates. Next, we set up the RPC interface to the Movable Type blog. Make sure you put your correct URL in here for your blog. Then, we talk to MT to get a list of the categories. We do this because we need to map the RSS feed name to the appropriate MT category.

if($DEBUG)
{
  foreach $i (%category)
  {
    printf("$category{$i} $i\n");
  }
}

Some debugging script to dump the category information. This is a good check to make sure that the RPC interface is working. This script assumes that there is a pre-existing category defined for each RSS feed. Use the MT interface to create new categories.

foreach $site(@info)
{
  printf("*** Processing for site %s\n\n",$site->{'name'}) if $DEBUG;

  $xmldoc=get $site->{'url'};
  $feed=$p->parse($xmldoc);

This starts a loop for each RSS feed defined above.

  foreach my $i ( $feed->query('//item') )
  {
    my $datenode;
    my $date;
    my $titlenode = $i->query('title');
    my $linknode = $i->query('link');
    my $descnode = $i->query('description');

    if(($site->{'datetype'})==1)
    {
      $datenode = $i->query('pubDate');
      $date=UnixDate($datenode->text_content,"%Y-%m-%dT%H:%M:%S");
    }

    if(($site->{'datetype'})==2)
    {
      $datenode = $i->query('dc:date');
      $date=UnixDate($datenode->text_content,"%Y-%m-%dT%H:%M:%S");
    }

    my $dd = $descnode->text_content .
      "<br>Link: <a href=\"" . $linknode->text_content . "\">" .
      $linknode->text_content . "</a>";

For each entry in the RSS file, start pulling out information we’re interested in. I came across a problem with recording the date. If found both pubDate and dc:date tags. I use a variable called datetype to determine which one to look for in the RSS feed. I add a line of HTMl to the end of the article content that includes a link back to the original article.

    # Check to see if we've seen this one yet
    $q="SELECT count(source) FROM seen WHERE index=" . $dbh->quote($linknode->text_content);
    $sth=$dbh->prepare($q);
    $sth->execute();
    ($seencount)=$sth->fetchrow();
    $sth->finish();
    if($seencount==0)
    {

This is where we check our SQL table to see if we’ve seen this article URL before.

      # Post article
      printf("Posting %s\n",$titlenode->text_content) if $DEBUG;
      my $req=RPC::XML::request->new('metaWeblog.newPost',
                                     '1',
                                     $username,
                                     $password,
                                     RPC::XML::struct->new(
                                       'title' => RPC::XML::string->new($titlenode->text_content),
                                       'description' => RPC::XML::string->new($dd),
                                       'dateCreated' => RPC::XML::string->new($date),
                                       'mt_tb_ping_urls' => RPC::XML::array->new(
                                         $linknode->text_content)
                                     ),
                                     RPC::XML::boolean->new(1)
                                    );
      my $resp=$cli->simple_request($req);

This executes the RPC call to MT to actually post the article. Note that we attempt a trackback ping to the original article. This array can also be populated with other tracking sites, such as Technorati.

      # Change category
      $req=RPC::XML::request->new('mt.setPostCategories',
                                  $resp,
                                  $username,
                                  $password,
                                  RPC::XML::array->new(
                                    RPC::XML::struct->new(
                                      'categoryId' => $category{$site->{'category'}},
                                      'isPrimary' => RPC::XML::boolean->new(1)
                                    )
                                  )
                                 );
      $resp=$cli->simple_request($req);

Now we change the article’s category to be the same as the feed’s name.

      $q="INSERT INTO seen (index, source) VALUES (" . $dbh->quote($linknode->text_content) .
         ", " . $dbh->quote($site->{'name'}) . ")";
      $sth=$dbh->prepare($q);
      $sth->execute();
      $sth->finish();
    }
  }
}

# Close database
$dbh->disconnect();

We write a line into the database to say that we’ve seen this article before. We loop back for the rest of the articles, for the rest of the feeds. Finally, we close the database connection.

That’s it! I run this code from a crontab entry every hour or so. As soon as new articles are discovered in the RSS feeds, they will be magically turned into postings on a Movable Type blog, thanks to the wonders of XML-RPC.

I’d appreciate any comments or feedback if you decide to use this code in your own projects. Have fun!

Broken Lawnmower

Spring has finally arrived here in the Great White North. Time to give the lawn a trim (it’s looking pretty bad because it was getting kind of long last fall and then, all of a sudden, it was covered by snow). My wife pulled out the lawn mower and tried to start it. After sitting all winter, it didn’t want to start. I thought that it was about time it had some TLC. I’m not the most mechanical of people, but I can pull spark plugs and check filters. Working on the lawn mower on the garage floor wasn’t something my aching back and knees really wanted to do, but there wasn’t anywhere else to work on it (perhaps the kitchen table? No, I don’t think my wife would be too happy about that). A workbench in the garage! That’s what I need. I had some particle board and 2×4’s left over from a shelving project I did last fall, so I had most of what I needed. A few hours with a saw and drill, and I had a perfectly workable workbench. Well, now I was inspired. A quick trip to the hardware store, and I put up some pegboard behind the bench. Finally, a place to organize all of those ‘big’ tools that don’t fit in my electronic toolbox. I knew it was time to stop when I was seriously contemplating tracing out the tool outlines on the pegboard.

Contesting

It’s time once again for the CQ WW WPX ham radio contest. I like to participate in contests just to get a few more callsigns in my logbook. However, this time, I’m not sure I’m going to get much chance. We’re picking up a new puppy tonight, and I think spare time is going to be a rare commodity over the next little while. I’ll have to squeeze a few contacts in just so I can say I participated. I’ll post some puppy pictures in my moblog tonight.

Google Pays For Settlement With Adsense?

Google has announced a proposed settlement to settle claims of click-fraud. The part of the settlement that concerns me is that the $90 million isn’t to be paid out in cash – it’s to be paid out in advertizing credits. I haven’t seen any online commentary about the impact to Adsense subscribers. Imagine if Google decides to provide the $90 million in advertizing using their Adsense program. What if they decide to pay out to the Adsense subscribers (the people who actually display those context-sensitive ads) much lower than the going rate for theat ad? They could even pay zero (like a Public Service Ad), and the Adsense subscriber couldn’t do anything about it. They probably wouldn’t even know!

Fixing an XBOX with a bad TSOP

Several months ago, I acquired a second XBOX to use as a media center in my house. I thought I would try to skip the expense of a modchip, and I tried to flash the XBOX’s TSOP directly. Unfortunately, something went wrong, and I ended up with an XBOX that wouldn’t boot. I had to break down and purchase a modchip to replace the motherboard BIOS. Well, a few days ago, this XBOX developed a nasty problem whereby it would switch itself off after a random amount of time. Because the family is hooked on watching IPTV via the XBOXes, I went out and purchased a replacement, and moved the modchip over to the new unit.

I had a dead XBOX on my desk, and thought that I had nothing to lose by seeing if I could fix it. The first problem was fixing the switching-off problem. After careful inspection of the motherboard, I discovered that one of possibly several electrolytic capacitors had leaked in one area of the board. The main suspect was the 1-Farad clock backup capacitor. I replaced the few capacitors in the immediate area. I also replaced the heat transfer paste between the heatsink and CPU.

Powering up the unit (with a borrowed modchip) showed that the power-off problem appeared to be fixed. Good! Now I needed to address the TSOP issue. I spent many hours scouring the net to find a solution that didn’t involve removing the TSOP from the motherboard (a very daunting task). I discovered that I couldn’t boot from a BIOS on the LPC bus (that’s the header connector on the motherboard that most modern modchips plug into) and then access the TSOP to flash it. The solution ended up being building what’s called a 29 wire modchip. Yes, it’s as daunting as it sounds. The premise is simple – program a flash chip with a suitable BIOS, and solder address and data wires to the motherboard. As the name suggests, there’s 29 wires, and the contact points are very tiny. I used the diagrams at xbox-scene.com to construct the modchip. I also used this article to add the disable switch.

Several hours later I had a programmed flash chip (a 29F002 – 256K flash chip scavenged from an Asus P2B motherboard) with a disable switch soldered to the XBOX’s motherboard. I had to assemble a working XBOX with DVD drive and power supply on my bench, and hope it would live long enough to re-flash the TSOP. I powered it up, and it booted! I was successfully booting off of the new flash chip. I booted the Xebian distribution from DVD-R (I had to try three different media types before I found one that would successfully read in the XBOX drive). As soon as Xebian booted, I used SFTP to copy Raincoat 0.7 and a bios image file (the same one that I had burned on the flash chip) over to the /tmp directory on the XBOX. At this point, I used the switch to disable the replacement flash chip. I then used SSH to get a command prompt on the XBOX, and ran ./raincoat -p bios.bin. The screen said that the flash was successful. I tried rebooting the XBOX with the flash chip disabled. Success! I was booting from the internal TSOP.

I carefully removed the 29-wire mod and re-assembled the XBOX. I now had a modded XBOX with no modchip, and now every TV in the house has an XBOX running as a media center.

Adding Additional Analog Inputs on a Kantronics TNC

I just posted a how-to article describing adding additional analog inputs to a Kantronics TNC. Out ham radio club was installing a new APRS repeater, and had asked if there was any way of monitoring multiple analog values (specifically, two battery banks, the presence or absence of AC mains, and a temperature reading). I spent some time studying the schematics and doing some research on the web. I was unable to find any specific how-to articles other than vague references to using additional CPU pins. After building and testing the circuit, I decided to post an article describing the process for anyone interested in doing the same thing.

Lego Announces Next-Gen Mindstorms

Lego recently announced their next-generation follow-up to their popular Mindstorms robotics kits. The next generation is called Mindstorms NXT. It appears that Lego has listened to the requests of the Mindstorms community and incorporated several neat features. The most outstanding feature in my mind is bluetooth connectivity. The implications of a bunch of NXT robots able to communicate via bluetooth is incredibly exciting.

There are a few drawbacks, however. First, Lego has announced that there is no electrical compatibility with first-generation Mindstorms. Secondly, Lego has gone with a modified RJ11-style jack for connecting motors and sensors to the main unit. I’m sure that these connectors dragging around a big tub of Lego will soon find the listtle plastic tabs breaking off. Unfortunately, the offset-tab is not the MMJ style used by DEC. Lego has decided to offset the tab in the opposite direction. I have spent quite some time trying to source these connectors, but as yet I haven’t come up with anything.

Lego has announced a beta test program, with 100 lucky testers getting the opportunity to acquire a kit six months before release. In the questionnaire that went with the beta application, it looks like Lego is specifically looking for beta testers to blog about the product, develop models for uploading to Lego’s website, and to develop third party software and hardware for the NXT. If this is the case, and based on their previous history of releasing the developer’s kit, perhaps there’s some hope of a third party developing an interface device between classic Mindstorms and Mindstorms NXT.

My beta application is in. I can’t wait until the release.