A Little Off Code, Computers, Photography and Guns

28Feb/090

Mini ITX Shuffle

DSC_2200.jpg

Recently, even with my current lack of money I've been ogling an Intel mini ITX board at newegg.com. The board has an Atom 330 embedded as well as a 100/1000 NIC.

The reason that I bring this up is that I watched an episode of Hak5 which talked about pfSense a freeBSD based firewall//router OS (a fork of M0n0wall). I've used pfSense before and found it to be awesome I've just never had the hardware to use it as a permanent solution. However now I think I have the perfect set of hardware.

For a while I've been planning to upgrade the motherboard//proc on my file server which is running FreeNAS another freeBSD based OS (also based off of M0n0wall) meant for network attached storage systems. The board that the fileserver is running on now is a JetWay VIA C7 mini ITX board which does it's duty decently well. The JetWay board has dual-gigabit NIC's which is exactly what I'd like to use for a router box. So the plan is that once I've got the money for doing all this I'll be buying the Intel Atom 330 mini ITX board and replacing the JetWay board in my fileserver with the intel board while using the JetWay board for the router.

I figure it will work well enough because for the router I'll need at least 2 NIC's (which the JetWay has) and for the fileserver I'll only really need the one NIC. Either way it's a win-win situation, my fileserver gets a little beefier while I get guts for a Router!

24Feb/090

Resistor Calculator

Recently I had need of a simple way to create a circuit of equivalent resistance to a calculated value using only parts I had available from the ECE stockroom. Lucky for me this was made easy since there is a posted parts list spreadsheet including a page of all resistor values in stock.

The simplest way I could think of for doing this was just to use two resistors in parallel and find a pair of resistor values in the parts list that is equivalent to the value i'm looking for. Two resistors in parallel have an equivalent resistance of:
R_{eq} = \frac{R_1 \times R_2}{R_1 + R_2}

A little bit of coding and I wound up at this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import math

res_val = 19872
approx_list = []
parallel = lambda r1, r2: float(r1 * r2) / float(r1 + r2)

for sig in range(0, 4):
    if len(approx_list) > 0:
        pass
    else:
        for r1 in stockroom[len(stockroom) / 2:]:
            for r2 in stockroom:
                if math.trunc(parallel(r1, r2) / (10**sig)) == math.trunc(float(res_val) / (10**sig)):
                    if (r2, r1, parallel(r1, r2)) not in approx_list:
                        approx_list.append((r1, r2, parallel(r1, r2)))

for r1, r2, req in approx_list:
    print '\t'.join([str(r1), str(r2), str(req)])

I left out the stockroom parts list because it's a bit long, there's about 130 resistor values included. Now mind you this program assumes a few things:

  • You've already checked the parts list for the resistor value you're looking for.
  • You've already checked the parts list for a resistor twice the value of the part you're looking for since in parallel they would equal resistance of the part you're looking for.

