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.

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.

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.