Dear Congressperson, if you take my hamburger. . .

January 18th, 2012

Dear Congressperson:

If you take my hamburger, I go hungry but if you copy my software, music or movie we can both benefit from them, discuss them and share ideas and experiences which enhance our mutual ownership. This may sound like a bunch of hippy communist bull but it is capitalism in it’s truest form.

It’s as simple as the law of supply and demand. When supply goes up relative to demand, with out artificial influences, such as unnecessary laws, price goes down. We can copy digital works all day long at almost no cost so their supply is essentially limitless. According to this most basic law of economics, in an unencumbered capitalist system, the price of digital works will naturally tend towards zero.

We have been duped into believing that you can steal an idea. What a farce. What a complete and utter wrong turn for humanity. All because we made the mistake of forcing concepts we understand in the physical world, like stealing, on to the relatively new world of digital works where they do not apply. Our society has built an economy around marketing and selling products but we’re still trying to pound that square peg in to a round hole. The natural laws of physical goods simply do not apply to digital works. If we, as an intelligent society, want to maximize the value of our creations then, when it comes to digital works, we must maximize sharing. We must fight for our basic right to share in the limitless possibility of a free world of free digital works, free ideas, free music, free software, free art.

Freedom does not mean that artists are not to be compensated. They must be compensated for the act of creation. Not for sharing the fruits of their labor but for the labor itself. The business model has to change. We cannot sell music or movies like widgets. Artists must sell the act of creating as a service not the results as a product. The music and movie industry has to be turned on its head. There is no denying that it will be painful for some in the short term but it’s better than heading down the dark road of draconian enforcement which is the only end to the path we are currently on.

A free system is more beneficial to creators anyway. On the Internet, there is nothing more valuable than attention and unhindered sharing is the best way to get it. This applies to creators now not in some distant utopian future. For creators today this is the best bet not a vague hope that to win the record industry lottery. Tell these middle who are asking you to artificially prop up an outdated system, “I’m sorry, you had a good run, you made a lot of money but now you must go the way of the wagon wheel maker.”

I am 35 year old software developer. Internet freedoms are extremely important to me and many of my generation. I write and distribute software and my entire livelihood depends on what is ultimately a copyrightable digital work. Yet I believe in free and open sharing. The RIAA and MPAA need to change their tactics if they want to survive. They are wrong not the public. And their billions of dollars do not justify their position.

I will likely vote in the next elections based solely on your stance on issues of Internet privacy and freedom.

I beg you to strongly oppose SOPA and PIPA and any other legislation which attempts to limit freedom on the Internet and instead fight to reverse the damage that has already been done by laws like the DMCA!

Most earnestly your constituent,

Joseph Coffland

A “real” Ikea Dioder hack

December 29th, 2009

The other day I was walking around Ikea for some reason or another and I noticed this cool LED thing called the Dioder. It consists of 4 strips of 9 bright RGB LEDs (a.k.a. pretty color changing lights) with a control box and a bunch of cabling allowing you to arrange the LED strips in many different configurations. The Dioder has three modes. The first lets you cycle through some preset colors with the button. The second will automatically cycle through these colors. The third fades colors. The lights are not individually addressable so they are all the same color at any given time. The modes are selected by holding down a single button for different lengths of time while a buzzer beeps to let you know what mode you are in. At $50 its a little expensive but I immediately thought it looked hackable so I bought one.

It sat around the house for several days as I debated what to do with it and waited for a bit of leisure time. I knew I couldn’t just install it as intended. That wouldn’t justify the $50. So like any good hacker I did some googling to see what others had done. I did find some “hacks” but they consisted of “hey look I put these lights on my TV” or “here they are in a box, isn’t this cool.” I’m sorry, I may be a geek snob but using something pretty much the way it was intended is not a very cool hack.

