// start A/D conversion on altimeter sensor // niaddr = 0xee to convert temperature // 0xf4 to convert pressure // returns 1 if successful, else 0 uns8 StartBaroADC(uns8 niaddr) { #ifdef NOT_PORTED_FOR18F // use gregs code when ready I2CStart(); if( SendI2CByte(BARO_ADDR) != I2C_ACK ) goto SBerror; // access control register, start measurement if( SendI2CByte(0xf4) != I2C_ACK ) goto SBerror; // select 32kHz input, measure temperature if( SendI2CByte(niaddr) != I2C_ACK ) goto SBerror; I2CStop(); // set or clear bit to signal what A/D is currently running _BaroTempRun = (niaddr == 0xee); return(1); SBerror: I2CStop(); #endif return(0); }
void DoCompassTest() { uint16 v; TxString("\r\nCompass test\r\n"); I2CStart(); if( SendI2CByte(COMPASS_I2C_ID+1) != I2C_ACK ) goto CTerror; v = ((uint16)RecvI2CByte(I2C_ACK)*256) | RecvI2CByte(I2C_NACK); I2CStop(); TxVal32((int32)v, 1, 0); TxString("deg\r\n"); return; CTerror: I2CStop(); TxString("FAIL\r\n"); } // DoCompassTest
uint8 ScanI2CBus(void) { int16 s; uint8 d = 0; for(s=0x10; s<=0xf6; s+=2) { // use all uneven addresses for read mode I2CStart(); if( SendI2CByte(s) == I2C_ACK ) { d++; TxString("\t0x"); TxValH(s); TxNextLine(); } I2CStop(); Delay1mS(2); } return(d); } // ScanI2CBus
// read temp & pressure values from baro sensor // return value= niltemp; // returns 1 if value is available uns8 ReadValueFromBaro(void) { #ifdef NOT_PORTED_FOR18F // use gregs code when ready // test if conversion is ready I2CStart(); if( SendI2CByte(BARO_ADDR) != I2C_ACK ) goto RVerror; // access control register if( SendI2CByte(0xf4) != I2C_ACK ) goto RVerror; I2CStart(); // restart if( SendI2CByte(BARO_ADDR+1) != I2C_ACK ) goto RVerror; // read control register niltemp.low8 = RecvI2CByte(I2C_NACK); I2CStop(); if( (niltemp.low8 & 0b0010.0000) == 0 ) { // conversion is ready, read it! I2CStart(); if( SendI2CByte(BARO_ADDR) != I2C_ACK ) goto RVerror; // access A/D registers if( SendI2CByte(0xf6) != I2C_ACK ) goto RVerror; I2CStart(); // restart if( SendI2CByte(BARO_ADDR+1) != I2C_ACK ) goto RVerror; niltemp.high8 = RecvI2CByte(I2C_ACK); niltemp.low8 = RecvI2CByte(!I2C_NACK); I2CStop(); return(1); } return(0); RVerror: I2CStop(); #endif _UseBaro = 0; // read error, disable baro return(0); }
void CalibrateCompass(void) { // calibrate the compass by rotating the ufo through 720 deg smoothly TxString("\r\nCalib. compass. Press any key to cont.\r\n"); while( !RxChar() ); I2CStart(); // Do Bridge Offset Set/Reset now if( SendI2CByte(COMPASS_I2C_ID) != I2C_ACK ) goto CCerror; if( SendI2CByte('O') != I2C_ACK ) goto CCerror; I2CStop(); Delay1mS(7); // set Compass device to Calibration mode I2CStart(); if( SendI2CByte(COMPASS_I2C_ID) != I2C_ACK ) goto CCerror; if( SendI2CByte('C') != I2C_ACK ) goto CCerror; I2CStop(); TxString("\r\n720 deg in ~30 sec.!\r\nPress any key to cont.\r\n"); while( !RxChar() ); // set Compass device to End-Calibration mode I2CStart(); if( SendI2CByte(COMPASS_I2C_ID) != I2C_ACK ) goto CCerror; if( SendI2CByte('E') != I2C_ACK ) goto CCerror; I2CStop(); Delay1mS(50); TxString("OK\r\n"); return; CCerror: I2CStop(); TxString("FAIL\r\n"); } // CalibrateCompass
// Read direction, convert it to 2 degrees unit // and store result in variable AbsDirection. // The current heading correction is stored in CurDeviation void GetDirection(void) { #ifdef NOT_PORTED_FOR18F // use gregs code when ready int16 DirVal, temp; // set Compass device to Compass mode I2CStart(); if( SendI2CByte(COMPASS_ADDR+1) != I2C_ACK ) { I2CStop(); CurDeviation = 0; // no sensor present, deviation = 0 return; } DirVal.high8 = RecvI2CByte(I2C_ACK); DirVal.low8 = RecvI2CByte(!I2C_ACK); I2CStop(); // DirVal has 1/10th degrees // convert to set 360.0 deg = 240 units DirVal /= 15; // must use pre-decrement, because of dumb compiler if( AbsDirection > COMPASS_MAX ) { CurDeviation = 0; AbsDirection--; } else { // setup desired heading (AbsDirection) if( AbsDirection == COMPASS_MAX ) // no heading stored yet { AbsDirection = DirVal; // store current heading CurDeviation = 0; } // calc deviation and direction of deviation DirVal = AbsDirection - DirVal; // handle wraparound if( DirVal <= -240/2 ) DirVal += 240; if( DirVal > 240/2 ) DirVal -= 240; // positive means ufo is left off-heading // negative means ufo is right off-heading if( DirVal > 20 ) // limit to give soft reaction DirVal = 20; if( DirVal < -20 ) DirVal = -20; // Empirical found :-) // New_CurDev = ((3*Old_CurDev)+DirVal) / 4 // temp = (long)CurDeviation; // the previous value! temp *= 3; temp += DirVal; // add the new value temp <<= 2; // = 16* NewCurDev temp *= CompassFactor; CurDeviation = temp.high8; } #endif }
// initialize compass sensor void InitDirection(void) { #ifdef NOT_PORTED_FOR18F // use gregs code when ready // set Compass device to Compass mode I2CStart(); if( SendI2CByte(COMPASS_ADDR) != I2C_ACK ) goto IDerror; // this initialization is no longer needed, is done by testsoftware! #if 0 if( SendI2CByte('G') != I2C_ACK ) goto IDerror; if( SendI2CByte(0x74) != I2C_ACK ) goto IDerror; // select operation mode, continuous mode, 20 Hz if( SendI2CByte(0b0.11.1.00.10) != I2C_ACK ) goto IDerror; I2CStop(); I2CStart(); if( SendI2CByte(COMPASS_ADDR) != I2C_ACK ) goto IDerror; if( SendI2CByte('r') != I2C_ACK ) goto IDerror; if( SendI2CByte(0x06) != I2C_ACK ) goto IDerror; I2CStop(); // read multiple read count to avoid wear-and-tear on EEPROM I2CStart(); if( SendI2CByte(COMPASS_ADDR+1) != I2C_ACK ) goto IDerror; if( RecvI2CByte(!I2C_ACK) != 16 ) { // not correctly set, set it up. I2CStop(); I2CStart(); if( SendI2CByte(COMPASS_ADDR) != I2C_ACK ) goto IDerror; if( SendI2CByte('w') != I2C_ACK ) goto IDerror; if( SendI2CByte(0x06) != I2C_ACK ) goto IDerror; if( SendI2CByte(16) != I2C_ACK ) goto IDerror; } #endif _UseCompass = 1; IDerror: I2CStop(); #endif _UseCompass = 0; }