IR remote control of servo using Arduino

Got a little bit done of the control for the sound system… I wasn’t getting good results from the Sharp GP1U5 module I was using until I stumbled upon some work by Ken Shirriff. He has written an IRremote library that supports both sending and receiving and includes support for a few different protocols.

The supported protocols don’t seem to cover the remotes I’m playing with, but luckily, he also did a post on handling arbitrary remotes by generating a hash value. Using that as a starting point, I cobbled together a fairly simple proof of concept sketch.

/*
* IR Remote controlled servo
*
*
*
* IR Remote code from Ken Shirriff (www.arcfn.com), specifically this post:
* http://www.arcfn.com/2010/01/using-arbitrary-remotes-with-arduino.html
*/

#include
#include

Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

#define LEDPIN 13

int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

int volume = 0;
int max_volume = 180; // determined by max position of the servo
int mute = 0;

void setup()
{
irrecv.enableIRIn(); // Start the receiver

myservo.attach(9,600,2400); // attaches the servo on pin 9 to the servo object with pulse widths for Hitec
// servo

myservo.write(0); // tell servo to go to base position
delay(1000);

Serial.begin(9600);
}

// Compare two tick values, returning 0 if newval is shorter,
// 1 if newval is equal, and 2 if newval is longer
// Use a tolerance of 20%
int compare(unsigned int oldval, unsigned int newval) {
if (newval < oldval * .8) {
return 0;
}
else if (oldval < newval * .8) {
return 2;
}
else {
return 1;
}
}

// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
#define FNV_PRIME_32 16777619
#define FNV_BASIS_32 2166136261

/* Converts the raw code values into a 32-bit hash code.
* Hopefully this code is unique for each button.
*/
unsigned long decodeHash(decode_results *results) {
unsigned long hash = FNV_BASIS_32;
for (int i = 1; i+2 rawlen; i++) {
int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
// Add value into the hash
hash = (hash * FNV_PRIME_32) ^ value;
}
return hash;
}

void loop() {
if (irrecv.decode(&results)) {
unsigned long hash = decodeHash(&results);
switch (hash) {
case 0x4B12992B: // Vol Up
case 0x22D912B8:
Serial.println("Volume Up");
volume += 1;
if ( mute == 1 ) {
volume -= 1;
mute = 0;
}
break;
case 0x1BE8C80D: // Vol Down
case 0x776C6E79:
Serial.println("Volume Down");
volume -= 1;
if ( mute == 1 ) {
volume += 1;
mute = 0;
}
break;
case 0x92DFD41C:
Serial.println("Mute");
mute = 1;
break;
default:
Serial.print("'real' decode: ");
Serial.print(results.value, HEX);
Serial.print(", hash decode: ");
Serial.println(hash, HEX);
}
irrecv.resume(); // Resume decoding (necessary!)
if ( volume max_volume ) { volume = max_volume; }
if ( mute == 1 ) {
myservo.write(0);
}
else {
myservo.write(volume);
}
}
}

I’m using a Hitec HS-325HB servo with this code, and I implemented volume controlling from two different remotes I had kicking around – only one had a mute button.

Mute is handled by moving the servo to the zero position, and the next volume up/down will unmute by returning the servo to the correct position.

With the Arduino side basically figured out, the next step is to figure out the best way to tie the volume control and Arduino together. One potential problem is that with the servo hooked up, turning the volume control manually will probably not be possible. I’ll probably add a mute button and up/down buttons to allow control without needing to find the remote control. Doing that should be simple enough, and make it a lot more user friendly.

Playing with Arduino

I finally managed to start playing with the Arduino again – I’ve had one for a couple years, and played with it a bit as soon as I got it, but then it sat on my shelf of unfinished projects.

My collection actually has three Arduinos – one is a Freeduino with a USB interface, and the other two are intended for use on a breadboard (a Boarduino and a Bare Bones Board). For a while, I’ve been intending to use the Freeduino to program the chips on the other boards since I don’t have the right cable to connect them otherwise, but I hadn’t realized that on the arduino.cc site, they actually have instructions for doing that. In addition, they show the most minimal setup possible – which only requires an AVR, a resistor, a capacitor and a few wires if you use the internal oscillator. How much else you need depends on what you are using the Arduino for, but it certainly makes the idea of embedding the Arduino in a project more interesting since it drops the base cost under $10.

I’m currently playing with two projects – reading a SD card, and controlling a servo. The SD card is to see if a ‘dead’ card that a friend has can be accessed via SPI. I’m assuming that the typical USB readers use something other than SPI since that is a slower mode of access, and is optional on microSD cards. I’m going to set up a breadboard with a circuit to access my test card (a 32 Mb Canon card) until I get a chance to pick up a 74AHC125. The issue is that SD cards run at 3.3V, while the Arduino is at 5V. I can use a resistor divider setup to interface to SD cards, but if I want to support SDHC cards, I need to be able to meet the 10ns risetime requirements in the spec, which the 74AHC125 should manage.

