June 20, 2005

converting from shoutcast to icecast

because of dissatisfaction with several aspects of shoutcast i decided to migrate kpsu's streaming servers (hi, lo) to icecast.

the hardest part was poking around until i found the sample shoutcast config file (icecast_shoutcast_compat.xml). after that i setup the server on a different port to test it, added a few extra entries:

<shoutcast-mount>/listen</shoutcast-mount>
<paths>
    <logdir>./logs</logdir>
    <webroot>./web</webroot>
    <adminroot>./admin</adminroot>
    <alias source="/" dest="/status.xsl"/>
    <alias source="/listen.pls" dest="/listen.m3u"/>
</paths>

the shoutcast-mount and the aliases provide a bit of backwards compatilbity for old links.

Posted by drewish at 12:53 PM | Comments (0) | TrackBack

April 11, 2005

yapp (yet another pov project)

Lady Ada, patron saint of all things POV and all things housed in an Altoid's tin, has a new POV project up based around the Amtel ATtiny2313. Best of all she shows how to program the controller via parallel port so you don't need to buy yet another programmer. There are free plans or she'll sell you a kit.

Posted by drewish at 07:25 PM | Comments (0) | TrackBack

March 29, 2005

the minty mouse

school started on monday but i'm not quite ready for it. i'm becoming ever more desperate to avoid homework. today, i spent four hours putting an optical mouse into an altoids tin.

before the hacking begins... the inards the completed minty mouse
Posted by drewish at 07:40 PM | Comments (0) | TrackBack

March 17, 2005

2-sided pov toy

i've spent the last few months working on a persistence of vision (pov) circuit for a bike wheel. this is my first foray into electronics and micro-controllers so, while it works, it's a bit of a hack. in fact, you might just want to skip on down to the "things to fix" section.

photo of wheel spinning saying 'fuck bush' photo of wheel spinning saying 'spaceman' finished 2-sided pov

the project is based on two of lady ada's plans for pov projects, the minipov and spoke pov. the minipov uses only a single pic16f630 while the spoke uses an amtel micro-controller, an eeprom, and several 74x259 8-bit latches.

i wanted to enhance the minpov to display text on both sides of the bike wheel. i chose to use microchip's pic because they sold a cheap programmer and i had lady ada's working source code. the biggest challenge with displaying text on both sides of the wheel each side needs to read from a different end of the string. if you're displaying ABC the left side needs to start at C and the right side needs to start at A. that meant i needed 16 outputs, four more than the 16f630 has. to work around this i used an 8-bit addressable latch for each side.

the minipov project uses a simple bitmap to determine what to output. i wanted to have separate bitmaps for each character and link them together in a string. i started by modifying the minipov to use two jump tables. the first selected the character from the string, and the second returned individual lines in the character. once that was working, i started trying to figure out how to read it backwards. i wasn't able to think of anything cleaver so i decided to throw memory at it. i duplicated the code in and reversed order.

i went through a hell of a time finding the proper LEDs for this. trying to find bright LEDs that had a wide viewing angle and didn't cost a buck each was hard. i probably ordered ten different kinds from digikey. the ones below are 1500 mcd with a 70° by 40° viewing angle and only cost about 30 cents each.

parts list

description quantity supplier part number
PCB board 1 advanced circuits custom order
PIC16F630 8-bit PIC microcontroller 1 digikey PIC16F630-I/P-ND
14-pin IC socket 1 digikey AE7214-ND
74HC259 8-bit addressable latch 2 digikey 296-8291-5-ND
high brightness LEDs 16 digikey 160-1620-ND
3 volt lithium battery with soldering tabs 1 digikey P201-ND
SPDT slide switch 1 digikey EG1901-ND

software

here's the PIC assembly code. to assemble it you'll need microchip's mplab IDE or the gnu PIC tools. you'll need something to program the PIC with. i threw down the $30 for microchip's pickit 1 flash starter kit.

hardware

the board layout was done using cadsoft's freeware version of eagle. you can download the board and schematic files by clicking on the images below.

eagle schematic eagle board layout

things to fix

this is the first board i've ever designed so i made plenty of mistakes :

  • i didn't label the board with orientation information (i've corrected this in the version posted here).
  • i forgot to put resistors inline with the LEDs. this hasn't been as big a problem as i would have thought because they're being pulsed and because cooling isn't a problem.
  • i didn't put a switch on the board forcing me to put it inline on the power cable.

in the next revision i've got several things i'm looking at changing :

  • putting a momentary contact switch on the board and having it put the pic into sleep mode.
  • adding a hall effect sensor and magnet to determine the speed of the wheel ala the spoke project.
  • moving to a higher end pic with more flash space or using an external flash rom chip.

i'll get some more photos up here when i'm making the next set of them.

update: stoked. i got linked to by hack a day. my 15 minutes of internet fame begins.

