Shop OBEX P1 Docs P2 Docs Learn Events
Help interfacing Altimeter MS5607 with Arduino SPI - From the I2C — Parallax Forums

Help interfacing Altimeter MS5607 with Arduino SPI - From the I2C

danidubdanidub Posts: 13
edited 2012-08-24 14:50 in Accessories
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
#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

  • FranklinFranklin Posts: 4,747
    edited 2012-08-23 13:26
    You need to stick with your original thread and not start a new one. It is against forum rules and causes readers to start over without the knowledge imparted in the previous thread. Please go back and check the other thread.
  • danidubdanidub Posts: 13
    edited 2012-08-24 14:50
    I'm sorry about that, I'll continue from the other post and paste this message. Thank you
Sign In or Register to comment.