The servo is going to be controlled by the Arduino via an IR remote. I have an IR receiver module that keeps things simple – feed it power and it spits out a clean signal that you can connect to the Arduino. From there you need to decode the pulses to figure out what key was pressed, and take appropriate action.

As far as the servo goes, I have never used one before, so when I hooked one up today, I wasn’t sure how difficult it was going to be. There is a sample sketch that is provided with the Arduino IDE that sweeps the servo back and forth, and I loaded it up on the Arduino and expected to see some motion. No such luck…. no motion at all. I checked with Google, and found some forums where other people were having trouble, but nothing that appeared to be my problem.

Then I did a check on my setup – power and ground hooked up? Check. Control signal? Check. Servo voltage of 5V enough to drive it? Yup. Control signal hooked up to the right Arduino pin? Uh-huh. I finally tracked the problem down to the jumper wires I had used to connect everything. I had soldered some pins to each end of some lengths of wire to make it easy to get a good connection with the stranded wire I was using – unfortunately, the control wire had a bit of extra solder on the one side. And wouldn’t you know it, that was the side that was facing the power connection. I had a short between 5V and the control signal, so as far as the servo was concerned, there was no control signal.

Once I fixed that little issue, the servo started turning back and forth as expected. Now all I have to do is remember how to decode the IR input and make it control the servo. That shouldn’t be very hard, should it? In any case, I’m going to play with it tomorrow and see where I get. I’ll try real hard to do a decent write-up if I manage to get it working – same for the SD card reader….

Rare Earth Magnets to the rescue

Just found another thing rare earth magnets are good for – fishing wires at a 90 degree angle….

Normally, if I’m trying to run wires, I use fish tape (also known as a draw wire or draw tape). It works great if you are trying to run stuff through conduit, or in a fairly straight line. Where it doesn’t work so well is if you are trying to go around a corner.

In the past, my solution has been to feed in wires from both sides with hooks bent at the ends, and try and hook them together. It generally works after a lot of attempts, a lot of swearing and a lot of frustration.

Today, I had the bright idea of using rare earth magnets to make the process a whole lot easier…. one goes on the end of a string that gets dropped through the vertical access, the other on a rigid pipe or stick that is fed in the horizontal one. Get the two close to each other, and ‘click’, they are attached and you can pull the string out with the stick. If you need to feed up and over, just use an appropriate length of pipe, and wire instead of string (since it’s hard to feed string through a pipe). The wire can be fed through the pipe, and you can use the pipe to lift the magnet into position. Once the two magnets have made contact, the pipe can be lowered – the wire will pull through the pipe and you can then pull that through as before.

Canon iP2200 – borderless printing under Linux

I picked up a Canon printer a while back – specifically a Pixma iP2200. Getting it to work properly under linux has turned out to be… somewhat challenging.

Since I run Ubuntu at home, the page at the Ubuntu wiki does a good job of getting the printer set up and working.

The only trouble is that printing photos turned out to be a problem – none of the programs I tried seemed to be able to print properly. Most of them seemed to use gutenprint (aka gimp-print) which had no driver for the iP2200 by default, and when I specified the ppd file from the Canon setup, I wound up with about 3/4 of an inch of the left side of the image on the far right of the paper. Even when I did manage to get a decent printout, I was stuck with a border on the print.

After looking into it for quite a while, I happened across a document for the iP2500 – it talked about a program (supplied with the Canon driver for the printer) called cifip2500. It supported command line options for borderless printing.

[EDIT: It turns out that if I had bothered to grab the manual Canon supplied, the information is there as well....]

Checking on my own system, I found a corresponding program called cifip2200. Running cifip2200 –help gave me this output:

Canon Inkjet Print Filter Ver.2.60 for Linux
Copyright CANON INC. 2001-2006
All Rights Reserved.

Usage: cifip2200 --gui (gui mode)
cifip2200 [switches] [file]

switches: [ --imageres 1 - 32767 ]
[ --cartridge cartridgetype ]
[ --media mediatype ]
[ --halftoning halftonetype ]
[ --quality 1 - 5 ]
[ --grayscale ]
[ --papersize size ]
[ --paperload position ]
[ --borderless ]
[ --extension 0 - 3 ]
[ --location position ]
[ --fit ]
[ --full ]
[ --percent 20 - 400 ]
[ --copies 1 - 999 ]
[ --renderintent intent ]
[ --gamma 1.4 / 1.8 /2.2 ]
[ --balance_c -50 - 50 ]
[ --balance_m -50 - 50 ]
[ --balance_y -50 - 50 ]
[ --balance_k -50 - 50 ]
[ --density -50 - 50 ]
[ --inkcartridgesettings cartridgetype ]
[ --bbox left,bottom,right,top ]

