Archive for the ‘code’ Category.

An open source LED grid clock

So your analog wall clock breaks… What do you do about it? Make a digital clock, of course. Lumitock is an “LED grid” clock, where the time is represented by the number of lit LEDs within a segment of the clock.

Lumitock is based on the Arduino platform, specifically using an Arduino Pro Mini 328 (socketed, I have commitment issues). It also uses a DS1337C RTC for time-keeping, and TLC5940 LED drivers to keep track of all that light. I used BatchPCB to fab some boards for it, and they turned out great. Very solid, and such an easy service when time isn’t much of a factor.

It is open hardware and software, available on github. The Arduino project as well as Eagle CAD project files are included.

Beware! The current version (tag version-1) has a fairly nasty issue with the PCB layout, the TLC5940 sockets were drawn as .4″ wide, not .3″. Not fun to solder that up, you can see the kludgey fixes in the images. I will be updating the PCB as well as making a SMT-only version to slim things up.

The video cannot be shown at the moment. Please try again later.

Images

Migrating multi-project Subversion repositories to Git

So I finally gave in and submitted to the version control Gods, Git is the way to go.  Of course it would happen that Git repositories are typically a single-project-per-repo situation, and I have a couple globbed together Subversion repositories with many projects in them.  How do I separate out my histories from the individual projects, maintain tags and branches, and not lose that precious history that nobody really ever looks at anyway?

Well, luckily there is a nifty script called svn2git that gets us the bulk work of migrating history of a single Subversion repo to a new Git repo.  Coupled with a few admin tools that come with Subversion, we got it covered.

The current situation

I have a couple repositories, looking like the following:

/var/lib/svn/repo1
  /project1
    /trunk
    /tags
    /branches
  /project2
    /trunk
    /tags
    /branches
/var/lib/svn/repo2
  /project3
    /trunk
    /tags
    /branches
  /project4
    /trunk
    /tags
    /branches

The desired situation

I’d like them all separated, with all history!!!  Resulting in the following structure:

/var/lib/git/project1.git
/var/lib/git/project2.git
/var/lib/git/project3.git
/var/lib/git/project4.git

Step 1 – Dump your projects from the Subversion repository

Subversion ships with a tool, svnadmin, that will help dump a repository.  It must operate on the local filesystem of the Subversion repository, not a working copy.  As a result, it only dumps full repositories, hence the problem in general.

Be not afraid though!  Subversion also ships with svndumpfilter, the key to our salvation.

For my example above, to dump project1, project2, project3 and project4 into separated Subversion repositories, I would:

mkdir svn-convert && cd svn-convert
svnadmin create project1.svn
svnadmin create project2.svn
svnadmin create project3.svn
svnadmin create project4.svn
svnadmin dump /var/lib/svn/repo1 | svndumpfilter include project1 | svnadmin load project1.svn
svnadmin dump /var/lib/svn/repo1 | svndumpfilter include project2 | svnadmin load project2.svn
svnadmin dump /var/lib/svn/repo2 | svndumpfilter include project3 | svnadmin load project3.svn
svnadmin dump /var/lib/svn/repo2 | svndumpfilter include project4 | svnadmin load project4.svn

And viola, separated Subversion repositories.

Step 2 – Convert via svn2git

First, download and install svn2git, it’s a Ruby script, the instructions are good, it’ll work for you.

Next, create a text file, ‘authors.txt’ with contents like the following:

name1 = Full Name <email@example.com>
name2 = Another Name <email2@example.com>

Substituting the names of users who have committed to the Subversion repositories of course. This will map the Subversion users to Git authors.

Next, we make a place for the new repository and run the conversion utility.  It will init the Git repository and create the necessary history.

mkdir project1.git && cd project1.git
svn2git file:///home/nick/svn-convert/project1.svn \
    --trunk project1/trunk --branches project1/branches \
    --tags project1/tags --authors ../authors.txt

Repeated for each repository with appropriate substitutions, and you’ve got yourself some Git repositories.

Quick verification should show you you’re in business:

$ git tag
v1.0
v1.0.1
v1.0.2
v1.0.3
$ git branch
* master
  ticket102
  ticket87

All that is left is to put them in a safe place and start cloning!

Time to broadcast, iPhone style

Ran into a need to dynamically determine the current UDP broadcast address for the WiFi interface on the ole’ iPhone. Since NSHost appears to be a private API even w/the 3.0 software, it seems one must go lower. I wrapped it up in a neat little bundle that seems fairly usable if not verbose and full of magic (but understandable) numbers.