So the debate went on. I cracked the control module open by removing the four screws and found a fairly simple circuit. It consists of three transistor pairs which drive the red, green and blue LED lines, a piezo buzzer, a button, a 5v regulator and a 12F629 PIC microcontroller. The circuit has only the three LED driver channels and that is why the LEDs are always the same color. I thought about building separate RGB drivers for each of the for LED strips so I could get four colors at once but in the end I decided that building new drivers circuits from scratch would take much more time than I wanted to invest in this project. Finally, I decided the simplest thing I could do, that was still “cool”, was to interface the controller with my computer to control the LEDs. Anything is cool when it’s connect to your computer right?

Unfortunately the PIC 12F629 does not have a serial port so I decided to piggy back one of my favorite little microcontrollers on top of the PIC, the ATTiny2313. This chip has plenty of IO lines, PWM, a serial port, is pretty easy to use and I happened to have some lying around and some prototyping boards already made up for them. Here is a picture of the prototyping boards I use:

Atmel 2313 prototyping board

The picture shows a populated proto board from the top on the left and an unpopulated board from the bottom on the right. You may notice that the picture shows an AT90S2313. This is the predecessor to the ATTiny2313 and is pin compatible. I did end up going with the ATTiny2313 for this project. Here is the schematic in Eagle CAD format and images so you can make your own proto boards:

AVR prototyping board PCB image

These images should be printed at 600 DPI for correct sizing. I used a laser printer press and peel type method to get the pattern on to copper clad boards and then etched them. Google it and you will find plenty of information on this.

Something like this could also work instead: AVR ATMEL PROTOTYPE BOARD.

The proto board is populated with the following:

  • 1 x 10Mhz crystal clock
  • 2 x 22pF capacitors
  • 1 x 1uF capacitor
  • 1 x 6 pin dual row .1″ pitch ISP for in circuit programming
  • 1 x 4 pin right angle header for logic level serial port connection
  • 1 x small jumper wire connecting the two extra holes from the microcontroller to the 6-pin ISP
  • 1 x ATTiny2313 Micro controller. I recommend you also socket it in a 20-pin socket.

In this project, I also added a single row right angle 8-pin .1″ pitch header to connect to the Dioder and a matching female header socket.

Here is a picture of the soldered proto board from the bottom.

Proto board from bottom

You will notice the serial send and receive wires and a ground wire connected to the 8-pin single row header. I also had to cut the trace connecting that ground pin to the microcontroller.

After soldering and testing the proto board I soldered 7 small wires on to the pins of the PIC12F629. The wires were connected to all but pin 3 of the microcontroller. The diagram below shows how the PIC’s pins are used in the Dioder:

Pin-out of PIC in Dioder

Pin 3 is not used and is just pulled to ground.

Below is a picture of the Dioder’s circuit with wires attached. In this picture there is one wire too many (pin 3).

Dioder with wires attached

Here is a close up:

Dioder with wires attached closeup

The glossy stuff is solder flux. You might also notice that I scraped off the green coating from the trace coming from the +5v input to the microcontroller. This trace was later cut and another wire was attached to the end not on the microcontroller’s side. This makes it possible to enable or disable the PIC from the AVR making all the functionality of the PIC still available.

Here is the final wiring with hot-glue to hold everything in place:

Dioder with wires attached closeup

The wires were connected as follows:

Signal PIC pin AVR pin AVR function
+5v NA 20 Vcc
PIC +5v 1 11 PD5
Buzzer 2 13 PB1
Button 4 12 PB0
Green 5 15 PB3
Blue 6 14 PB2
Red 7 16 PB4
Ground 8 10 GND

Then to allow the wires to come out of the Dioder control box I cut a small hole in the upper part of the plastic shell with a box cutter.

Here is the cut shell:

Cut Dioder shell

After trimming and connecting the wires to the 8-pin female .1″ pitch header here is the finished hardware:

Finished Dioder hack

Trust me I really did end up using an ATTiny2313. The chip pictured above ended up being bad and had to be desoldered. That’s one reason it is a good idea to use a chip socket.

Once the hardware was completed all that remained was the software. There are two parts. One the code that goes on the ATTiny2313 and two the PC side software.

