Work has been busy so this has suffered somewhat.
I have done some work around integrating a EM406A SiRF III GPS with an Arduino compatible and displaying the results on a 2x16 LCD.
Here's a photo of the completed prototype.

Sorry about the smudging of the last two digits on the display - it actually resolves right to my house!
Connecting the GPS to the Ardweeny is trivial. Buy a spare cable to connect the GPS with. These are usually 30cm long. Cut it in 1/2 and solder pins onto the wire ends. Connect the GND & +5v pins, then connect the Tx pin to D0 (pin 2) of the Ardweeny.
Next we need to connect the display to the Ardweeny.
These connections control the display device:
D10 -> 4 (RS)
D11 -> 5 (R/W)
D12 -> 6 (Enable)
These connections carry data 4bits at a time:
D4 -> 11 (Data 4)
D5 -> 12 (Data 5)
D6 -> 13 (Data 6)
D7 -> 14 (Data 7)
Finally we need to connect the remaining display pins:
1 -> GND
2 -> +5v
3 -> GND (LCD Contrast)
7 -> 4.7k resistor -> GND (Data0)
8 -> 4.7k resistor -> GND (Data1)
9 -> 4.7k resistor -> GND (Data2)
10 -> 4.7k resistor -> GND (Data3)
To make it work you'll need the following sketch. This will print the current LAT/LONG to the LCD as well as echo the selected messages to the TX line, suitable for viewing via the serial monitor.
int contrastPin= 9;
int contrast = 0;
int stepval = 25;
int dir = 1;
int limit = 250;
int RegisterSelect = 10;
int ReadWrite = 11;
int Enable = 12;
int LEDPin = 13;
static int bpc = 8;
void setup() {
// Set digital output pins 0 though 7 as outputs.
// These are used to send the displayed characters
DDRD = 0xF0; // d4,d5,d6 & d7 are outputs
// DDRD = 0xFF; // All pins are outputs.
// Initialize the LCD control lines.
digitalWrite(Enable, HIGH);
digitalWrite(RegisterSelect, LOW); // LOW = device CTRL, HIGH=data
digitalWrite(ReadWrite, LOW);
digitalWrite(LEDPin, LOW);
analogWrite(contrastPin, 60);
//digitalWrite(contrastPin, LOW);
// Set control pins to be outputs
pinMode(RegisterSelect, OUTPUT); // LCD Register Select
pinMode(ReadWrite, OUTPUT); // LCD ReadWrite
pinMode(Enable, OUTPUT); // LCD Enable
pinMode(contrastPin, OUTPUT); // LCD Contrast
pinMode(LEDPin, OUTPUT); // LED Blinkin Light
delayMicroseconds(250);
// Step one - set the Bits per character (and command)
writeCommand(0x30);
writeCommand(0x30);
writeCommand(0x30);
set4bitmode();
writeCommand(0x28); // 4bit mode, 2 lines, 5x7 dots
writeCommand(0x0F); // Display ON, Cursor ON, Blink ON
clearDisplay(); // Clear the display
delayMicroseconds(500);
Serial.begin(4800);
//delay(1000);
//Serial.write("$PSRF100,01,4800,08,01,00*0E\r\n");
writeString("GPS_TO_LCD");
moveCursor(1, 0);
writeString("Version 0.1");
delay(2000);
}
void printPrompts() {
clearDisplay();
writeString("Lat:");
moveCursor(1,0);
writeString("Long:");
}
void moveCursor(int row, int col) {
char outputByte = 0x0;
outputByte = row * 0x40 + col;
outputByte |= 0x80;
writeCommand(outputByte);
}
void clearDisplay() {
writeCommand( 0x01 );
delay(4);
}
void enableDisplay() {
writeCommand( 0x0F );
}
void set8bitmode() {
bpc = 8;
PORTD = 0x38;
digitalWrite(RegisterSelect, LOW);// LOW = device CTRL, HIGH=data
digitalWrite(Enable, LOW);
delayMicroseconds(250);
digitalWrite(Enable, HIGH);
delayMicroseconds(250);
}
void set4bitmode() {
bpc = 4;
digitalWrite(4, LOW);
digitalWrite(5, HIGH);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(RegisterSelect, LOW);// LOW = device CTRL, HIGH=data
digitalWrite(Enable, LOW);
delayMicroseconds(250);
digitalWrite(Enable, HIGH);
delayMicroseconds(250);
}
void writeCommand(char character) {
digitalWrite(RegisterSelect, LOW);// LOW = device CTRL, HIGH=data
if(bpc == 4) {
writeNibble((character & 0xF0) >> 4);
writeNibble(character & 0x0F); }
else {
PORTD = character;
digitalWrite(Enable, LOW);
delayMicroseconds(250);
digitalWrite(Enable, HIGH);
delayMicroseconds(250); }
}
void writeCharacter(char character) {
digitalWrite(RegisterSelect, HIGH);// LOW = device CTRL, HIGH=data
if(bpc == 4) {
writeNibble((character & 0xF0) >> 4);
writeNibble(character & 0x0F); }
else {
PORTD = character;
digitalWrite(Enable, LOW);
delayMicroseconds(250);
digitalWrite(Enable, HIGH);
delayMicroseconds(250); }
}
void writeNibble(char character) {
digitalWrite(7, character & 0x08 ? 1 : 0);
digitalWrite(6, character & 0x04 ? 1 : 0);
digitalWrite(5, character & 0x02 ? 1 : 0);
digitalWrite(4, character & 0x01 ? 1 : 0);
digitalWrite(Enable, LOW);
delayMicroseconds(250);
digitalWrite(Enable, HIGH);
delayMicroseconds(250);
}
void writeString(char *string) {
char *pointer = string;
while(*pointer) {
writeCharacter(*pointer);
pointer++; }
}
void loop() {
char nmea_sentence[128];
char *ptr = nmea_sentence;
char newchar;
int match_cnt;
char *saveptr, *latlongptr;
char time[11];
char latitude[11];
char northSouth[2];
char longitude[11];
char eastWest[2];
char quality[2];
Serial.print("Entering main loop\r\n");
printPrompts();
while(true) {
while(Serial.available() > 0) {
newchar = Serial.read();
*ptr = newchar;
ptr++;
if(newchar == 0x0A) {
*ptr = 0x00;
/* Is it a string we're interested in? */
if(strncmp(nmea_sentence, "$GPGLL", 6) == 0 ) {
Serial.write(nmea_sentence);
}
else if(strncmp(nmea_sentence, "$GPGGA", 6) == 0 ) {
Serial.write(nmea_sentence);
ptr = nmea_sentence;
strsep(&ptr, ",");
strsep(&ptr, ",");
latlongptr = strsep(&ptr, ",");
moveCursor(0,15-strlen(latlongptr));
writeString(latlongptr);
writeString(strsep(&ptr, ","));
latlongptr = strsep(&ptr, ",");
moveCursor(1,15-strlen(latlongptr));
writeString(latlongptr);
writeString(strsep(&ptr, ","));
}
/* We're finished with that string, reset the pointer. */
ptr = nmea_sentence;
}
else {
if(ptr > nmea_sentence + sizeof(nmea_sentence)) {
clearDisplay();
writeString("Error - NMEA");
moveCursor(1,0);
writeString("string too long");
delay(1000);
printPrompts();
ptr = nmea_sentence; }
}
}
}
}