Archive for the ‘hobby’ Category

Programming in Akelos

For some while I have been using the Akelos library for MVC development within PHP. The reason I like this library over other well-known libraries like Zend Framework, CakePHP etc, is that this library is very much coded with “Convension over configuration” which means that you don’t have to over-configure everything. And it’s easy to learn new people how to use it. (more…)

Simple Perl based Icecast clone

This is acctually a mini project I did a while ago, but I thought I could write a small post about it here, and give out the source code.

The reason I did this, was because I used icecast, and had 5 streams up with a lot of users, but sometimes you would get sound from other streams on the same server, or old sound in the middle of the stream. I tried googling after other people with the same problems as me. But found nothing. So I thought; it’s quite simple software, how hard can it be to make a stable myself?

So first I made a proof-of-concept perl script to receive data, and send out to several listeners. Worked great at first try. Only a minior problems. If I paused the stream on one client, the whole server started waiting for that one listener, before sending any more data to all the other listeners. (more about this later) The other problem was that I didn’t have any in-stream “title” support.

The reason the stream stopped when one of the clients stopped listening for data (and blocked further data), is that I was sending data with a blocking socket. Now I tried googling about how to _send_ nonblocking, but coulnd’t find anything. So I made my own little workaround. (someone please give me a better solution)

Instead of:

$sock->syswrite($data)

I wrote a new send subroutine using IO::Select to check if the client is ready for data:

sub send {
	my $self = shift;
	my $sock = $self->{'sock'};
	my $data = shift;
 
	my $select = IO::Select->new;
	$select->add($sock);
	if ($select->can_write(0)) {
		return $sock->syswrite($data);
	} else {
		return 0;
	}
}

This finally did the work for me. The “send()” subroutine now returns how many bytes it sent to the client, and if it couldn’t send any, then it returns zero of course.

Then over to the problem of sending title updates inside the stream. I googled this and found a nice informative page about Shoutcast MetaData.  To bring it into a short explanation; if the client supports shoutcast metadata, it sends the following request header “Icy-MetaData:1” to inform the server that it knows about metadata. Then the server, my script, sends “icy-metaint: 123″ back in the response header, where “123″ is the amount of mp3 bytes before a metadata string should arrive. After exactly 123 (or whatever the server decides) bytes, the server sends a byte containing information about how long the metadata block is, and then the metadata right after. The “length byte” must be multiplied by 16 to get the real length of the metadata string. So the largest metadata string possible would be 4096 bytes long. Just after the metadata, the mp3 data continues as usual. Usually you won’t send the title data each time the metaint-counter goes around. You’re probably good by sending zero length metadata (just sending a ‘\0′ byte as metadata-length) all the time, until the title actually changes.

So at this time I rewrote the script, and mode it more module based, and added support for several streams, and yaml configuration file for access control, and some status pages, using TemplateToolkit.

So anyways, the script is still in early beta stage, but it should work fluently. It did however seem that the title-data got out of sync after about a day of listening to a stream, until you reconnected. Can’t seem to understand how it would get out of sync, unless a malformed tcp packet would arrive. So either I was testing it with a really crappy internet connection that time, or there is a bug berried deep in the simple code. You are free to have fun with the script, and tell me whats wrong. I also think it’s still full of debug printing. But I have already warned you, this is still in the proof of concept “whack-some-shit-together” stage. I’ts just one of those projects that ends up collecting dust.

If you fire the script up, and go to http://127.0.0.1:8001/ it should give you a list of the current connected streams. Also http://127.0.0.1:8001/xml should give you xml output of current streams. I’ve been using oddcast to send icecast stream to it.

Here’s the full script: perlcast.tar

Big timecode display

So, in the last blog entry I told you about the perl DMX backend that we are doing for the party project of ours.

We have concluded that we will have a bitchin’ intro show. And it will be timecode controlled. Every little audio / DMX / Video effect will be timed to the millisecond.