The ATTiny2313 firmware is fairly simple. It listens on the serial port at 38400 baud with no parity 1 stop bit and 8-bit data. When it receives a command it recognizes it sets values for the red, green and blue PWM pulses. The firmware uses the ATTiny2313’s built in hardware PWM in 8-bit mode. The PWM is very fast an produces lighting which is much less jittery then the original Dioder.

You can check out the source from my subversion repository like this:

svn co https://cauldrondevelopment.com/svn/dioder-hack/

I built the software in Ubuntu Linux. First install the following packages:

sudo apt-get install gcc-avr avrdude build-essential

Then in the trunk directory run:

make

This will build dioder.hex and set_color as well as some other files.

You can also find the binaries here: dioder.hex, set_color

To program dioder.hex in to the AVR microcontroller I used Atmel’s AVR ISP mkII. There are many AVR programmers out there and you can even build your own but the mkII is cheap and effective. With the mkII plugged into the USB hole and the other end connected to the 6-pin ISP programming port on the proto board, oriented so that the little tab points down towards the 4 pin serial header, run the following to program the chip:

make program

This will run avrdude to program the AVR. If you use a different programmer you may need to change the Makefile. This can also be done in Windows but you are on your own there.

The 4-pin port on the proto board is a logic-level (i.e. 5v) serial port. This can be connected to a Brainstem USB to serial converter from Acroname. There are other ways to do this. For example, you could wire in your own MAX232 serial level converter and a 9-pin serial port but many computers don’t have actual serial ports these days.

Once everything is connected you can open the USB serial port in a terminal program, set the parameters to 38400 baud N81 and start playing with the pretty lights. Here are the keyboard commands:

r Toggle red
g Toggle green
b Toggle blue
o Turn everything off.
0 Disable the PIC. (default)
1 Enable the PIC (The Dioder will support all its normal functions).

This is fun for a few minutes but then you’ll want to set other colors. This is where the set_color program comes in. It is not very smart. It just opens /dev/ttyUSB0 and sends color commands. If your serial port is on another device then you will have to change the code and rebuild. set_color also does not even try to configure the serial port. You will have to make sure it is configured correctly first. If you configure the port in a terminal program, such as minicom, and then exit it should leave the serial port in the correct state.

set_color can be run as follows:

./set_color 255 100 0

The above command should make the lights a yellowish orange. The numbers are color values from 0 to 255. The order is red, green, blue.

With a little shell script you can fade the colors like this:

while true; do for i in $(seq 1 255) $(seq 254 -1 2); do ./set_color $i 4 64; done; done

This will fade the lights back and forth between light blue and light pink. You can stop it with CTRL-C.

Here is another cool one that is very hacky:

cat /dev/urandom >/dev/ttyUSB0

This one might leave the Dioder PIC enabled.

So where do we go from here? Here are some ideas I have about improving this:

  • Write a nice python program for controlling the hacked Dioder with a pretty GUI interface for selecting colors and choosing color change patterns.
  • Use the hacked Dioder to indicate events such as email arriving, twitter tweets or certain tags in news feeds.
  • Change colors based on the weather outside or somewhere else.
  • Build the four channel Dioder hack I decided I didn’t have time for.

So in the end I was quite happy with the hack. It was entertaining and now I have computer controlled color LED lighting to show off. If you found this article useful, built this hack for yourself or have other ideas for the Dioder or other Ikea LED products for that matter, I’d love to hear about it.

How to deal with ls, vi and emacs colors on a dark background

December 14th, 2009

I like to use a dark gray background with a light gray foreground for my command terminals and editors. I don’t do this just to be uber-l33t. If you’ve ever spent long hours in front of a screen you may have noticed that your eyes go blurry and you start to find it difficult to focus. This use to happen to me about 8 hours in but with the right color scheme and a good LCD monitor I no longer have this problem.

Many software systems these days are setup with a white background and black foreground. This is not so terrible since you can usually change the defaults. However, once you’ve changed them there is a further problem. Programs, such as ls, vi and emacs, have color syntax highlighting which is a very handy feature but when the colors were chosen to match a white background some colors, like dark blue, are very difficult to see on a dark background.