The basic logic of the program is like so:

  1. For 0 to 4 (skips digits when / 10 ** index of this for loop).
  2. If there aren't any resistor pairs in the approximation list then we haven't found a pair yet.
  3. For the first half of the stockroom list (we only need to compare once or we'll end up with swapped duplicates).
  4. Compare every item in the stockroom list to the current resistor value.
  5. If the equivalent resistance of the current pair of resistors is equal to the value you're looking for.
  6. Add it to the list.

Once we've compared all of them we go back and do the same process again but only if we found no resistor pairs matching the desired value. The next time through the list we'll ignore the last digit on both the equivalent resistance of the current resistor pair and the desired resistance value so we can at least get some sort of approximation even if it isn't optimal.

Update: I've been thinking a lot in my spare time about this and i'm sure there's a simple recursive way of developing a circuit with only resistors you have on hand provided you had a lot of the same ones. Probably just for nested parallel branches and series of them. If I have enough time to write the code for this I'll be sure to post it here.

22Feb/091

Musical Hard Drives

DSC_3314

Early Friday morning around say... 6am I decided to play musical hard drives and move the 3x 640GB drives from my file server into my desktop since my file server didn't spend enough time at home for it to be worthwhile. This was also due to not having enough stuff to actually justify keeping all the drives in the server. It grows by about 1GB of TV shows a month so 3x 250GB drives in RAID 5 is good enough for my server's storage needs. So I went through the process of backing up and syncing the content between my server and my desktop so I could safely swap the drives and restore the data. The photo above//left is when I had all 6 of the drives on my desk before I put the sleds onto the 250GB drives. My desktop now has a happy 1.2GB RAID 5 for backup and bulk storage along with a 640GB work-space drive and a 250GB OS drive.

Tagged as: , , 1 Comment
21Feb/090

Are WordPress and LaTeX Friends?

I was wondering for a while whether or not I could easily get LaTeX support on this, my personally hosted WordPress blog. I found out that it's not as simple as throwing in some $'s and latex in between. I decided it would just be easier to use an external service for generating the images and if I'm less lazy I'll cache the images on my server to be nice.

\forall{x}\forall{y}(Q(x,y) \leftrightarrow \neg{Q}(y, x)

Followup: As it turns out Louis a friend of mine found an awesome plugin for using LaTeX on his WordPress blog called Easy LaTeX. I think I'll be nice to CodeCog's latex renderer and just use this plugin which uses WordPress' main latex server.

Tagged as: , No Comments
21Feb/090

Why ‘A Little Off’?

Thursday afternoon at some arbitrary time I was discussing my frustration with getting some of the code to work on my Arduino with a friend of mine at work. This sort of lead to me showing him the blog post I had written a draft for the night before. He noticed I finally got the syntax highlighting plugin working and he was actually there when I was looking through the different color themes for the code. Eventually I settled on one which almost but didn't quite match the theme for the rest of my blog perfectly.

Until this point I hadn't really thought much about why I named the blog what I did. Except now I have a real reason. Before I just sort of thought... "What will people say when they read these posts... AH HAH! 'A Little Off'!!". This doesn't necessarily mean I know my posts will suck or that nobody will appreciate them for whatever they might actually be worth but... generally my ideas are a little off, good, but a little off. But now I have a real reason: If anyone should ask me "Why 'A Little Off'?" all I'll have to do is say "Take a look at the syntax highlighting on the code".

20Feb/099

High(ish)-speed Photography (followup)

DSC_3299

So this Tuesday I got my Arduino in the mail. I really mean just in the mail... it was in an anti-static bag in a bubble-wrap envelope! Anyway I managed to waste about 6 hours screwing around with it the first night I got it. Since then after a lot of researching, googling, swearing and scratching my head I've successfully setup the first major part for the camera trigger project.

I discovered that the delay functions built into the Arduino C library are mostly useless. The microsecond delay function is most useless of all because it will only produce accurate delays between 4 microseconds and 16383 microseconds. So I gave up on that and just wrote a custom delay function. But before I wrote the custom delay function I looked at creating my own timer using Timer2 and giving up digital pins 11 and 3 for accurate times. Eventually I ditched this method because I never got any of the sample code to work at all.

Eventually I arrived at this at least reliable if not accurate delay function:

1
2
3
4
void customDelay(unsigned long time) {
    unsigned long end_time = micros() + time;
    while(micros() < end_time);
}

The advantage to this over the delayMicroseconds() function is that this will at least pay attention to how long it's actually been since it started where the delayMicroseconds() function just blindly sleeps for an arbitrary amount of time and wakes up when it sees fit. The function for oscillating the IR led at the frequency I needed for triggering the camera is of the same form just with a bit of code for switching the LED on and off twice every clock cycle in the while loop. It also turns out that changing the state of a digital pin isn't near instantaneous either, which is to be expected. I've compensated for this using a constant defined for the number of microseconds it takes for it to turn a digital pin on or off.

Once I solved the timing issues it was essentially about cleaning up the code from that point on. I ended up storing the sequence of oscillation and pausing that Nikon SLR's use in two arrays, one for oscillation and one for the matching pause between each oscillation period. Which makes for a clean section for firing the led and pausing all inside a for loop that iterates over each item in the two arrays.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/*
Author:         BeMasher
Description:    Code sample in C for firing the IR sequence that mimics the
                ML-L1 or ML-L3 IR remote control for most Nikon SLR's.

Based off of:   http://make.refractal.org/?p=3
                http://www.cibomahto.com/2008/10/october-thing-a-day-day-7-nikon-camera-intervalometer-part-1/
                http://ilpleut.be/doku.php/code:nikonremote:start
                http://www.bigmike.it/ircontrol/

Notes:          This differs slightly from the other 3 versions I found in that this doesn't use the built in
                delay functions that the Arduino comes with. I discovered that they weren't accurate enough for
                the values I was trying to give them. The delayMicrosecond() function is only accurate between about
                4uS and 16383uS which isn't a very workable range for the values we need to delay in for this project.
                The ASM code that Matt wrote works well but is limited to only pin 12 and I haven't got a good enough
                grasp of the architecture to modify the code to work on any pin. So this is what I've come up with to
                produce the same result.
*/


#define IR_LED 13        //Pin the IR LED is on
#define DELAY 13         //Half of the clock cycle of a 38.4Khz signal
#define DELAY_OFFSET 4   //The amount of time the micros() function takes to return a value
#define SEQ_LEN 4        //The number of long's in the sequence

unsigned long seq_on[] = {2000, 390, 410, 400};        //Period in uS the LED should oscillate
unsigned long seq_off[] = {27830, 1580, 3580, 0};      //Period in uS that should be delayed between pulses

void setup() {
    Serial.begin(19200);        //Initialize Serial at 19200 baud
    pinMode(IR_LED, OUTPUT);    //Set the IR_LED pin to output
}

void customDelay(unsigned long time) {
    unsigned long end_time = micros() + time;    //Calculate when the function should return to it's caller
    while(micros() < end_time);                  //Do nothing 'till we get to the end time
}

void oscillationWrite(int pin, int time) {
    unsigned long end_time = micros() + time;    //Calculate when function should return to it's caller
    while(micros() < end_time) {                 //Until we get to the end time oscillate the LED at 38.4Khz
        digitalWrite(pin, HIGH);
        customDelay(DELAY);
        digitalWrite(pin, LOW);
        customDelay(DELAY - DELAY_OFFSET);        //Assume micros() takes about 4uS to return a value
    }
}

void triggerCamera() {
    for(int i = 0; i < SEQ_LEN; i++) {            //For each long in the sequence
        oscillationWrite(IR_LED, seq_on[i]);      //Oscillate for the current long's value in uS
        customDelay(seq_off[i]);                  //Delay for the current long's value in uS
    }
    customDelay(63200);                            //Wait about 63mS before repeating the sequence
    for(int i = 0; i < SEQ_LEN; i++) {
        oscillationWrite(IR_LED, seq_on[i]);
        customDelay(seq_off[i]);
    }
}

void loop() {
    if(Serial.available()) {        //Wait 'till something is connected
        if(Serial.read() != 0) {    //If anything but 0 is sent take a photo
            triggerCamera();        //Take a photo
        }
        delay(100);                 //Delay an arbitrary amount of time, serial isn't instantaneous
    }
}
19Feb/090

Programming for *wait for it* the fun of it

Most of my friends think that there's something wrong with me, most of them have had programming experience before with at least one class, some of them more programming than that, but the real reason they think there's something wrong with me is that I enjoy programming. Occasionally they'll ask me what I'm up to and when I tell them that I'm programming, they assume it's for a class of some kind but recently it's only been for entertainment//fun. None of them seem to understand how I could possibly enjoy programming. To be completely honest I don't really know myself why I enjoy it so much.

Lately I've been fooling around with Python's functional programming which is pretty limited in terms of pure functional programming but is still interesting. Take the following code for example:

1
2
3
4
5
6
7
8
def GetPrimes(p, i=1):
    if i**2 < p[-1]:
        p[i:] = filter(lambda x: x % p[i-1] != 0, p[i:])
        return GetPrimes(p, i + 1)
    return p

print GetPrimes(range(2,51))
#[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

This was an example I spent about an hour one night coding. It was brought about by a friend of mine that is in a physics computation course that introduces students to the C programming language and it's applications in science. One of the first problems they were given was to determine whether an integer was a prime number or not.

The python blurb I came up with is a short implementation of the Sieve of Eratosthenes. The basic principle of the Sieve of Eratosthenes is that given a list of integers between 2 and the number you wish, you can find all the primes by simply crossing out multiples.

  • Start with 2, remove all multiples of 2 from the list.
  • Move to the next item in the list, this must be a prime
  • Starting on this number's square (since all of the numbers between this number and it's square have already been crossed out) cross out all multiples of this number.
  • Continue until we reach a number in the list such that it's square is greater than the largest integer in this list.

According to the Wikipedia article on this method for finding primes it's useful for "small primes" such as all primes below 10,000,000. The main point of this is just that I found it fascinating and wasted enough time on it to produce a working function to do this...

17Feb/090

Google Data API

I've got a friend who has been doing a lot of web development for the UA Baja Racing Club and I've been offering ideas for developing certain things he wanted on the website like electronic time sheet submission. I suggested he just make a pdf form and have that post to a php script on his site which would then add the vales submitted to a table in his mysql database for the site. The reason I suggested a pdf form is that it would automatically do form validation for him without having to write or find extra code to do that in javascript or in the php part himself.

That ended up being a little too complicated for what he was looking at and wasn't a very feasible solution since he had no real experience with sql. So I started thinking about a few other ways he could do this that would be easier for him to implement himself. Eventually I remembered I wrote a python script for this very thing a few weeks ago that I use to tally up the amount of time I worked in the last pay period for when i'm getting ready to submit my time sheets at work.

The python script uses the gdata api to access my calendars and tally up the total amount of time I worked each day and displays it in a user-friendly format for entering into the website I submit the ETR to.

My grand idea was to simply use their master google account for the club to create calendars for each person//team, share them with each person such that they have permission to modify//create events. Then modify the python script I wrote to spit out CSV files for each shared calendar for easy import into excel (where they manage all of the info for each team and their members).

If you're interested in the script I could post it, it's mostly been kludged together from the python gdata tutorials I found so it's by no means original and I've only been programming in python for a couple of weeks so forgive any glaring mistakes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
try:
    from xml.etree import ElementTree # for Python 2.5 users
except ImportError:
    from elementtree import ElementTree
import gdata.calendar.service
import gdata.service
import atom.service
import gdata.calendar
import atom
import getopt
import sys
import string
import time
import base64
import re
import datetime
import operator
from datetime import date
from datetime import time

def gCalLogin(email, password):
    calendar_service = gdata.calendar.service.CalendarService()
    calendar_service.email = email
    calendar_service.password = base64.b64decode(password)
    calendar_service.source = 'PythonETR'
    calendar_service.ProgrammaticLogin()
    return calendar_service

def FindCalendar(calendar_service, title):
    feed = calendar_service.GetOwnCalendarsFeed()
    for i, a_calendar in enumerate(feed.entry):
        if(a_calendar.title.text == title):
            return a_calendar.id.text
    return False
   
def DateRangeQuery(calendar_service, calendar_id='default', start_date='2009-01-01', end_date='2009-01-30', event_title='Work for ARL'):
    result = []
    parseISO8601 = re.compile("(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+).(\d+)([+-]\d+:\d+)")
    query = gdata.calendar.service.CalendarEventQuery(calendar_id, 'private', 'full')
    query.start_min = start_date
    query.start_max = end_date
    feed = calendar_service.CalendarQuery(query)
    for i, an_event in enumerate(feed.entry):
        if (an_event.title.text == event_title) and (an_event.event_status.value != "CANCELED"):
            for when in an_event.when:
                current_when = [parseISO8601.findall(when.start_time), parseISO8601.findall(when.end_time)]
                if(current_when not in result):
                    result.append(current_when)
    return result

def FindWeekBounds(today, weekday):
    weekstart = datetime.timedelta(days=int(weekday) + 1)
    weekend = datetime.timedelta(days=(5 - int(weekday)))
    return [today - weekstart, today + weekend]
   
calendar_service = gCalLogin("emailaddress@gmail.com", "passwordb64encoded")
work_calendar = FindCalendar(calendar_service, "maincalendarnamehere")
p = re.compile('[\w\d]*?%40group.calendar.google.com', re.IGNORECASE)
work_calendar = ''.join(p.findall(work_calendar)).replace('%40', '@')
today = datetime.date.today()
work_week = {}
start, end = FindWeekBounds(date.today(), date.today().weekday())
work_events = DateRangeQuery(calendar_service, calendar_id=work_calendar, start_date=(start - datetime.timedelta(days=7)).isoformat(), end_date=end.isoformat())
for event in work_events:
    start = [int(x) for x in event[0][0] if x[0] not in ("-", "+")]
    end = [int(x) for x in event[1][0] if x[0] not in ("-", "+")]
    start_datetime = datetime.datetime(start[0], start[1], start[2], start[3], start[4], start[5], start[6])
    end_datetime = datetime.datetime(end[0], end[1], end[2], end[3], end[4], end[5], end[6])
    duration = end_datetime - start_datetime
    try:
        work_week[start_datetime.strftime("%x")] += duration
    except KeyError:
        work_week[start_datetime.strftime("%x")] = duration
       
days = work_week.keys()
days.sort()
for day in days:
    print day, work_week[day]

I did a little more work on the script since I posted the code on pastebin and I found a much simpler method for retrieving lists of calendars:

1
2
3
4
5
6
7
8
9
10
11
12
def GetAllCalendars(calendar_service):
    feed = calendar_service.GetAllCalendarsFeed()
    return map(lambda x: x[1], list(enumerate(feed.entry)))

def GetUserCalendars(calendar_service):
    feed = calendar_service.GetOwnCalendarsFeed()
    return map(lambda x: x[1], list(enumerate(feed.entry)))
   
def GetSharedCalendars(calendar_service):
    return filter(lambda x: x.title.text not in map(lambda y: y.title.text,
        GetUserCalendars(calendar_service)),
        GetAllCalendars(calendar_service))
16Feb/090

High(ish)-speed Photography

This semester I've started a class with the electrical and computer engineering college called Microprocessor Organization. The purpose of this class is to familiarize the students with you guessed it microprocessors. So far it's basically a glorified lab they wanted to turn into a lecture. The lab portion of the course is heavily oriented around assembling your own prototype board and programming said board. In the class we're using a PIC18F4550 microcontroller, which is fascinating and a bit more complex than I wanted to play with at home.

I started looking around for a microcontroller that was simpler and easier to play around with. Eventually I found the arduino which fit my needs perfectly, it's powered through USB, is cheap, has a built in programmer and enough processing power for most of the simple projects I've been thinking about doing at home for fun. As soon as I picked a decent online store I bought an Arduino Duemillanove and a lithium ion battery pack (rechargable  through mini-usb).

I should have both in the next few days and the very first thing I decided on trying was a high-speed camera trigger. I've already done some high-speed flash photography and it was amusing but it was too much of a hassle. Focusing in the dark isn't the easiest thing to do and setting up analog circuits to do this sort of thing aren't the simplest in the world and without custom PCB (breadboards instead) they fall apart as you go. I immediately got started coding a sound-sensitive trigger for firing the IR sequence for shutter release on my Nikon D50. Turns out I'm in luck since I was able to find the sequence and it works for almost all Nikon DSLR's of which my friends have a few. My friend pete wrote about this briefly on his blog and a reader offered to bring his camera out for the expirement to the shooting range (which I haven't mentioned yet... patience).