To do this, we have (for now) concluded that we will use Ardour as the audio platform, and use jackd as the timecode server.

The nice part about this, is that it’s very easy to code a jack client that fetches the timecode in realtime, and then transmit it via UDP to our external timecode display. And thats where this blog post comes in place; we are creating a cool 8 digit 7-segment display to display our timecode.


William got 8 of these modules from Kay, who agian bought them for almost nothing at eBay. :D (in Norway they cost about $25 each at the time of writing)

Anyways. As you see in the picture, william has glued the 8 digits together, wich we will put inside a box, and wire up with some pic18f4520 and some ENC28J60 for ethernet connectivity. Yes, the module will be stand-alone, only connected to ethernet, and display the current timestamp/timecode in Ardour/our DMX system.

Do we _really_ need it? no. Is it really cool? yes.

So, so far we have finally gotten the box for the device. It’s acctually a image frame, with an exceptionally deep frame on the backside to contain the whole shebang.

Here are some more “under construction” photos:


In the first photo you can (almost) see the PIC18F4520 on a vero board, with a connected prototype board with the ENC28J60 chip, which works perfectly and successfully outputs data to the (soon to be connected) displays when it receives timecode UDP data on port 1337 ;P

This project has not been the easiest, even though the concept is simple. I’m not the greatest engineer in regards to analog electronics. The problem is that the 7segment displays needs 7.2v, and uses common anode. This means that I cannot use the displays directly from the PIC processor. So i went on using a ULN2803A to drive the display. This solves the “common anode” problem. Now on to solving the 7.2v problem. I have as I said, not very much to say in the analog electronics world. So I went on, and found the first PNP transistor I could find. Kay was kind enough to donate them to us.

He had a bunch of 2N3906 transistors, wich seemed to be “workable”. So i set them up on a breadboard and after some fidling with resistors and pulling up the signal, to let the PIC pull it down, to enable the flow trough collector and emitter. This seemed to work great, so I soldered the whole shebang together.

Everything works great now, except that the display “fluctuates”. Seems like either the 5v regulator is too weak (it gets pretty hot, but I can’t check it, because my multimeter doesn’t want to measure current), or the transistors are a bit too sensitive. Sometimes, when there is traffic on the network the display fluctuates when the ethernet-leds light up. So something is not at it’s fully potential yet. But I’ll measure a bit when I get a working multimeter.

So here are the latest images(only thing missing is the 4 dots at the bottom):

DMX system in perl

William and me are starting to prepare for the next Exploit party, and this year we have decided to control all the lightning and video equiptment by perl.

We started for two days ago. William has a ENTTEC USB Pro which is fine for interfacing. In Linux, it is recognized as a standard COM port, and the API consists of sending characters to the virtual COM port.

So as an example of how easy it is to send DMX with this device from perl, I’ll give an example below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/perl
use Device::SerialPort;
use Time::HiRes qw/usleep/;
use strict;
 
my $PORT = '/dev/ttyUSB0';
 
my $ob = Device::SerialPort->new($PORT) or die "Can't Open $PORT: $!";
 
my $packet = chr(0) . (chr(128) x 30);
my $length = length $packet;
 
my $write = $ob->write("\x7E\x06" . chr($length & 0xFF) . chr(($length >> 8) & 0xFF) . $packet . "\xE7");
print "Wrote $write bytes to DMX controller\n";

This little script will send 30 channels of value 128 to the DMX controller, which will keep repeating this information, until it gets new information.

To clarify, the first byte 0×7E is the start byte for the enttec api. The next byte 0×06 is the function we are using, which is DMX OUT. Then there is two bytes of length information, describing how many channels we are going to send. And then the package is sent. It’s important to remember to send a 0×00 byte as the first channel, since this is the start byte of the actual DMX data. (also called the SC in the DMX standard specification)

We needed a central area to save our current channel data, and william found a nice perl module called Cache::FastMmap which uses mmap to save data. This way we can have several scripts using the same memory buffer, where we will putt the current DMX channel data. The first byte in the shared memory holds the current ‘version number’ of the data. Each time any data is changed, the first byte’s value is increased. This way each “reader” can check if there are new data asyncronically.