Fortunately solutions to these problems exist and are simple but once I get everything configured all is fine for a few weeks or months until I logon to a new system which doesn’t have my settings. I inevitability forget the magic incantations or where they are even supposed to go and have to re-google which can cost 15 minutes of digging through posts, flames and why-would-you-want-to-do-that responses to locate clear concise answers. So for myself and other nerds around the world here are the answers minus the nonsense:

vi

Add the following to the file .vimrc in your home directory:

set background=dark

ls

On Linux (RedHat, Ubuntu, et.al.) run the following command:

eval $(dircolors -b)

You can also add this to your .bashrc or whatever the startup file is for your shell.

And on Mac OS X:

export CLICOLOR=1 # Enable color ls
export LSCOLORS=gxfxcxdxbxegedabagacad # Set sane colors for dark background

You can add these to your .profile

emacs

To get the low-contrast colors I like I use the following code in my .emacs file:

(add-to-list 'default-frame-alist '(cursor-color . "red3"))
(add-to-list 'default-frame-alist '(foreground-color . "gray85"))
(add-to-list 'default-frame-alist '(background-color . "gray25"))
(set-cursor-color "red3")
(set-face-background 'region "gray85")
(set-face-foreground 'region "gray25")

There might be more to getting emacs syntax highlighting correct for dark backgrounds but this is all I seem to have in my config.

If you have any related tips or things to add to this please feel free to comment.

Resize QEMU NTFS image

February 26th, 2009

I recently needed to increase the size of an NTFS partition used in a kvm virtual machine. There are instructions in several places on the Internet but I found many of them to be incomplete. One of the best sources I found is linked below but the instructions failed to work as written. This may be due to updates in software or my particular configuration.

See the section: How to enlarge a QEMU qcow or raw image that contains an NTFS bootable partition
http://qemu-forum.ipi.fi/viewtopic.php?p=12362

Additionally, the above instructions do not use less disk space if your image is not already in raw format.

My Setup:

  • Ubuntu 8.10
  • KVM 83
  • Intel(R) Core(TM)2 Duo CPU T7500 @ 2.20GHz
  • Windows XP SP2 Corporate
  • A single NTFS partition

Step 0: Install some pacakges

$ sudo apt-get install ntfsprogs gparted hexedit

hexedit may not be needed. See below.

Step 1: Convert to raw format

$ qemu-img convert -f qcow hda.qcow -O raw hda.raw

Step 2: Check the number of heads

$ sudo losetup /dev/loop0 hda.raw
$ sudo fdisk -ul /dev/loop0
Disk /dev/loop0: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
 
Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1   *          63     8176895     4088416+   7  HPFS/NTFS
$ sudo losetup -d /dev/loop0

Remember the number of heads and start sector listed above. If heads are 255 you shouldn’t have any problems. If it is some other value like 128 or 64 you will likely have to change the number of heads in your NTFS partition later.

As was noted in the comments below, you also need to remember the starting sector and sector size for the partition offset calculation below. In this case it is 63.

Step 3: Increase the raw image’s physical size

dd if=/dev/zero of=hda.raw bs=1G count=0 seek=20

The above command will increase your raw image size to 20GB. Change the number in the seek calculation to change the target size.

Step 4: Recheck and possibly fix the number of heads
Rerun the commands in step 2. If the number of heads has changed then you will need to patch your NTFS partition. Otherwise, don’t worry about it and go to step 5.

First calculate the hexadecimal offset of the number of heads in the NTFS partition header. It will be start sector * sector size + 0×1a. In my case, 0×7e1a. Then run these commands:

$ sudo apt-get install hexedit
$ hexedit hda.raw

In hexedit hit Enter 7e1a Enter to move to the offset you calculated above. This location should hold the current value in hex of the number of heads according to the NTFS partition. If this does not match what you expect don’t edit it; you are in the wrong place. Otherwise, type over this value with the new number of heads in hex. For example FF for 255 heads. Save with Ctrl-X then y.

Step 5: Resize NTFS

$ sudo apt-get install ntfs
$ sudo losetup -o$((63 * 512)) /dev/loop0 hda.raw
$ sudo ntfsresize /dev/loop0
$ sudo losetup -d /dev/loop0

If ntfsresize refuses to work you may need to boot Windows and run:

chkdsk /f

As David points out in the comments below, if your offset or sector size are different then you will have to adjust the offset calculation. The calculation is start sector * sector size.

Step 6: Resize the partition
The above method skips over the partition table so ntfsresize can work. Thus even though NTFS has increased in size the partition table has not been updated. This will cause Windows not to boot. The following procedure will fix. However, you must recreate the partition at the same start offset. The default is 63 but if your offset is something else you will need to enter it below instead of 63:

$ sudo losetup /dev/loop0 hda.raw
$ sudo fdisk -u /dev/loop0
The number of cylinders for this disk is set to 2610.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
 
Command (m for help): d
Selected partition 1
 
Command (m for help): n
Command action
e   extended
p   primary partition (1-4)
p
Partition number (1-4): 1
First sector (63-41943039, default 63):
Using default value 63
Last sector, +sectors or +size{K,M,G} (63-41943039, default 41943039):
Using default value 41943039
 
Command (m for help): a
Partition number (1-4): 1
 
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): 7
Changed system type of partition 1 to 7 (HPFS/NTFS)
 
Command (m for help): w
The partition table has been altered!
 
Calling ioctl() to re-read partition table.
 
WARNING: Re-reading the partition table failed with error 22: Invalid argument.
The kernel still uses the old table.
The new table will be used at the next reboot.
Syncing disks.
 
$ sudo losetup -d /dev/loop0

The above steps will:

  1. Delete the old partition
  2. Create a new one of the correct size
  3. Set the partition type to NTFS
  4. Mark it bootable
  5. Write the new partition table

Note that the “Last sector” default value will be different if your disk is a different size. Don’t worry about the warning at the end.

Step 7: Boot Windows and let chkdsk run
Now just boot in to windows. chkdsk should run automatically. Check your disk size from with in windows it should be correct.

Problem: UNMOUNTABLE_BOOT_VOLUME on windows boot
Windows does not like it when NTFS and the partition table disagree on the partition size. I got this problem when following instructions elsewhere which didn’t address the change in heads. You can try the suggestions in step 6 above or follow this procedure below:

First boot from a windows install CD, go to the recovery prompt (F4) and then run:

C:\> fixboot
C:\> fixmbr

Then reboot. This should just reset your NTFS partion to its old size.

KVM/QEMU tun/tap network

February 26th, 2009

The default user mode networking supported by kvm/qemu is pretty good. However, if you want to easily be able to connect to your VM you might want to switch to tun/tap networking.

Here is a script which you can use to start and stop a tun/tap network for your kvm. You should change the TAPUSER to the user you use to run the VM. You also need to install the dnsmasq package.

#!/bin/bash
 
HOSTIF=kvmnet0
TAPUSER=nobody
HOSTIP=10.1.1.1
NETWORK=10.1.1.0
NETMASK=255.255.255.0
DHCPRANGE=10.1.1.2,10.1.1.32
DHCPPID=/var/run/dnsmasq-$HOSTIF.pid
DHCPD=/usr/sbin/dnsmasq
VERBOSE=false
 
tabbed_print() {
 X=$1
 shift
 X=$(($X + `echo $@ | wc -c`))
 
 while [ $X -lt 80 ]; do
   echo -n " "
   X=$(($X + 1))
 done
 echo $@
}
 
action() {
 LEN=$(echo -n $1 | wc -c)
 MSG="$1"
 shift
 
 if $VERBOSE; then
     echo "$@"
 fi
 
 echo -n "$MSG"
 if $VERBOSE; then
     $@
 else
     $@ >/dev/null 2>/dev/null
 fi
 if [ $? == 0 ]; then
   tabbed_print $LEN OK
 else
   tabbed_print $LEN FAILED
 fi
}
 
start() {
 action "Creating $HOSTIF"
 tunctl -u $TAPUSER -t $HOSTIF
 
 action "Configuring $HOSTIF"
 ifconfig $HOSTIF $HOSTIP up
 
 action "Adding $NETWORK route"
 route add -net $NETWORK netmask $NETMASK dev $HOSTIF
 
 action "Starting dnsmasq"
 start-stop-daemon -S -p $DHCPPID -a $DHCPD --
 -i $HOSTIF --dhcp-range=$DHCPRANGE -9 --listen-address=$HOSTIP
 --bind-interfaces --except-interface lo --pid-file=$DHCPPID
}
 
stop() {
 action "Stopping dnsmasq"
 start-stop-daemon -K -p $DHCPPID
 
 action "Deconfiguring $HOSTIF"
 ifconfig $HOSTIF down
 
 action "Removing $HOSTIF"
 tunctl -d $HOSTIF
}
 
status() {
 if [ -e $DHCPPID ]; then
   ps $(cat $DHCPPID)
 else
   echo "DHCP not running!"
 fi
 echo
 
 ifconfig $HOSTIF
 
 route | grep $HOSTIF | grep $NETWORK
}
 
while [ "$1" != "" ]; do
   case "$1" in
       start)
           start
           ;;
 
       stop)
           stop
           ;;
 
       restart)
           stop
           start
           ;;
 
       status)
           status
           ;;
 
       -v)
           VERBOSE=true
           ;;
 
       *)
           echo "Syntax: $0 <start>"
           exit 1
           ;;
   esac
 
   shift
