If anyone's interested, here's the code I used, slightly modified and spliced from the internet. This is for the SCP1000-D01, with my temperature running about 35 degrees F hot which for now I'm attributing to the heating from the amperage:// define spi bus pins#define SLAVESELECT 10 //CSB#define SPICLOCK 13 //SCK#define DATAOUT 11 //MOSI#define DATAIN 12 //MISO#define UBLB(a,b) ( ( (a) << 8) | (b) )#define UBLB19(a,b) ( ( (a) << 16 ) | (b) )//Addresses#define REVID 0x00 //ASIC Revision Number#define OPSTATUS 0x04 //Operation Status#define STATUS 0x07 //ASIC Status#define START 0x0A //Constant Readings#define PRESSURE 0x1F //Pressure 3 MSB#define PRESSURE_LSB 0x20 //Pressure 16 LSB#define TEMP 0x21 //16 bit tempchar rev_in_byte;int temp_in;unsigned long pressure_lsb;unsigned long pressure_msb;unsigned long temp_pressure;unsigned long pressure;float altitude;void setup(){byte clr;pinMode(DATAOUT, OUTPUT);pinMode(DATAIN, INPUT);pinMode(SPICLOCK,OUTPUT);pinMode(SLAVESELECT,OUTPUT);digitalWrite(SLAVESELECT,HIGH); //disable deviceSPCR = B01010011; //MPIE=0, SPE=1 (on), DORD=0 (MSB first), MSTR=1 (master), CPOL=0 (clock idle when low), CPHA=0 (samples MOSI on rising edge), SPR1=0 & SPR0=0 (500kHz)clr=SPSR;clr=SPDR;delay(10);Serial.begin(9600);delay(500);Serial.println("Initialize High Speed Constant Reading Mode");write_register(0x03,0x09);}void loop(){rev_in_byte = read_register(REVID);pressure_msb = read_register(PRESSURE);pressure_msb &= B00000111;pressure_lsb = read_register16(PRESSURE_LSB);pressure_lsb &= 0x0000FFFF;pressure = UBLB19(pressure_msb, pressure_lsb);pressure /= 4;altitude = (1 - pow((float)pressure/101325,0.19025515825))*(288.15/0.00199074074);Serial.print("Altitude ft [");Serial.print(altitude);Serial.println("]");temp_in = read_register16(TEMP);temp_in = temp_in / 20;temp_in = 1.8 * temp_in - 3;Serial.print("TEMP F [");Serial.print(temp_in , DEC);Serial.println("]");delay(1500);}char spi_transfer(volatile char data){SPDR = data; // Start the transmissionwhile (!(SPSR & (1<<SPIF))) // Wait for the end of the transmission{};return SPDR; // return the received byte}char read_register(char register_name){char in_byte;register_name <<= 2;register_name &= B11111100; //Read commanddigitalWrite(SLAVESELECT,LOW); //Select SPI Devicespi_transfer(register_name); //Write byte to devicein_byte = spi_transfer(0x00); //Send nothing, but we should get back the register valuedigitalWrite(SLAVESELECT,HIGH);delay(10);return(in_byte);}float read_register16(char register_name){byte in_byte1;byte in_byte2;float in_word;register_name <<= 2;register_name &= B11111100; //Read commanddigitalWrite(SLAVESELECT,LOW); //Select SPI Devicespi_transfer(register_name); //Write byte to devicein_byte1 = spi_transfer(0x00);in_byte2 = spi_transfer(0x00);digitalWrite(SLAVESELECT,HIGH);in_word = UBLB(in_byte1,in_byte2);return(in_word);}void write_register(char register_name, char register_value){register_name <<= 2;register_name |= B00000010; //Write commanddigitalWrite(SLAVESELECT,LOW); //Select SPI devicespi_transfer(register_name); //Send register locationspi_transfer(register_value); //Send value to record into registerdigitalWrite(SLAVESELECT,HIGH);}/-------------------------------------------------------------------------------------------------------------------------------This is the code I used to get a decent compass heading. There's a lot of extra fluff in this code, and its not modified at all:#include#includeint magReading = 0;int XmagValue = 0;int YmagValue = 0;int Azimuth = 0;void setup(){Serial.begin(9600);Wire.begin();}void magRead(int outputMode){// int HMC6352Address = 0x42;// Shift the device's documented slave address (0x42) 1 bit right// This compensates for how the TWI library only wants the// 7 most significant bits (with the high bit padded with 0)// slaveAddress = HMC6352Address >> 1; // This results in 0x21 as the address to pass to TWIint slaveAddress = 0x21; // This is calculated from HMC6352's address, see comments aboveint ramDelay = 100; // us, delay between a RAM write command and its effect, at least 70usint getDelay = 10; // ms, delay between a get data command and its effect, at least 6msbyte magData[2];int i;switch (outputMode){case 0:Wire.beginTransmission(slaveAddress);Wire.send(0x47); // Write to RAM commandWire.send(0x4E); // Output Mode control byte addressWire.send(0x00); // 0x00 for Heading modeWire.endTransmission();break;case 1:Wire.beginTransmission(slaveAddress);Wire.send(0x47); // Write to RAM commandWire.send(0x4E); // Output Mode control byte addressWire.send(0x03); // 0x03 for Magnetometer X modeWire.endTransmission();break;case 2:Wire.beginTransmission(slaveAddress);Wire.send(0x47); // Write to RAM commandWire.send(0x4E); // Output Mode control byte addressWire.send(0x04); // 0x04 for Magnetometer Y modeWire.endTransmission();break;default:Wire.beginTransmission(slaveAddress);Wire.send(0x47); // Write to RAM commandWire.send(0x4E); // Output Mode control byte addressWire.send(0x00); // default to Heading modeWire.endTransmission();}delayMicroseconds(ramDelay); // RAM write needs 70 microseconds to respondWire.beginTransmission(slaveAddress);Wire.send("A"); // The "Get Data" commandWire.endTransmission();delay(getDelay); // Get Data needs 6 milliseconds to respondWire.requestFrom(slaveAddress, 2); // Request the 2 byte data (MSB comes first)i = 0;while(Wire.available() && i < 2){magData[i] = Wire.receive();i++;}magReading = magData[0]*256 + magData[1];}void loop(){magRead(0);Azimuth = magReading;magRead(1);XmagValue = magReading;magRead(2);YmagValue = magReading;Serial.print("Mag X: ");Serial.print(XmagValue);Serial.print(" Mag Y: ");Serial.print(YmagValue);Serial.print(" Azimuth: ");Serial.print(-int(atan2(YmagValue,XmagValue)*57));Serial.print(" degrees ");Serial.print(int(Azimuth/10));Serial.println(" degrees ");delay(500);}
Just working with what I have. I checked the altitude I was getting from the scp1000, compared it against the local altimeter setting and it was spot on. I don't believe higher fidelity is necessary.
Are you fully aware that at 60USD there is a calibrated altitude meter with ASCII and binary serial output? www.aerialrobotics.eu/altigps/altigps-en.pdf
There is a long way of calibrating and recalculating the altitude to ground level.
Comments
www.aerialrobotics.eu/altigps/altigps-en.pdf
There is a long way of calibrating and recalculating the altitude to ground level.