Archive

Archive for the ‘Development’ Category

Installing Phidgets in Fedora

January 26th, 2010

Phidgets are boards for sensing and control projects that are managed via a USB connection to a computer. I use the Phidget Interface Kit 0/0/4 for my Christmas light controllers. To control the boards from a Linux workstation, it is necessary to install the Phidgets driver. To allow connectivity to Phidgets from Fedora 12 (or Fedora 10 or 11):

  1. Download the Phidget source: http://www.phidgets.com/drivers.php
  2. Untar the contents and change to the phidget21 directory.
  3. Run make, then sudo make install.
  4. Copy the udev configuration file to the appropriate location.
    sudo cp udev/99-phidgets.rules /etc/udev/rules.d/
  5. Restart udev.
    sudo /etc/init.d/udev-post reload
  6. Connect (or unplug and reconnect) the Phidget board to an available USB port.

I typically control the Phidget board using Python. To install the necessary Python modules:

  1. Download the Python module source: http://www.phidgets.com/programming_resources.php
  2. Unzip the module.
  3. Move the Phidgets directory to the standard location for Python modules.
    sudo mv Phidgets/ /usr/lib64/python2.6/

Christmas Lights, Development, Linux , , , ,

Revert Commit in Subversion

January 21st, 2010
svn merge -r HEAD:[revision number before bad commit] .
svn commit

Development

Preventing Auto-Padding in C Structures

January 5th, 2010

Most networking applications written in C use structures to easily access the data in a packet header. If all the pieces are appropriately word aligned (i.e. one or more sequential parts of the header total 4-bytes in length), then a regular C structure works just fine. The standard IP, TCP, and UDP headers are all word aligned.

However, the custom packet header I was using for a project was not word aligned. Using a regular structure without any special notation, caused the GNU C compiler (gcc) to automatically add padding to the structure to force one or more sequential variables to be 4-byte aligned. But, the packet should not contain this extra padding. The parts of the header need to be “packed.”

To force an entire structure to be packed, add

__attribute__((packed))

at the end of the structure definition. For example:

struct mine {
short a;
int b;
}__attribute__((packed));

It is important to note that not all architectures will allow “packed” structures. Most RISC architectures require that variables be word-aligned, and generate a fault when memory is read across two words. The x86 and x86_64 architectures allow non-word-aligned variables for backwards compatibility to earlier processor versions. Wikipedia has more details on data structure alignment.

(The original source of this solution is: http://tuxsudh.blogspot.com/2005/05/structure-packing-in-gcc.html)

Development

Multiple Letter Mail Merge in Word 2007

August 9th, 2009

I recently assisted someone with a mail-merge in Microsoft Word 2007 for a letter whose content depended on a person’s interests. I started with three different components (all in the same directory):

  1. An Excel spreadsheet containing the name, address, and area of interest for everyone who should receive the letter.
  2. A Word document with the top of the letter (date, address block, and greeting).
  3. Word documents with a different letter body and signature for each area of interest. The documents were each named for the area of interest as stored in the spreadsheet.

In the Word document containing the top of the letter, I setup a mail-merge. The source data was the Excel spreadsheet. I inserted the necessary merge fields for the top of the letter. I also inserted the area of interest field surrounded by four equal signs (=) in the place where the body should go.

====<<Area_Of_Interest>>====

In the same document I wrote a macro to do the following:

  1. Complete the merge to a new document
  2. Find the first occurrence of ====*==== in the document, where * was a wild card for the area of interest
  3. Remove the equal signs and area of interest
  4. Insert one of the body and signature Word documents using the area of interest to determine the file name
  5. Go back to step #2 and repeat until no more occurrences of ====*==== exist

In the end, I had each letter with the appropriate address block, greeting, and letter body based on the data in the Excel spreadsheet. Below is the VBA code for the macro.

Sub InsertLetter()
Dim dept
Dim aRange
Dim done
Dim filename

'Execute mail merge
With ActiveDocument.MailMerge
    .Destination = wdSendToNewDocument
    .Execute
End With

'Search entire document for special tags
done = False
Selection.SetRange ActiveDocument.Range.Start, ActiveDocument.Range.End

'Continue searching document until no more tags are found
Do While (Not done)
    'Execute search
    With Selection.Find
        .Text = "====*===="
        .Forward = True
        .Wrap = wdFindContinue
        .Format = False
        .MatchCase = False
        .MatchWholeWord = True
        .MatchWildcards = True
        .MatchSoundsLike = False
        .MatchAllWordForms = False
    End With
    Selection.Find.Execute

    'If tag is found, get value of tag
    If (Selection.Find.Found) Then
        dept = ActiveWindow.ActivePane.Selection
        dept = Left(dept, Len(dept) - 4)
        dept = Right(dept, Len(dept) - 4)
        filename = dept + ".doc"

        'Verify document to insert (replacing tag) exists and insert
        If (Dir(filename) <> "") Then
            ActiveWindow.ActivePane.Selection = ""
            Set aRange = ActiveWindow.ActivePane.Selection
            aRange.Start = aRange.End
            aRange.InsertFile filename:=filename
            'Display and put error message in document if file does not exist
        Else
            MsgBox "No letter found for department: " + dept, vbExclamation
            ActiveWindow.ActivePane.Selection = "No letter found for department: " _
                + dept
        End If

        'Update search range to search the rest of the document
        Selection.SetRange Selection.End, ActiveDocument.Range.End
    Else
        done = True
    End If
Loop
End Sub

Development