So after some initial successful testing, I created a module called Exploit::Scene. This is the module that all scripts that need direct DMX control will use. The external methods are pretty simple. You have get(), set(), to get and set a single channel value, isNew() and resetNew() to check if the DMX channel data has changed since last time you checked. commit() to save new channel data you have edited, and getDMXpacket() to get full 513 bytes of channel data. (or less, if you have set a smaller universe_size)

Now we could start to create some small test scripts. So William made a script that tests a single RGB LED fixture. And I created a console application to show/edit the DMX data. Of course these scripts are just for testing, and will not be used in the finished ‘product’, since everything will be centralized in a web interface to combine effects, etc.

Here you can se the console application i wrote with the Curses perl module. The green cursor on the left is moved with your up and down keys, to select a channel. If you use the left or right keys, you increase or decrease the channel value. If you press space, you toggle the channel to full 0xff or null 0×00 values. Page Up and Page Down will show you next ‘page’ of channels, up to 512. The color on the bars is reflecting the channel value, first 1/3 is red, next is yellow, and last is green. The console is live, so if any other processes is changing DMX data, it will immediately show the new data while you are editing. So it’s both a monitor and editor. Which will be nice to have when the full system is done. So we can monitor the dmx channels live without the actual fixtures.

We have created two backend scripts. backend-dmx and backend-udp. These connect to the mmap with the Exploit::Scene module as explained, and use the getDMXpacket() function to get the data to send to either the DMX controller, or udp. By UDP I mean that we are sending all the DMX data to a local multicast address. 239.255.0.$universe. This way, any computer on the network can connect to this stream, and get out the data it needs. So we can have several computers on the network triggering on DMX data. For this we have the Exploit::UDPScene module, which behaves similar to the MMAP version, but used multicast to get it’s data.

More info will come when we are further along with the project.

13 Input USB Temperature Sensor for PC

I love doing statistics of everything, because data is power. So we thought we would put a temperature sensor in every server-rack in this server housing facility, and I checked the prices of some standard components. First I thought of the DS1820, which is fine, but two drawbacks. It’s somewhat expensive, and takes a full second to read value from. So if you wire a lot of sensors serially, you’ll need to wait one second for each sensor on the same line.

Then I found these cute analog temperature sensors, called MCP9700A. And they cost only €0.37 each. Or if you buy larger quantites, you’ll get even lower prices. So I thought.. the PIC18F4520 has 13 analog ports. Why not create a small pcb with a pic18f4520, and some connectors, and wire it to the computer via RS232.

The problem then, is that i’d have to buy max232 chip, and then I’d need a RS232->USB cable, and thats pretty expensive. But then I found the life-saver chip FT232R. This awesomeness in a chip enclosure is a RS232(or any serial data in TTL levels)-to-USB ‘converter’. It has drivers for windows *, Mac, Linux. And you can even modify the eeprom inside it, to make it use a different VID and PID or just change the device description of it. And it also have two GP pins, which you can connect to LEDs to show when it sends or receives data. The BEST part about this already awesome chip, is it’s price. Here in Norway a RS232->USB cable costs from €42 an up. But this device, practically the same (except for missing RS232 level converter), costs only €2.87. And thats with all the leetnes of being able to change the device description and all, included.

So I wired it all up in Eagle, and it came out to be like this.
Schematics:

Board:


So here I have a PIC18F4520 processor, 20Mhz XTAL for it (because I had some laying around), FT232R chip, 100K Resistor pack, and a few LEDs. All in all, about €20 worth of components.

So, now that I had designed the board, how to get it made, and cheap? Well, I found this site called [link]www.batchpcb.com[/link]. Which is fabulous. They collect PCB boards for a bunch of people who need cheap prototype boards, and send everything together to China, where they produce the boards, and return them in about 12 days. They often set up your board several times, in case some of them should be bad. (bleedout on the copper). And the best part. If more than one of your boards are ok, they even send you the extras, with no extra charge. So I received two pcs of the PCB I ordered, and couldn’t be happier :)