A few things of note. en0 is the WiFi interface. There are others. Instrument the following code w/some debug to get them all out. The ip/netmask methods return nil when the WiFi interface is not active. I would also be shocked if there were no corner cases I am ignoring…

#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <errno.h>
#include <ifaddrs.h>
#include <stdio.h>
 
static NSString *kWifiInterface = @"en0";
 
@implementation NetUtil
 
+ (NSString *)broadcastAddressForAddress:(NSString *)ipAddress withMask:(NSString *)netmask {
    NSAssert(nil != ipAddress, @"IP address cannot be nil");
    NSAssert(nil != netmask, @"Netmask cannot be nil");
    NSArray *ipChunks = [ipAddress componentsSeparatedByString:@"."];
    NSAssert([ipChunks count] == 4, @"IP does not have 4 octets!");
    NSArray *nmChunks = [netmask componentsSeparatedByString:@"."];
    NSAssert([nmChunks count] == 4, @"Netmask does not have 4 octets!");
 
    NSUInteger ipRaw = 0;
    NSUInteger nmRaw = 0;
    NSUInteger shift = 24;
    for (NSUInteger i = 0; i < 4; ++i, shift -= 8) {
        ipRaw |= [[ipChunks objectAtIndex:i] intValue] << shift;
        nmRaw |= [[nmChunks objectAtIndex:i] intValue] << shift;
    }
 
    NSUInteger bcRaw = ~nmRaw | ipRaw;
    return [NSString stringWithFormat:@"%d.%d.%d.%d", (bcRaw & 0xFF000000) >> 24,
            (bcRaw & 0x00FF0000) >> 16, (bcRaw & 0x0000FF00) >> 8, bcRaw & 0x000000FF];
}
 
+ (NSString *)ipAddressForInterface:(NSString *)ifName {
    NSAssert(nil != ifName, @"Interface name cannot be nil");
 
    struct ifaddrs *addrs = NULL;
    if (getifaddrs(&addrs)) {
        NSLog(@"Failed to enumerate interfaces: %@", [NSString stringWithCString:strerror(errno)]);
        return nil;
    }
 
    /* walk the linked-list of interfaces until we find the desired one */
    NSString *addr = nil;
    struct ifaddrs *curAddr = addrs;
    while (curAddr != NULL) {
        if (AF_INET == curAddr->ifa_addr->sa_family) {
            NSString *curName = [NSString stringWithCString:curAddr->ifa_name];
            if ([ifName isEqualToString:curName]) {
                char* cstring = inet_ntoa(((struct sockaddr_in *)curAddr->ifa_addr)->sin_addr);
                addr = [NSString stringWithCString:cstring];
                break;
            }
        }
        curAddr = curAddr->ifa_next;
    }
 
    /* clean up, return what we found */
    freeifaddrs(addrs);
    return addr;
}
 
+ (NSString *)ipAddressForWifi {
    return [NetUtil ipAddressForInterface:kWifiInterface];
}
 
+ (NSString *)netmaskForInterface:(NSString *)ifName {
    NSAssert(nil != ifName, @"Interface name cannot be nil");
 
    struct ifreq ifr;
    strncpy(ifr.ifr_name, [ifName UTF8String], IFNAMSIZ-1);
    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == fd) {
        NSLog(@"Failed to open socket to get netmask");
        return nil;
    }
 
    if (-1 == ioctl(fd, SIOCGIFNETMASK, &ifr)) {
        NSLog(@"Failed to read netmask: %@", [NSString stringWithCString:strerror(errno)]);
        close(fd);
        return nil;
    }
 
    close(fd);
    char *cstring = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
    return [NSString stringWithCString:cstring];
}
 
+ (NSString *)netmaskForWifi {
    return [NetUtil netmaskForInterface:kWifiInterface];
}
 
@end

NSURLConnection + startImmediately:NO == boom?

Having issues creating NSURLConnections using initWithRequest:delegate:startImmediately?

NSURLConnection *c = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:url]
                                                     delegate:self
                                             startImmediately:NO];

Apparently when not using the simpler initWithRequest:delegate:, or even startImmediately:YES, the connection does not get scheduled in the current run loop. And again apparently, this causes unhappiness to occur when you eventually get around to calling start.

Simple fix, just stuff it in the current run loop before calling start and everyone gets along just fine.

[c scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[c start];

If there is something I am doing wrong or something I can do to prevent this, I’d like to know. Alas, the API is fairly brief on NSURLConnection, I don’t think I’m missing anything. This seems consistent with Cocoa, Cocoa Touch.

Python SubWCRev

Fired out a little Python script for exercise…

pysubwcrev is a Python version of TortoiseSVN’s SubWCRev app. SubWCRev is a windows-only console app, pysubwcrev is a command-line argument compatible replacement that is Python-based, and therefore runs on any platform with an available Python interpreter and pysvn. Currently only Linux is tested.

The code is hosted @ github. Currently no packaged release exists but it is (should be?) feature complete.

Note: This is just a hack at playing w/Python, jabs and criticism w/the style can come in the form of patches.

Conditional Jumping in PIC16 Assembly

PIC Microcontrollers have a funky way of handling conditionals. I’d like to present a set of macros I’ve made to make this easier to use, as well as explain the basics behind the technique in general.

Most MCU’s I’ve worked with before PICs had nice simple conditional statements… The mnemonic was usually to the effect of “branch if x to destination”. Not so on the PICs.

On a PIC, we have to do an operation between the data to test, then either skip the next instruction or not, based on the results of this test.

Take the instruction “BTFSS” meaning “Bit-test F, Skip if Set”. This instruction takes a register and a bit number, and will jump over the next instruction if that bit number in the register is set. For example:

We have 2 registers, REG1 and REG2. We want to know if the value in REG1 equals the value in REG2. A quick, simple way to do this is first to load one into W, then subtract the other from it, with the result going in to W as not to destroy one of the variables. This sets the “ZERO” bit in the STATUS register to either 1 if the operation resulted in a 0, or 0 otherwise. We know if the operation resulted in 0 the two values are equal, so we can code like so:

TESTIFZERO
  movf REG1, w
  subwf REG2, w
  btfss STATUS, Z
    goto NOTEQUAL
EQUAL
  ; they were equal
  goto DONETESTING
NOTEQUAL
  ; they weren't equal

So we can test for equality.

We can also macro-ize it for ease of use…

BEQ macro REG1, REG2, DEST	; branch if REG1 == REG2
  movf REG2, W			; W &lt;- REG2
  subwf REG1, W			; W &lt;- REG1 - REG2
  btfsc STATUS, Z		; if result was nonzero: skip out
    goto DEST			; otherwise jump
  endm

This gives us a macro we can call with 2 registers and a destination, and have it jump there if the condition ends up being true, and just pass on through if it’s not true. Much, much easier to use.

The other tests: inequality, less than, greater than, less than or equal to, greater than or equal to and so on follow a similar pattern. They are all covered in the “conditionals.inc” file I use quite often. I have both register-register comparisons and register-literal comparisons in there. Feel free to grab a copy and use it in your next project.

Downloads

PIC buttons (interrupt-based)

Schematic

Schematic

Previously, in PIC buttons (polling) we saw how to poll for the state of a line connect to a button, that is all fine and good but really that is not the best way to do them. The “real” way to interface with external components like that is through interrupts, a slick feature.

Interrupts provide you with lots of freedom in your code. They allow you to sit back, relax, and be told when an event occurs, and not be forced to sit and wait for it to happen.

For this program, the schematic and circuit are practically the same, the only thing that changed location is the button.

Instead of looping over and over again, we simply wait, using a goto $ we are essentially goto’ing the same address over and over, “goto here, goto here, goto here…” ad nauseum. A common technique is also to use a SLEEP command, which puts the PIC in a low power mode and halts the program counter. Same effect to the user though. You of course could do ‘real’ work too instead of just burn cycles.

Once the button is pressed and released, the PIC will generate an interrupt, forcing the program to goto memory location 4. This is labeled in the code as ISR (Interrupt Service Routine).

For this program we are using the RB0/INT Interrupt. This interrupt occurs when there is a low-high change in PORTB,0. It can also be configured for high-low as well.

To enable this, we set INTCON,INTE. This bit says we want to know if a change occurs. To enable interrupts in general, we must then set INTCON,GIE. This lets all enabled interrupts occur.

We then wait for the interrupt. Once it occurs, GIE is automatically cleared so we can’t have them inside each other, and blink the LED a couple times. We then clear the interrupt flag, saying we’ve handled the interrupt (INTCON,INTF). We then re-enable interrupts and return from the interrupt: retfie.

It should be noted that if we were using more than one interrupt type, we would have needed to check the flag bits to find out which one interrupted us. We then handle it, and clear its flag. The PIC is somewhat crippled in this manner. Any and all interrupts generated and thrown into address 4 and “we” have to figure out which one occured. Many higher end MCU’s will have a table of addresses to jump to for each particular interrupt type, we then code in each location the correct routine and the processor knows which to call based on what happens.

Downloads