Now that I've gotten the code written out and a small microphone for sensing sound, an IR LED and at least 3 Nikon DSLR's, all that's left is going out to the shooting range. My main goal for this is to get photographs (in sequence or parallel for stereoscopic photos) of different guns ejecting shells and cycling bolts. Since we're not using the same camera's for each shot they've all got different shutter lag times. My D50 is about 130-140ms when pre-focused. The D40 is 95-105ms when pre-focused. Last but not least the D80 is about 75-85ms. This will turn out well because they're all close enough in time that I won't even need to trigger each camera individually for quick sequences of photos. However this makes doing stereoscopic photos a bit more difficult since I'll have to synchronise two of the camera's to the slower shutter lag of the two. Doing that requires that I have at least two IR LED's, and in the case that I want the cameras to fire in much faster sequence I'll need at least 3 IR LED's (and hope that I can trigger them as quick as I need with the Arduino).

The actual photographic part of this experiment is relatively simple, all I'll need is a similar focal length on each of the cameras which isn't difficult since they all use DX format sensors and it's safe to assume that we all have a lense which can match the same focal length on each camera. And suppose we're shooting at the equivelant sensitivity of iso 400 on each camera (since I doubt we all have prime 35mm lenses that are as fast as the one I've been using) with the same aperture, shutter speed (~1/500-640th) and white-balance we can achieve near identical exposures between the different cameras.

16Feb/090

I Warned You

as tanks developed armour too thick to be penetrated by even this large, powerful rifle, its uses switched to fields such as long range sniping, tank harassment and an improvised anti-aircraft weapon.

via Lahti L-39 - Wikipedia, the free encyclopedia.

I'm well aware that I'm already straying from the suggested topics I outlined in the Problem Statement, but then I did warn you. I sort of feel like Tim the enchanter from Monty Python and the Holy Grail saying that.

Anyway I was talking with my friend Pete a rather gunny person and he sent me a link to a photo of two guns. Now this isn't a very strange occurrence between Pete and I, except that he immediately said "the one on the right is .50BMG" which sort of produced a jaw-dropping effect because the gun on the left was a good 3x larger than the gun on the right. Sure enough it was a 20mm rifle which you may have noticed from the quote above was used in the second World War. I read the wikipedia article on it and found a rather amusing statement that once tanks evolved to become resistant to it it was used for "tank harassment" which I found hilarious.

I'm trying really hard to think of any other way you might "harass a tank" but I can't come up with any other way short of destroying them but that's a lot less harassment than it is destroying which I suppose would still be irritating to those inside. Either way tank harassment doesn't sound like a very fun activity not like cow tipping or other mischievous acts would be.

Filed under: Uncategorized No Comments