done

You should then change your kvm network config to:

-net nic -net tap,ifname=kvmnet0,script=no,downscript=no

If you want your virtual machine to access the external network you will also need to masquerade the interface with these commands:

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o kvmnet0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i kvmnet0 -o eth0 -j ACCEPT

Assuming your external network interface is eth0.

Migrating a VMWare XP install to KVM

February 26th, 2009

KVM seems to have gotten quite good. I am a long time VMWare user and fan but I prefer Open-Source apps and KVM uses my CPU’s hardware visualization features. And besides my VMWare setup has started to crash fairly regularly for no apparent reason.

But, I don’t want to reinstall Windows. Here is my setup:

Ubuntu 8.10
KVM 83
Intel(R) Core(TM)2 Duo CPU T7500 @ 2.20GHz
XP SP2 Corporate

You will need your XP install disk.

- Download kvm-83 from:

http://sourceforge.net/project/showfiles.php?group_id=180599

- Install some packages:

sudo apt-get install  gcc gcc-3.4 gcc-4.1 libsdl1.2-dev make libz-dev uuid-dev libasound2-dev gcc libc6-dev zlib1g-dev qemu bridge-utils

- Build and install kvm

tar xzvf kvm-83.tar.gz
cd kvm-83
./configure
make
sudo make install

- Load modules

sudo modprobe kvm kvm_intel

- Convert VMWare image. This is not necessary but a good idea because it also backs up your XP image. Your images are probably located in /var/lib/vmware/Virtual Machines

qemu-img convert WinXPPro.vmdk -O qcow2 WinXPPro.qcow2

At this point you could try booting but I got an error on boot up “A problem has been detected…” I used the following steps to fix this.

- Boot with Win XP disk.

kvm -m 1024 -hda WinXPPro.qcow2 -boot d -cdrom Microsoft_Windows_XP_Professional_Corporate_SP2.iso

- Go through the menus and run the repair existing installation option.

- Now boot for real

kvm -m 1024 -hda WinXPPro.qcow2 -boot c

Notes:

  • Network just worked
  • I can change screen size through Windows driver settings.
  • Adding ‘-usbdevice tablet’ to my kvm command line let the mouse automatically switch between screens like in VMWare.
  • Haven’t figured out how to automatically adjust guess OS screen to fit like in VMWare
  • I have mouse tracking problems with VNC mode
  • Otherwise this setup is MUCH faster than my VMWare Server

Let me know if it worked for you. Good luck.