Here’s the result, (image quality courtesy of iPhone 3G)


Then we add all the components. And bobs your uncle: (image quality courtesy of iPhone 3G)


And it even works! ;)

The software I have uploaded to the PIC18F4520 sends all the temperature info, and the 8 general purpose inputs to the computer via a virtual com port on the computer, 20 times a second.

SIM300CZ library for Eagle

I am playing around with this nifty GPRS module called SIM300, which is just plain awesome. :cool:

I am still using the test board that you can buy from the manufacturer, but are soon getting ready to use my own PCB board. But to do that, I need to draw the PCB board first. And I like to use Eagle, since the trial version has everything I need.

Only thing left is to have symbols for schematics and package for PCB. This is what I have been working on today.

So this is the resulting symbol:


And this is the package:


Now, I made the package, using the measurements in the SIM300C documentation, but I haven’t tried it yet. So I really don’t know if I have been dead on, on all the measurements in the package. But time will show, as I will try to print it out and compare, and eventually etch a pcb with it :)

If anyone wants to try the library, its here:
SIM300.lbr

The library contains both SIM300Z and SIM300CZ. The SIM300Z package (molex package) was created by Vamsi Kodati, but the symbol and the SIM300CZ and the pin-connecting is all me :happy:

Kerneldriver for LCD display (Tyan M1000 display for GT14 barebone)

So we bought this 1U Tyan GT14 Barebone with a LCD display and buttons in front of it. It was chosen mainly because of it’s anonymity and the LCD display.

So I set to download LCD drivers for linux. First I couldn’t find them at all.. The page at tyan.com is extremely slow, and even with google cache, it was not possible to find the driver. After a while, I tried connecting to their FTP server, where I were more lucky. Here I found a C example of how to write text to the display. Only problem was, it was linked to a binary library which was compiled with a different libc version. Shit out of luck I thought, no. I searched the FTP a bit more, and suddenly I found a lcdproc module by the Tyan staff. And it included all the source!

Yippee! But I don’t like the way LCDproc prevents me from doing what I want. I want to be able to control it directly, but from several sources. So I went to create a kernel module for Linux. Partly also because I wanted to play a bit with kernel development again :P

So attached you can find the source code for the new M1000 tyanlcd driver for 2.6 kernels.
tyanlcd-0.1.tar.gz

It actually took me a while longer to do. Not because of very big problems. But because as I started to google about on how to access the serial port from kernel-space, I quickly found out that it is not very easy. There is a lot of serial drivers, and even though this device will only be on tyan mainboards, so it sould be safe, I wanted to be sure it worked on any serial port that linux has support for. I tried looking at serio, but found ot that this was the wrong way to go. And then read Alan Cox mentioning somwhere that the best approach to use the serial port would be to create a new line discipline. But I could not find a good description of this, or even how to use it when done.

So I ended up using the not so loved filp_open() to open /dev/ttyS1 where the LCD device always resides in a tyan barebone. This way I had acces to the device using file->f_op->write() and someone used file->f_op->ioctl, but I found out that this was not exported in the file object I received. So I went on investigating the insides of the kernel myself, and finally found a way to reach it’s ioctl function. The tty object resides inside file->private_data, and inside the tty object you have a driver struct, with a ops struct which have the ioctl function. So by doing:

1
2
  tty=(struct tty_struct*)f->private_data;
  tty->driver->ops->ioctl(tty, f, TCSETS, (unsigned long)&settings);

I was finally able to set the correct baud rate, number of bits, stop bits, etc. As soon as this was done, it was piece of cake writing text to the LCD display using the original lcdproc driver code as a template for the instructions to the device.