As you can see there is a –borderless option, and options to set lots of other things as well. During my first attempt, I was surprised to get lots of control characters scrolling across my screen – turns ou8-bit per color RGB/8-bit Gray/Index/8-bit per color α RGB/8-bit α Grayt that the program output is intended to be redirected to the printer (or a file). My print command looked like this:

cifip2200 –media glossypaper –papersize 4X6 –fit –picture.tif > /dev/usb/lp0

That generated a very nice picture (in this case of my dog with antlers, taken for Christmas), but didn’t work until I ran it as root, and shut down cups, since it complained that the printer was busy.

So, the full list of restrictions at the moment with this method:
1) Limited file formats based on documentation for the iP2500 version:
TIFF:Uncompressed mode only
BMP: Only 8-bit per color RGB
PPM: Only 8-bit per color RGB (binary format)
PNG: 8-bit per color RGB/8-bit Gray/Index/8-bit per color α RGB/8-bit α Gray

2) Must be run as root

3) Cups must be stopped to allow access to printer

Presumably the pstocanonij program used as the cupsFilter in the ppd file takes the postscript generated for cups, and converts it into a supported format which is then printed using cifip2200. This is supported by the fact that the bottom of the ppd file has options that match the above options very closely (except for –boderless not being present).

One thing that puzzles me is that no resolution is specified for cifip2200 – does it choose based on the quality setting, and the input file? If so, then resolution settings in the .ppd file are merely for the postscript file (and conversion to image). In any case, I have a solution for now and some more testing to do to determine how to get optimal quality. If I recall correctly, the pstocanonij code is available, so once I get everything figured out, it may be possible to add the borderless setting, either by default or as an option.

[edit: The documentation says that the default resolution is 120dpi, and gives an example of setting it to 60dpi. Seems strange considering the specs say 600-2400 dpi...]

-This is my first attempt at a post using the QTM blogging software-

8830 Media Format followup

I wasn’t completely sure that I was correct when I said that the 8830 required an .mp4 container, but I’ve come across a Document on the BlackBerry site that lists supported media for the 8100, 8300 and 8830. It clearly states ‘The BlackBerry World Edition smartphone is unable to play .avi files’.

Not sure why it can’t, when the rest can, but it certainly explains my trouble trying to generate playable .avi files.

I also came across information that suggests that mencoder can output using the correct container format, and that the trouble could be the fourcc being used…. I’ll follow up on that once I’ve had a chance to do some testing.

update:

While you can convince mencoder to use other containers, the support is still buggy. The .avi container is the one to stick with if using mencoder, unfortunately, that makes it useless for the 8830.

GPS and Video on the Blackberry 8830

We switched service providers at work, and as a result switched to new Blackberrys. Since my position involves international travel, that meant that I got one of the spiffy ‘World Edition’ 8830s. The two things about it that I wanted to explore a little were the gps capability and it’s media support.

On the gps front, it has a full internal gps, unlike a lot of cell phones that can only determine location with the assistance of cell towers. There are a few commercial applications out there that support the unit, but I was unwilling to pay $25 or more when the unit already has an included mapping package and the ability to install google maps. Since the missing feature as far as I’m concerned is logging of position over time, I naturally went looking for open source solutions. I found a few different programs, but the one that worked for me was bbTracker. It tracks the position, displays it on the screen, and saves the track to the Blackberry. Once you have a saved track, you can export it in a couple of formats, and use it to do things like display in Google Maps.

I did run into one problem with bbTracker – it seemed like it wouldn’t work for me at first, everytime I tried to use it, it would crash. The crashing is definitely a bug, but there turned out to be an easy workaround. The problem is that if no gps position has been calculated when you start a track, when it gets the first position it crashes. To avoid this, you need to wait for a position to be displayed before starting a track. Other than that, it does what I want. The next trick is to take the track data and use it to automatically tag my photographs with location data.

Once I had gps working, I then turned my attention to converting video into a format that would play on the 8830. RIM has a page that lists the supported codecs, etc. but I had a lot of trouble getting anything to work. It seemed like no matter what I did, it told me the format was not supported. Since I’m primarily a linux user, the fact that the Roxio Media Manager application converts videos to the right format didn’t help as a long term solution. It did however give me a valid file to look at – and using that I managed to figure out how to successfully convert videos.