another update: people have emailed to ask me if i plan to sell these either assembled or as a kit. i do not. my feeling is that you shouldn't sell something unless you can stand behind it. this project is really just a prototype put together by someone who hadn't used a soldering iron since he was 12 years old (i actually had to go down to fry's and buy one). i'm learning it as i go. i was inspired by lady ada and the whole make crowd to stop staring at other people's cool projects on the internet and start making my own.

Posted by drewish at 12:45 PM | Comments (18) | TrackBack

January 22, 2005

migrate makethumbs.sh photo albums to flickr

after my gallery albums got corrupted i started messing around with flickr and got hooked. i'd been pretty frustrated by gallery's rigid album structure, flickr's usage of tags and sets is much more to my liking. there's also an excellent api for those times when you need to roll your own app. the fact that they handle all the backup convinced me to throw down the $45 on a pro account.

now the task it to upload all of my photos to their servers. it's a good chance to go back and import all the old stuff that never made it into gallery. i'm starting with some albums i'd make using jason molenda's makethumbs shell script. i hacked together a perl script to parse the titles and descriptions from the description.txt file, upload the images, and add them to a set. click the read more link to view the script. i hope someone else may find it of use.

update: i finally got around to encoding it as valid html. copy and paste should work better.

#!/usr/bin/perl
use strict;
use warnings;

# upload a makethumbs album to flickr
#
# by andrew morton - http://drewish.com
#
# to use this script fill in the next three variables, then change
# to the directory with the makethumbs album and run it. email if 
# you have problems.

my $flickr_email = 'your@email;
my $flickr_pass = 'secret';
my $photo_tags;

# shouldn't need to change anything below here.

# variables
my $flickr_key = '58ac590250ef4eeb81e6d853ee942034';
my @photo_ids;	# id assigned after upload
my $config_file = 'descriptions.txt';
my $album_title;	# album title
my $album_desc;		# album description
my %image_title;	# file titles
my %image_desc;		# file descriptions

$|= 1; # auto flush

use Flickr::API;
use Flickr::API::Request;
use Flickr::Upload;
use LWP::UserAgent;
use XML::Parser::Lite::Tree::XPath;

ReadMakeThumbsData();
UploadToFlickr();
AddToNewSet();
print "All done.\n";

sub ReadMakeThumbsData() {
	print "Loading makethumbs data from $config_file\n";
	open(CONFIG, $config_file) or die "Can't open $config_file : $!\n";
	
	# skip to short title section
	while (<CONFIG>) {
		last if /^\[short title\]/;
	}
	# suck up album title.
	while (<CONFIG>) {
		chomp;
		last if /^\[longer page description\]/;
		$album_title .= $_;
	}
	# suck up album description
	while (<CONFIG>) {
		chomp;
		last if /^\[captions\]/;
		$album_desc .= $_;
	}
	# suck up image titles
	while (<CONFIG>) {
		chomp;
		next unless $_; # skip empty lines
		last if /^\[descriptions\]/;
		/^(\S*)\s(.*)/;
		$image_title{$1} = $2;
	}
	# suck up image descriptions
	while (<CONFIG>) {
		chomp;
		next unless $_; # skip empty lines
		/^(\S*)\s(.*)/;
		$image_desc{$1} = $2;
	}
	close CONFIG;
}

sub DebugPrintData() {
	print("album title: $album_title\n");
	print("album desc: $album_desc\n");

	foreach my $key (keys %image_title) {
		print "$key\n\ttitle: $image_title{$key}\n";
		print "\tdesc: $image_desc{$key}\n";
	} 
}

sub UploadToFlickr() {
	my $ua = LWP::UserAgent->new;
	my $file;
	my $id;

	print "Uploading photos to flickr for $flickr_email\n";

	foreach $file (sort(keys %image_title)) {
		print "$file";
		print "\n\ttitle: $image_title{$file}" if $image_title{$file};
		print "\n\tdescription: $image_desc{$file}" if $image_desc{$file};
		print "...";

		$id = Flickr::Upload::upload(
			$ua,
			'email' => $flickr_email,
			'password' => $flickr_pass,
			'photo' => $file,
			'title' => $image_title{$file},
			'description' => $image_desc{$file},
			# Everyone can view
			'is_public' => 1,
			'is_friend' => 1,
			'is_family' => 1,
			'tags' => $photo_tags
		);

		if ($id) {
			push @photo_ids, $id;
			print " assigned id $id\n";
		} else {
			print STDERR "Failed to upload $file";
		}
	}
}

sub AddToNewSet() {
	my $api = new Flickr::API({'key' => $flickr_key});
	my $response;
	my $xpath;
	my @nodes;

	print "Creating set '$album_title' ...";
	$response = $api->execute_method(
		'flickr.photosets.create',
		{
			'email' => $flickr_email,
			'password' => $flickr_pass,
			'title' => $album_title,
			'description' => $album_desc,
			'primary_photo_id' => 3654245# $photo_ids[0]
		}
	);
	$response->{success} or
		die "Could not create the set : $response->{error_message} \n";

 	$xpath = new XML::Parser::Lite::Tree::XPath($response->{tree});
	@nodes = $xpath->select_nodes('/photoset');
	print " assigned id: $nodes[0]->{attributes}->{id}\n";

	print "Adding photos to set...";
	$response = $api->execute_method(
		'flickr.photosets.editPhotos',
		{
			'email' => $flickr_email,
			'password' => $flickr_pass,
			'photoset_id' => $nodes[0]->{attributes}->{id},
			'primary_photo_id' => $photo_ids[0],
			'photo_ids' => join(', ', @photo_ids)
		}
	);
	$response->{success} or
		die "Could not add photos to set : $response->{error_message} \n";
	print " finished.\n";
}
Posted by drewish at 04:52 PM | Comments (0) | TrackBack
Creative Commons License xml feed