After this proof of concept worked, I added the posibility to both read and write to the display using the /proc filesystem. The driver creates a file called /proc/tyanlcd where you can send text which wil be sent directly to the display. The first 16 characters is the first line, and the next 16 characters is the last line. (the display is 16×2 characters).

Reading the proc file gives you both lines on a single line. Seperate them by 16 characters and you have the current two lines displayed on the display.

Next task will be to make support for the buttons.

Small videoclip of the date showing in the display: mov02074.avi
Which shows the realtime output of the following proof of concept bash script:

1
2
3
4
while true; do
  echo -n "    $(date +%H:%M:%S)      " > /proc/tyanlcd
  sleep 1
done

LEDDisplay games

So.. We can’t have a “screen” without pong or snake, can we?
When I completed the LED Displays abillity to be controlled from the computer via RS232, I wrote a nifty little module in Perl, which I called: Acme::LEDDisplay.

With this module I am able to use the display just as a.. well… display :)
But ’till today, I haven’t made anything really cool. Just some small things like live Network-graph and live IRC log ;p

But today I wrote two games for it, and I’m pretty pleased about the result :)

The new scripts for today are Snake/Nibbles, Pong, and a little meaningless bouncy-script.

Nibbles

Source:
nibbles.pl
Video:
MOV00332.avi

Pong

Source:
pong.pl
Video:
MOV00334.avi

Meaningless script
Also made this little ball-bouncing script, which pong is built upon. It uses pretty much the same “ball” module. You can start it with as many balls you want. And it bounces them randomly about.

Source:
bballs.pl
Video:
MOV00331.avi

LEDDisplay / BlinkenLed

My newest project; LED Display.

Youtube video of it

The idea came from germany, where the group “CCC” or Chaos Computer Club, created a matrix of lights in the “Haus des Lehrers” building at Alexanderplatz in Berlin. They installed computer controlled lights in 144 windows spanned over 8 floors (18 windows per floor). This was done first in 2001. You can look at their webpage at BlinkenLights.de.

If you search for Blinkenlights on video.google.com or youtube you will find a really interesting documentary about the Blinkenlights project. I saw this video a few years ago, but when I saw it again now recently, I ignited on all my sparks. I had to make my own small scale version.

So I surfed the web, and I found, amongst others, BlinkenLEDs. These guys had done almost exactly what I wanted to do. I saw that they were using a 4094 Bit-shift register. I myself would have used a 74xxx series chip, but since they had done it perfectly with this chip, and since it looked like it worked perfectly even without resistors for each LED, I incorporated the 4094 chip in my plans.

My plan differs from theirs in two ways. I wanted mine to be able to run without a computer connected. For this I planned using the PIC16F628. Someone might wonder why I wouldn’t use the cheaper “less cmos” version PIC16F84. But the answer is also the answer to the other way my project differs. I wanted to use the serial port, instead of the LPT(read: printer) port. And the PIC16F628 has hardware USART capability, which makes RS232 connection simple.

The part-list for mye circuit is as follows:

  1     PIC16F628
  1     18-PIN socket (for the PIC)
  1     MAX232
  1     95128 SPI controlled EEPROM (128KB memory)
  1     20MHz Crystal for the PIC
  1     33uF electrolyte capacitor (noise reduction for PIC)
  2     22pF capacitors for 20Mhz crystal
  2     Veroboards (prototyping boards)
  3M    Flat cable
  4     1uF electrolyte capacitors (for the MAX232)
  18    4094 Bit shift registers
  144   Red 3mm Leds (I've got 4000 spare :P)
  misc  Wires

The circuit was planned live inside my head ;) I have regretted this a bit as the project evolved, but all in all, I’m pretty happy/proud about the result.

Here you can see a picture of the controller-card when I had completed the wiring of 3 bit-shift registers, the PIC16F628 and the MAX232. I were planning on having two rows of bitshift registers filling the whole left side of the board, spacing just enough to have 8 wires up to the LED board from each register.