The solution appears to be to use a .mp4 container, not a .avi container. My initial conversion attempts all used mencoder, but I had to switch to ffmpeg to get it into an mp4 container. To make that work on Ubuntu, I wound up having to recompile ffmpeg since the required codecs are not supported by default. If you need to do the same thing, these are what I used.

The actual command I’m using looks like this:

ffmpeg -i input_file.mpg -f mp4 -vcodec mpeg4 -maxrate 800k -b 700k -qmin 3 -qmax 5 -bufsize 4096 -g 300 -acodec aac -ab 64 -s 320:240 -aspect 4:3 output_file.mp4

There appear to be a couple ‘correct’ resolutions – 320×240 is full screen, 4:3 aspect ratio, 240×180 is the ‘recommended’ 4:3 resolution, and 320×180 is the right one for a 16:9 aspect ratio.

I suspect there are a bunch of tweaks that can be applied to this yet, for instance, I suspect I can reduce the base video bitrate can be reduced a little, but for now I’ve figured out how to convert movies that will play.

WordPress 2.2

A new release of WordPress happened last week, and I’ve installed it on the site. As a result the normal theme has been removed until I can make sure it works properly, not that that should be a big deal considering that I’ve been really, really bad with updates.

I should be posting some new pictuers soon – we had a goose decided that the ‘green’ roof at our building was a great place to build a nest. As a result, I was able to get some interesting shots as a brave man took on the goose to move her goslings to safety. (Man, goose and goslings all survived intact)

EDIT: The theme appears to work just fine

…and the resolution bites the dust

Not even two weeks into the new year, and already I’ve managed not to keep my New Year’s resolution….

I’m ok on the photo side, need to get a few more pictures up today, but meeting the once a week thing for now. The written side is obviously where I’ve fallen behind since this is my first entry this year. I’m not giving up on the resolution just yet, and we’ll see how it goes.

Just switched off a two week night rotation, and am going to be an odd stretch for the next one, with a four day stretch of day, day, night, night. It’s what Jenn normally works, so it isn’t a bad block, just different than normal for me.

With personnel changes at work, I’ve taken over scheduling for the tech desk, and since the schedule was done on Excel in the past, and I’m never on a Windows machine anymore, I’ve been working on programming a simple scheduling application in PHP. It’s taken some time, but I’m starting to get functionality working to let me set up schedules pretty easily. One of the features I really wanted was to be able to export the schedules so that they are useable in other caledar programs. That part has worked out pretty well. I don’t know whether something like that is useful to the world at large (simple way of laying out a 24-7 support desk schedule), and I didn’t find anything like it when I went looking. I may decide to make it available to others once I’ve cleaned it up a bit and made the user interface a little cleaner – right now it is definitely a ‘made for me’ type of application, with very little error checking.

LightZone

I just started using a new program the other day. It’s called LightZone, and I have a feeling I’m going to be using it a lot. It is an interesting photo editor that is geared towards taking digital photos and prepping them for output. It is definitely geared towards photographers including the Ansel Adams zone system.

It allows you to retouch photos in an intuitive way without worrying about numbers. The reason I started playing with it was that I wanted to find a good way to process my raw (.crw) files in Linux, but I’ll be using it for much more than that. It’s also getting good responses elsewhere.

As an added bonus, for those of us using Linux, we can get a free copy. Definitely check it out!

New (to me) Camera

I’ve been bad… no updates to the site in months. What is especially bad about that is that I have a new camera, which should mean that I’ve got lots of new stuff to post. I picked up a used Canon 10D camera, and am having a blast with it. I spent a lot of time turning an expensive camera into one that uses a pinhole lens… I’ll post details of that in a different post.

I’m still trying to be successful at the ‘one picture a day’ thing, I’ll see how I manage from here but don’t count on exactly one a day. I’m thinking of making it a New Year’s resolution :-)

If you want to watch for pictures, this isn’t going to be the right spot anymore. Instead, you’ll want to go to photos.dragonsbyte.ca. I’ve installed PixelPost there, which is geared for photobloging, and nothing else. I did that because one of the things I was always fighting with was WordPress, and how to get it to show pictures in a simple, clean format. Separating words, and pictures might get me what I am after.

I’ll still be posting here, but it won’t be photos per se. There may be some as part of the posts, but the ‘this is a picture for it’s own sake’ stuff will be handled on the photoblog.

I’ve also finally gotten rid of the re-direct on the www.dragonsbyte.ca page, and replaced it with a very simple page that lets you choose the photoblog, or written one. I’m toying with the idea of setting up an RSS feed on that page that combines the data from the written and photo site. Not sure if it’s worthwhile though, since I have no idea if anyone reading the blog actually uses RSS.