/* compass.c Routines for the vector compass module. Pinouts are specified as global variables. Must call compass_init before attempting to read the compass. It takes approx .26 seconds to take a reading, so if you're turning at the time ... :-( v1.0, Doug Rinckes, 2001 doug.rinckes@iname.com */ /* digital outputs on the expansion board */ int sclk = 5; /* green wire */ int pcss = 6; /* white wire */ int reset = 7; /* brown wire */ /* digital inputs on the handyboard */ int sdo = 14; /* blue wire */ int eoc = 15; /* purple wire */ void compass_init() { set_digital_out(pcss); set_digital_out(sclk); set_digital_out(reset); clear_digital_out(reset); msleep(15L); set_digital_out(reset); msleep(5L); /* this long wait is to prevent attempting to read the compass until it is fully reset. */ msleep(100L); } int compass_read() { int bit; int heading = 0; int eoc_return; /* set sclk and pcss high, then drop pcss for a short time */ set_digital_out(sclk); set_digital_out(pcss); msleep(5L); clear_digital_out(pcss); msleep(2L); set_digital_out(pcss); /* eoc should drop... */ eoc_return = digital(eoc); if (eoc_return == 1) { /* hmm, eoc didn't drop. try poking it again */ set_digital_out(pcss); msleep(5L); clear_digital_out(pcss); msleep(2L); set_digital_out(pcss); eoc_return = digital(eoc); /* if eoc still didn't drop, bomb out, otherwise continue */ if (eoc_return == 1) { return -1; } } /* ok now wait until eoc goes high - indicates that the compass is ready */ while (digital(eoc) != 1) { ; } /* so eoc is now high, and the compass can be read */ /* drop pcss while data is being clocked out */ clear_digital_out(pcss); /* clock 7 times to clock out seven bits which aren't used. */ for (bit = 1;bit <= 7;bit ++) { clear_digital_out(sclk); set_digital_out(sclk); } /* get the next bit */ clear_digital_out(sclk); set_digital_out(sclk); if (digital(sdo) == 1) { heading=256; } /* now clock out the next 8 bits */ msleep(5L); for (bit = 7;bit > 0;bit --) { clear_digital_out(sclk); set_digital_out(sclk); if (digital(sdo) != 0) { heading +=(int)((2.^(float)(bit))+1.); } } /* clock out final bit (bit 0). causes floating point overflow if done in previous loop. */ clear_digital_out(sclk); set_digital_out(sclk); if (digital(sdo) != 0) { heading +=1; } clear_digital_out(sclk); set_digital_out(pcss); set_digital_out(sclk); return heading; }