Help interfacing Altimeter MS5607 with Arduino SPI - From the I2C
danidub
Posts: 13
Hello, I'm stucked in this issue 3 months ago, I really need help, this is the problem, I have to connect the Altimeter MS5607 with my Arduino UNO and using SPI, after trying so many times, I'm really MAD! haha
I think there is a way if I start from the I2C code (I'll paste the example for I2C that works):
I really need it to be using SPI Protocoll
2 files, Altimeter_Arduino_10.ino
and IntersemaBaro.h
Can anyone help me on this one? I dont know where to get help. Thank you very much
I think there is a way if I start from the I2C code (I'll paste the example for I2C that works):
I really need it to be using SPI Protocoll
2 files, Altimeter_Arduino_10.ino
#include <Wire.h>#include "IntersemaBaro.h" Intersema::BaroPressure_MS5607B baro(true); void setup() { Serial.begin(9600); baro.init(); } void loop() { int alt = baro.getHeightCentiMeters(); Serial.print("Centimeters: "); Serial.print((float)(alt)); Serial.print(", Feet: "); Serial.println((float)(alt) / 30.48); delay(400); }
and IntersemaBaro.h
// http://code.google.com/p/ardroneme/// From the file NavData2.zip /* Updated by MAPGPS based on Richi's code: * http://ulrichard.is-a-geek.net/?p=23 */ //Update by boulderjoe 12/30/11 to work with arduino 1.0 #ifndef INTERSEMA_BARO_H #define INTERSEMA_BARO_H #include <Wire.h> #include <util/delay.h> #include "Arduino.h" namespace Intersema { class BaroPressure { public: virtual void init() = 0; int32_t getHeightCentiMeters(void) { return AcquireAveragedSampleCm(NUM_SAMP_FOR_AVG); } protected: virtual int32_t AcquireAveragedSampleCm(const uint8_t nSamples) = 0; virtual uint32_t ConvertPressureTemperature(uint32_t pressure, uint32_t temperature) = 0; int32_t PascalToCentimeter(const int32_t pressurePa) { // Lookup table converting pressure in Pa to altitude in cm. // Each LUT entry is the altitude in cm corresponding to an implicit // pressure value, calculated as [PA_INIT - 1024*index] in Pa. // The table is calculated for a nominal sea-level pressure = 101325 Pa. static const int32_t PZLUT_ENTRIES = 77; static const int32_t PA_INIT = 104908; static const int32_t PA_DELTA = 1024; static const int32_t lookupTable[PZLUT_ENTRIES] = { -29408, -21087, -12700, -4244, 4279, 12874, 21541, 30281, 39095, 47986, 56953, 66000, 75126, 84335, 93628, 103006, 112472, 122026, 131672, 141410, 151244, 161174, 171204, 181335, 191570, 201911, 212361, 222922, 233597, 244388, 255300, 266334, 277494, 288782, 300204, 311761, 323457, 335297, 347285, 359424, 371719, 384174, 396795, 409586, 422552, 435700, 449033, 462560, 476285, 490216, 504360, 518724, 533316, 548144, 563216, 578543, 594134, 609999, 626149, 642595, 659352, 676431, 693847, 711615, 729752, 748275, 767202, 786555, 806356, 826627, 847395, 868688, 890537, 912974, 936037, 959766, 984206}; if(pressurePa > PA_INIT) return lookupTable[0]; else { const int32_t inx = (PA_INIT - pressurePa) >> 10; if(inx >= PZLUT_ENTRIES - 1) return lookupTable[PZLUT_ENTRIES - 1]; else { const int32_t pa1 = PA_INIT - (inx << 10); const int32_t z1 = lookupTable[inx]; const int32_t z2 = lookupTable[inx+1]; return (z1 + (((pa1 - pressurePa) * (z2 - z1)) >> 10)); } } } static const uint8_t NUM_SAMP_FOR_AVG = 4; unsigned int coefficients_[6]; }; class BaroPressure_MS5607B : public BaroPressure { public: /// @param CSB i2c address select BaroPressure_MS5607B(bool CSB = false) : i2cAddr_((CSB ? 0xEC : 0xEE) >> 1) { } void init() { ResetSensor(); ReadCoefficients(); } private: const uint8_t i2cAddr_; static const uint8_t cmdReset_ = 0x1E; static const uint8_t cmdAdcRead_ = 0x00; static const uint8_t cmdAdcConv_ = 0x40; static const uint8_t cmdAdcD1_ = 0x00; static const uint8_t cmdAdcD2_ = 0x10; static const uint8_t cmdAdc256_ = 0x00; static const uint8_t cmdAdc512_ = 0x02; static const uint8_t cmdAdc1024_ = 0x04; static const uint8_t cmdAdc2048_ = 0x06; static const uint8_t cmdAdc4096_ = 0x08; static const uint8_t cmdPromRd_ = 0xA0; void ResetSensor() { Wire.begin(); Wire.beginTransmission(i2cAddr_); Wire.write(cmdReset_); Wire.endTransmission(); delay(3); } void ReadCoefficients(void) { for(uint8_t i=0; i<6; ++i) coefficients_[i] = ReadCoefficient(i + 1); #ifdef DEBUG for(uint8_t i=0; i<6; ++i) { Serial.print("Coefficient "); Serial.print(i + 1, DEC); Serial.print(" : "); Serial.println(coefficients_[i], DEC); } Serial.println(ConvertPressureTemperature(6074082, 8574974)); Serial.println(ConvertPressureTemperature(6074082, 8574984)); #endif } uint16_t ReadCoefficient(const uint8_t coefNum) { uint16_t rC=0; Wire.beginTransmission(i2cAddr_); Wire.write(cmdPromRd_ + coefNum * 2); // send PROM READ command Wire.endTransmission(); Wire.requestFrom(i2cAddr_, static_cast<uint8_t>(2)); if(Wire.available() >= 2) { uint16_t ret = Wire.read(); // read MSB and acknowledge uint16_t rC = 256 * ret; ret = Wire.read(); // read LSB and not acknowledge rC = rC + ret; return rC; } #ifdef DEBUG else { Serial.println("No data available in ReadCoefficient()"); } #endif return 0; } virtual int32_t AcquireAveragedSampleCm(const uint8_t nSamples) { int64_t pressAccum = 0; for(size_t n = nSamples; n; n--) { const uint32_t temperature = ReadAdc(cmdAdcD2_ | cmdAdc4096_); // digital temperature value : typical 8077636 const uint32_t pressure = ReadAdc(cmdAdcD1_ | cmdAdc4096_); // digital pressure value : typical 6465444 const uint32_t pressConv = ConvertPressureTemperature(pressure, temperature); pressAccum += pressConv; /* //MAPGPS Serial.print("pressure: "); Serial.print(pressure, DEC); Serial.print(", pressConv: "); Serial.print(pressConv, DEC); Serial.print(", temperature: "); Serial.println(temperature, DEC); */ } const int32_t pressAvg = pressAccum / nSamples; const int32_t AltCm = PascalToCentimeter(pressAvg); return AltCm; } int32_t ReadAdc(const uint8_t cmd) { Wire.beginTransmission(i2cAddr_); Wire.write(cmdAdcConv_ | cmd); // send conversion command Wire.endTransmission(); // wait necessary conversion time switch(cmd & 0x0f) { case cmdAdc256_: delay(1); break; case cmdAdc512_: delay(3); break; case cmdAdc1024_: delay(4); break; case cmdAdc2048_: delay(6); break; case cmdAdc4096_: delay(10); break; } Wire.beginTransmission(i2cAddr_); Wire.write(cmdAdcRead_); Wire.endTransmission(); Wire.requestFrom(i2cAddr_, static_cast<uint8_t>(3)); if(Wire.available() >= 3) { uint16_t ret = Wire.read(); // read MSB and acknowledge uint32_t temp = 65536 * ret; ret = Wire.read(); // read byte and acknowledge temp = temp + 256 * ret; ret = Wire.read(); // read LSB and not acknowledge temp = temp + ret; return temp; } #ifdef DEBUG else { Serial.println("No data available in cmdAdc()"); } #endif return 0; } uint32_t ConvertPressureTemperature(uint32_t pressure, uint32_t temperature) { // calcualte 1st order pressure and temperature (MS5607 1st order algorithm) const int32_t dT = temperature - coefficients_[4] * 256; // difference between actual and reference temperature //const int32_t temp = (2000 + (dT * coefficients_[5]) / pow(2, 23)) ; // / 100; // actual temperature //const int64_t OFF = static_cast<int64_t>(coefficients_[1]) * pow(2, 17) + dT * coefficients_[3] / pow(2, 6); // offset at actual temperature //const int64_t SENS = static_cast<int64_t>(coefficients_[0]) * pow(2, 16) + dT * coefficients_[2] / pow(2, 7); // sensitivity at actual temperature //const int32_t press = ((pressure * SENS / pow(2, 21) - OFF) / pow(2, 15)); // / 100; // temperature compensated pressure //MAPGPS: adapt formulas to avoid overflow const int32_t OFF = coefficients_[1] * 4 + ((float)dT / 2048) * ((float)coefficients_[3] / 1024); const int32_t SENS = coefficients_[0] * 2 + ((float)dT / 4096) * ((float)coefficients_[2] / 1024); const int32_t press = ((float)pressure / 2048) * ((float)SENS / 1024) - OFF; /* Serial.println(); Serial.println(dT, DEC); Serial.println(OFF, DEC); Serial.println(SENS, DEC); Serial.println(); */ return press; } }; } // namespace Intersema #endif
Can anyone help me on this one? I dont know where to get help. Thank you very much
Comments