Here you see how I wired the first 4 bit-shift registers. I found out later, that I wanted the first register to be on the next row. Even though here you can see that I have connected the first register on this “second row” to the PIC16F628 processor. If you are really observant, you can tell that I have changed my mind a few times on the wiring of the bottommost row ;P
It also prooved later that I should have thought it over just one more time. Because here lies the root of all evil! I wired up all the STROBE pins to +5v, and wired together all the OUTPUT ENABLE pins, to one of the ports of the PIC processor. This was not what I meant to do. Because of this, my display will flicker a bit each time it updates the screen. But since it is a 20MHz processor, it’s hardly noticable.

This is a picture of all the 18 Bit-shift registers wired up.

This is all the registers wired up. You can see I have moved the control-cable from the processor to the leftmost registers. I tested the circuit with a program on the processor that lit one row by one, and all of them worked at the first try! :D

It was then over to the LED card. Here I have drilled out 144 holes. Pretty boring work I can tell you…. You see that I have wired the ground from the 9 first LEDs.

This is how it looks when all 144 LEDs are connected. This took very long time, especially afther the first few rows. Since my friend had to leave, and so I was two hands short. But I got it done at the end. I wish this board was pre-tinned like the controller-vero board, since this made it even harder to solder the LEDS with only my own two hands.

Then I started wiring up the leds to the shift registers. I am glad that I saw how terrible the wiring looked at the projects at BlinkenLEDS. So that I bought flat cable for my project. I’m pretty satisfied with how I wired up the leds to the flat cable. Even though it took quite a long time. After each new row, I powered up the circuit to check if there were any “dead pixels”. There were a few (read: totally 4-5), mostly since the board wasn’t pre-tinned, and I don’t have flux other than what the tin provided. But since I was in lack of hands, the flux evaporated before I got to actually solder the leds to the board.

Here you see the board running a program that alternates between all the leds. The display works! It was time for celebration with a “blm” movie from the BlinkenLights project. So I wrote a parser in perl that converted a .blm file to .c code for my PIC16F628.

#!/usr/bin/perl
use strict;
 
my $ttl=100;
my @arr;
my @outarr;
my $out;
 
while(<>) {
  if (m/^@(\d+)$/) {
    $ttl = $1;
  }
  if (m/^[01]{18}$/) {
    push @arr, $_;
  }
  if (scalar(@arr) == 8) {
    print " PORTB &= ~SHOW; // Hide display\n";
    for my $pos (0..17) {
      for my $ari (0..7) {
        push @outarr, substr($arr[$ari],$pos,1);
      }
      print " sendbyte(0b".join("",@outarr).");\n";
      @outarr = ();
    }
    @arr = ();
    print " PORTB |= SHOW; // Show display\n";
    print " delay_ms($ttl);\n\n";
  }
}

The result was a moving version of this:

Source of the BLM file, and moving GIF of the animation can be found here.

I have now coded the RS232 support and I first modified the above code to send the animation directly to the display. And then I coded myself a perl module to control the display live. I called it “Acme::LEDDisplay” and using some quick hacks. I have support for pset (pixel set), pget (pixel get), line, circle and text.

With this I can create live output from just about everything. The sky is the limit :D

Here is a video sample of “spin.blm” on my display: MOV00315.avi

The project is almost done. I have made it possible to send blm movies directly from the PC, and control the display in simple perlcode. But the “offline-playing” part is not done. I had a few problems getting the SPI<->EEPROM communication to work, so I have ordered some more EEPROMs to check if the one I have is broken. I really hope that, because it would be fun to be able to upload a few “movies”, and let it run for itself on batterypower. Maybe show off a few christmas greetings for example ;)

I also might wire it to my recently bougt Bluetooth module, so I can control it without any wires whatsoever :)

If you want more info about how I wired things up, sourcecode, etc. Give me a reply!

My blog

Well.. Two things have been decided today;

  • To start a new blog
  • To keep it english (read: engrish)


So here it is. I will try to post my hobbyprojects here and stuff, maybe someone might appreciate it. :coffee: