Problem with the Altimeter Module MS5607
Skywolf
Posts: 3
Hello!
I recently bought my altimeter module. But I'm new to working with these and Arduino, and I'm having some trouble getting proper results. So here's My setup...
My code...
And my results--
[HTML]http://gyazo.com/c2ca47d96fe1d6894ae6d02529ce80e6[/HTML]
The data never changes. Am I doing anything wrong?
Thanks!
I recently bought my altimeter module. But I'm new to working with these and Arduino, and I'm having some trouble getting proper results. So here's My setup...
My code...
#include <Wire.h> #include "IntersemaBaro.h" Intersema::BaroPressure_MS5607B baro(true); void setup() { Serial.begin(9600); baro.init(); } void loop() { long alt = baro.getHeightCentiMeters(); Serial.print("Centimeters: "); Serial.print((float)(alt), 2); Serial.print(", Feet: "); Serial.println((float)(alt) / 30.48, 2); delay(400); }
// http://code.google.com/p/ardroneme/// From the file NavData2.zip /* * http://ulrichard.is-a-geek.net/?p=23 */ #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
And my results--
[HTML]http://gyazo.com/c2ca47d96fe1d6894ae6d02529ce80e6[/HTML]
The data never changes. Am I doing anything wrong?
Thanks!
Comments
After that, it looks like you are using the Parallax KickStart code, so I assume it works. You probably have a hardware problem. Can you provide a schematic for your circuit, and maybe a picture?
If the code is working correctly, you should be able to see a change in the numbers if you gently blow into the module. Do you see any change?
Thanks for replying! I posted these pictures earlier, but here they are again in case you didn't see them.
The numbers don't change when I blow into the module, but I noticed that if I remove the power while the script is running, the numbers change to a different set of digits. Does this mean that the chip is being "registered", but not working?
Thanks!
The change in readings is likely due to the pullup resistors being removed.
Well, it looks like you have everything wired up correctly, and the sample code is presumed good. So, here are some things that I would try:
1. Attach a logic analyzer or oscilloscope to the SCL and SDA lines, and see what data is sent.
2. Try a new Arduino and/or a new altimeter module.
After that, I don't have ideas.