Bootcamp Time Resync for Windows XP

October 3rd, 2007

Every so often while booted in Windows XP, I notice that the system time is off by 3 hours. This is due to the differences between how Windows and UNIX/OS X read time from the hardware clock, but that’s not important.

To solve it, I created a batch file in Notepad.exe containing one line:

w32tm /resync /rediscover

I saved it as resync.bat to my startup folder (right click Start, open Programs>Startup) and dragged a shortcut to the desktop. Now XP resyncs to the correct time when I reboot, and if it strays I just double click the batch file.

SEO and me

May 6th, 2007

One of my consulting clients ( Newfields Inc, http://www.newfields.ca ) has asked me to improve their website’s Google ranking. Never one to back down from a challenge, I’m learning all I can about search engine optimization.

If anyone has any tips (or needs a dental microscope installed in Canada!) let me know.

NSLevelIndicator

April 12th, 2007

After a year or so of low-level C coding, I’ve decided to switch over into the Xcode/Objective-C development side of things (GUI apps are a lot prettier than command-line apps). I’ve never been one to learn from books, so my current coding style is such that whenever I encounter a problem, I turn to Google.

Today, Google failed me.

I felt like playing around with NSLevelIndicator, as it’s a fancy 10.4 indicator that just looks cool. After hooking it up in Interface Builder, I tried to interact with it. Aside from setting the runtime value, I couldn’t figure out the command to set the value on the fly. The Apple documentation was no help, as all it provided was information on setting ranges and tick marks.

discreteLevelIndicator
greenLevelIndicator
yellowLevelIndicator
redLevelIndicator

No other sites could help me either. It turns out the solution was easier than I had expected: [NSLevelIndicator setDoubleValue:1.3]; (or any double value). It should also respond to setIntValue:n and setFloatValue:n.nn.

Other useful tidbits:

[NSLevelIndicator setFrameRotation: 90.0]; //makes a vertical NSLevelIndicator
[NSLevelIndicator setContinuous:YES]; //allows user interaction via dragging
[NSLevelIndicator setEnabled:NO]; //disables user interaction, enabled by default

Let’s get right into it…

April 12th, 2007

I recently picked up a BU-353 USGlobalSat USB GPS receiver for $50 off eBay. After some “troubles” with the not-well-advertised included magnet (more on that later) I hooked it up and began to search for ways to access the NMEA 0183 data stream.

It’s a fairly straightforward process, though accessing the stream using the right communication settings (8n1, 4800 baud) is somewhat confusing.

#include /* Standard input/output definitions */
#include /* String function definitions */
#include /* UNIX standard function definitions */
#include /* File control definitions */
#include /* Error number definitions */
#include /* POSIX terminal control definitions */
int fd;
struct termios options;
int streamGPSdata()
{
char b[255]; /* Input buffer */
char out[255];
char *bufptr; /* Current char in buffer */
int nbytes; /* Number of bytes read */
int tries; /* Number of tries so far */
fd = open(”/dev/cu.usbserial”, O_RDONLY | O_NOCTTY);
fcntl(fd, F_SETFL, 0);
tcgetattr(fd, &options);
cfsetispeed(&options, B4800);
cfsetospeed(&options, B4800);
options.c_cflag |= (CS8);
tcsetattr(fd, TCSANOW, &options);
for (tries = 0; tries < 20; tries ++)
{
bufptr = b;
while ((nbytes = read(fd, bufptr, b + sizeof(b) - bufptr - 1)) > 0)
{
bufptr += nbytes;
if (bufptr[-1] == ‘$’)
{
int d;
for(d = 0; d < 255; d++)
{
if(b[d]==’$'||b[d]==’A'||b[d]==’B'||b[d]==’C'||b[d]==’D’
||b[d]==’E'||b[d]==’F'||b[d]==’G'||b[d]==’H'||b[d]==’I’
||b[d]==’J'||b[d]==’K'||b[d]==’L'||b[d]==’M'||b[d]==’N’
||b[d]==’O'||b[d]==’P'||b[d]==’Q'||b[d]==’R'||b[d]==’S’
||b[d]==’T'||b[d]==’U'||b[d]==’V'||b[d]==’W'||b[d]==’X’
||b[d]==’Y'||b[d]==’Z'||b[d]==’0′||b[d]==’1′||b[d]==’2′
||b[d]==’3′||b[d]==’4′||b[d]==’5′||b[d]==’6′||b[d]==’7′
||b[d]==’8′||b[d]==’9′||b[d]==’,'||b[d]==’.'||b[d]==’*'){
if(b[d] != ‘*’){
out[d]=b[d];
}else{
out[d]=’\0′;
break;
}
// out[d]=b[d];
}
}
//printf(”\n”);
break;
}
}
if (strncmp(out, “GPGLL”, 5) == 0){
/* header, ddmm.mmmm (lat), N/S, dddmm.mmmm, E/W, hhmmss.sss, valid */
/* GPGLL, 4553.6629, N, 06422.4178, W, 142608.000, A*2B,0$9,18.7,M,022.1,M,18.8,0000*4E??$? */
printf(”We’ve got latitude/longitude!\n”);
printf(”%s\n\n”, out);
}
else if (strncmp(out, “GPRMC”, 5) == 0){
printf(”Time, date, position, course, speed.\n”);
/* header, hhmmss.sss, valid, ddmm.mmmm (lat), N/S, dddmm.mmmm (lon), E/W, speed, course, ddmmyy, magvar, */
/* GPRMC, 142607.000, A, 4553.6627, N, 06422.4175, W, 0.23, 137.29, 100407, ,*xx */
printf(”%s\n\n”, out);
}
else if (strncmp(out, “GPVTG”, 5) == 0){
/* header, course, T, course, M, speed, units, speed, units */
/* GPVTG, 284.29, T, , M, 0.20, N, 0.4, K*xx */
printf(”We’ve got a course and speed.\n”);
printf(”%s\n\n”, out);
}
else if (strncmp(out, “GPGSV”, 5) == 0){
/* header, #messages, message#, numsats, idCh1, elevation, azimuth, SNR, idCh2, elev, azim, SNR, idCh3, elev, azim, SNR, idCh4, elev, azim, SNR */
/* GPGSV, 3, 1, 12, 02, 76, 329, 32, 04, 51, 086, 31, 10, 49, 229, 30, 13, 34, 061, 20*xx */
printf(”This is overall satellite data.\n”);
printf(”%s\n\n”, out);
}
else if (strncmp(out, “GPGSA”, 5) == 0){
/* header, A, 2/3D, satUsedCh1, Ch2,Ch3,Ch4,Ch5,Ch6,Ch7,Ch8,Ch9,Ch10,Ch11,Ch12, PDOP, HDOP, VDOP */
/* GPGSA, A, 3, 12, 04, 02, 10, 05, 13, 30, 17, 23, , , , 1.5, 0.9, 1.3*xx */
printf(”This is active satellite data.\n”);
printf(”%s\n\n”, out);
}
else if (strncmp(out, “GPGGA”, 5) == 0){
/* header, hhmmss.sss, ddmm.mmmm (lat), N/S, dddmm.mmmm (lon), E/W, 1, numsats[0-12], HDOP, altitude, units, geoid sep, units, diff. corr., 0000 */
/* GPGGA, 143727.000, 4553.6654, N, 06422.4203, W, 1, 06, 2.2, 29.3, M, 022.1, M, 18.8, 0000*xx*/
printf(”This is GPS fixed data.\n”);
printf(”%s\n\n”, out);
}
}
return (-1);
}
int main()
{
streamGPSdata();
printf(”Quitting now.\n”);
close(fd);
}

The code is somewhat hackish - it scans through the NMEA stream (which consists primarily of ASCII garbage) for $GPxxx data (which only uses the shortened alphabet I scan for). It’s also still hardcoded for the Prolific-based BU-353, which installs a driver at /dev/cu.usbserial.

Compiled and tested under Mac OS X 10.4.8, gcc 4.0.0: gcc code.c -o app; ./app