Shop OBEX P1 Docs P2 Docs Learn Events
Arduino UNO not reading data from Parallax Altimeter. — Parallax Forums

Arduino UNO not reading data from Parallax Altimeter.

murraylmurrayl Posts: 9
edited 2014-01-21 18:30 in Accessories
I am attempting to get the arduino Parallax altimeter working with my Arduino UNO.
I have wired it per the diagram given in the example code.
I have verified a good consistent 5V in on the altimeter power leads. I am powering with a 9V battery.
I have checked the pins, with the Arduino UNO Analog 4 is connected to the SDA pin.
Analog 5 is connected to SCL pin.

I am using the Arduino IDE 1.0.5 with the Arduino UNO R3 SMD

The i2C routine appears to be reading back all zeroes from the altimeter module.
I turned on the debug code in the function AquireAveragedSampleCM().
It is labeled //MAPGPS.
When it prints the pressure/pressure converted/temperature, they all read zero.

This would lead me to the conclusion that either I've done something wrong, or something is not initialized properly.
It looks like the i2caddress comes from the code and appears to be set in the constructor to 0xee>>1 which I guess makes it 77.

I'm new to arduino and am rusty from a few years of not programming. I did embedded programming for many years.

I'm hoping it is some simple initialization.

I am using the 1.0 code downloaded from the Parallax site next to the diagram for the Arduino UNO.

I would be grateful for any help you could give!.

Comments

  • FranklinFranklin Posts: 4,747
    edited 2013-11-25 21:38
    Don't know if this will help but, http://forum.arduino.cc/index.php?topic=84897.0 Also power from the USB port like in the documentation until you get it working. 9 volt batteries are not very good at supplying the needed power.
  • murraylmurrayl Posts: 9
    edited 2013-11-27 15:18
    Franklin wrote: »
    Don't know if this will help but, http://forum.arduino.cc/index.php?topic=84897.0 Also power from the USB port like in the documentation until you get it working. 9 volt batteries are not very good at supplying the needed power.

    I went through the data sheet of the proc and the altimeter module and from what I can see, all the addresses are correct and the values being written look write. The debug code seems to indicate that there is no data coming back from the part. When it tries to read the coeffcients from the part, there are zero bytes in the rxbuffer for the Wire object.
    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) <<<<<<<<<<<<<< This is zero.
    {
    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()"); <<<<< I'm hitting this. Leads me to the conclusion the part is not answering.
    }
    #endif
  • FranklinFranklin Posts: 4,747
    edited 2013-11-28 14:37
    Two things try
    while( Wire.avaliable);
    
    and include all your code using the [code] tag option.
  • murraylmurrayl Posts: 9
    edited 2013-11-29 13:19
    I really appreciate the suggestions Franklin, it was a good one. Unfortunately the same effects.
    I put in a loop before the code in question while (Wire.available()==0); and the code stops hung there forever (no data incoming).
    I verified that I never saw any data coming in. Below the code, I'm showing the output when the while loop is not present, (once again no data back from part.)
    I am going to try to find time at work on Monday to hook up an oscilliscope and see if I can see the I2C requests going out (to verify it isn't a problem with the UNO board itself.
    I am hoping you see something obvious in the code, but since it has worked for others, my assumption is that it is my hardware.
    // 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"
    
    #define DEBUG 1
    
    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));
            Serial.println("Waiting for Data available from Altimeter Part");
            
            while (Wire.available()== 0);
           
            Serial.print("Bytes: ");
            Serial.println(Wire.available(),DEC);
            Serial.print("i2cAddr_: ");
            Serial.println(i2cAddr_,HEX);
            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
    
    

    Output if I don't have the while 1 loop waiting on data.
    i2cAddr_: 76
    No data available in ReadCoefficient()
    Coefficient 1 : 0
    Coefficient 2 : 0
    Coefficient 3 : 0
    Coefficient 4 : 0
    Coefficient 5 : 0
    Coefficient 6 : 0
    0
    0
    No data available in cmdAdc()
    No data available in cmdAdc()
    pressure: 0, pressConv: 0, temperature: 0
    No data available in cmdAdc()
    No data available in cmdAdc()
    pressure: 0, pressConv: 0, temperature: 0
    No data available in cmdAdc()
    No data available in cmdAdc()
    pressure: 0, pressConv: 0, temperature: 0
    No data available in cmdAdc()
    No data available in cmdAdc()
    pressure: 0, pressConv: 0, temperature: 0
    Centimeters: 1166.00, Feet: 38.25
  • FranklinFranklin Posts: 4,747
    edited 2013-11-29 13:26
    [COLOR=#333333][FONT=Parallax]while (Wire.available()== 0);
    
    Why are you adding the condition to the command? Try it just as I posted it and see what happens. Also what board are you writing this for and which compiler?[/FONT][/COLOR]
  • GordonMcCombGordonMcComb Posts: 3,366
    edited 2013-11-30 18:47
    When you say you've downloaded the Arduino 1.0 code from the Parallax site next to the picture for the Uno, which page is this exactly? The version of the InterSema Baro file you posted is not the version included with the basic demo on the Parallax Learn site:

    http://learn.parallax.com/KickStart/29124

    The Learn site version is known to return raw values that will at least demonstrate proper wiring and operation of the board.

    There's no need to power your Uno with a 9V battery if you're connected to a PC via USB and relying on debugging through the Serial window. The board will derive its power from USB, which is generally a more reliable power source.

    Franklin, your code and the code in the Intersema class are opposite. They are doing do-nothing loops until the Wire buffer is not empty. Murray mentioned it's an Uno board and the 1.0.5 Arduino IDE.
  • murraylmurrayl Posts: 9
    edited 2013-12-12 10:41
    Franklin wrote: »
    [COLOR=#333333][FONT=Parallax]while (Wire.available()== 0);[/FONT][/COLOR]
    

    Why are you adding the condition to the command? Try it just as I posted it and see what happens. Also what board are you writing this for and which compiler?
    I posted before, but for some reason it didn't show up.
    The reason I changed the code is of the way that Wire.available() works. It returns the number of bytes waiting in the RX buffer. So if there is nothing waiting in the RX buffer (which there is zero bytes) then the command while(Wire.available()) will always return zero (false) and you will immediately drop out of the loop. If there is data in the buffer you will loop there forever since no one will read it. (Because you are blocking before the read code below it.)
    The code while (Wire.available()==0) will wait in a tight loop until some data has arrived, then drop out, and go into the routines below.
    Also from some of my reading, it looks like the read routines are blocking with a timeout and so should be adequate to the task.
    I had put the code in with the hope that it was a timing problem and waiting until data is ready would help.
    From my reading it isn't necessary. See more in the response below to Gordon.
  • murraylmurrayl Posts: 9
    edited 2013-12-12 11:02
    When you say you've downloaded the Arduino 1.0 code from the Parallax site next to the picture for the Uno, which page is this exactly? The version of the InterSema Baro file you posted is not the version included with the basic demo on the Parallax Learn site:

    http://learn.parallax.com/KickStart/29124

    [LRM] It is the code you get when you push the button "Download Arduino 1.0 code for the Altimeter module" Since I am using the 1.0.5 IDE, this seems the appropriate code.

    The Learn site version is known to return raw values that will at least demonstrate proper wiring and operation of the board.

    There's no need to power your Uno with a 9V battery if you're connected to a PC via USB and relying on debugging through the Serial window. The board will derive its power from USB, which is generally a more reliable power source.
    [LRM] Yes, I only did this briefly as it was unclear whether USB would power properly. The external power statements about the UNO say the input voltage needs to be 7V or higher to ensure the output from the regulator is 5V. As it turns out even though the USB is only 5.0V the +5 rail seems to be solidly 5V when powered by the USB so I got rid of external power for the time being. Doesn't matter either way as the rail is solidly 5V with either solution. If it was inadequate, the 5V rail would drop and you'd know that was the problem.

    Franklin, your code and the code in the Intersema class are opposite. They are doing do-nothing loops until the Wire buffer is not empty. Murray mentioned it's an Uno board and the 1.0.5 Arduino IDE.

    [LRM] I did further testing the other day. I put it on an oscilloscope. I can see the I2C signal coming out of the Arduino UNO fine. I decoded the serial data stream and it appears to be correct. I see the reset sequence, followed after a while by the EEPROM read sequence. I don't see anything after the EEPROM read (to get the calibration constants) although it's possible the delay is too great for the scope trigger to catch it, but since there is no micro I would think the response would be almost immediate (i.e. a pure memory read). As far as I can tell I'm not seeing a peep from the altimeter. One other oddity is that in the datasheet for the chipset, it says the EEPROM data will come out on SDO. They show the data being clocked out on SDO in the clock / data diagram. I'm assuming since people have it working they tied SDO/SDI together on the board.
    So as far as I can see here is my analysis. It is one of the following:
    - Bad altimeter board: I ordered another and it is in route. If mine is zapped this will solve the problem.
    - Wrong Address: address I see used is 0x76 which looks right, and matched what I saw on the oscilloscope but there is one pin that has to match the way a pin is tied on the board. The PS (protocol select) has to be high to select I2c. It also calls out that in I2C mode that the CSB pin should be connected either to VDD or GND but don't leave it unconnected. It may be CSB is floating and not matching up. CSB allows a chip select line if you have multiple chips on the bus.
    - Code has a problem: Since others have it working, this is least likely.
  • murraylmurrayl Posts: 9
    edited 2014-01-08 11:36
    Any Suggestions anybody?
  • jim N8RHQjim N8RHQ Posts: 85
    edited 2014-01-08 17:31
    I struggled for two weeks trying to get my Uno to talk/listen to the 29124 Altimeter module. Somewhere on one of the Arduino forums, I found a similar problem. The solution seems to be using 3.3v for the supply, especially when using I2C apparently. I switched from 5v to 3.3v and now it works pretty good. I've attached my code for reference. I am not very proficient with the Arduino, so my code may be a little rough. But it does have the advantage of working without including IntersemaBaro.h. Setup is an Uno, Ethernet shield, sd card, and 29124 sensor. Program is designed to read the sensor, write data to sd card, and serve the data to an Ethernet connection if there is one. I hope this helps.

    jim

    //
    //changed to using 3.3v for power and this works great as of 1/1/14
    //reads sensor, displays to monitor, writes to card
    //responds to network
    //

    #include <SD.h>
    #include <SPI.h>
    #include <Ethernet.h>

    #include <Wire.h>
    #define ADDRESS 0x76
    const int chipSelect = 4;

    uint32_t D1 = 0;
    uint32_t D2 = 0;
    int64_t dT = 0;
    int32_t TEMP = 0;
    int64_t OFF = 0;
    int64_t SENS = 0;
    int32_t P = 0;
    uint16_t C[7];

    float Temperature;
    float Pressure;
    float f;
    // Enter a MAC address and IP address for your controller below.
    // The IP address will be dependent on your local network:
    byte mac[] = {
    0x90, 0xA2, 0xDA, 0x00, 0xD8, 0x83 };
    IPAddress ip(192,168,15,33);

    // Initialize the Ethernet server library
    // with the IP address and port you want to use
    // (port 80 is default for HTTP):
    EthernetServer server(80);

    void setup() {
    // Disable internal pullups, 10Kohms are on the breakout
    PORTC |= (1 << 4);
    PORTC |= (1 << 5);
    Wire.begin();
    Serial.begin(9600);
    delay(100);
    initial(ADDRESS);
    Serial.print("Initializing SD card...");
    // make sure that the default chip select pin is set to
    // output, even if you don't use it:
    pinMode(10, OUTPUT);
    // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    //return;
    }
    // start the Ethernet connection and the server:
    Ethernet.begin(mac, ip);
    server.begin();
    Serial.print("server is at ");
    Serial.println(Ethernet.localIP());

    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    //File dataFile = SD.open("datalog.txt", FILE_WRITE);
    delay(1000);
    delay(5000);
    }//end of setup loop here

    void loop()
    {
    compute();
    output();
    // listen for incoming clients
    EthernetClient client = server.available();
    if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
    if (client.available()) {
    char c = client.read();
    Serial.write(c);
    // if you've gotten to the end of the line (received a newline
    // character) and the line is blank, the http request has ended,
    // so you can send a reply
    if (c == '\n' && currentLineIsBlank) {
    // send a standard http response header
    client.println("HTTP/1.1 200 OK");
    client.println("Content-Type: text/html");
    client.println("Connection: close"); // the connection will be closed after completion of the response
    client.println("Refresh: 5"); // refresh the page automatically every 5 sec
    client.println();
    client.println("<!DOCTYPE HTML>");
    client.println("<html>");
    // output the value of each
    client.print("Temperature is ");
    client.print(f);
    client.println(" F,");
    client.print("Pressure is ");
    client.print(Pressure);
    client.print(" mb");
    client.println("<br />");
    client.println("</html>");
    break;
    }
    if (c == '\n') {
    // you're starting a new line
    currentLineIsBlank = true;
    }
    else if (c != '\r') {
    // you've gotten a character on the current line
    currentLineIsBlank = false;
    }
    }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
    }delay(15000); //should make writes to card every 15 sec
    }

    long getVal(int address, byte code)
    {
    unsigned long ret = 0;
    Wire.beginTransmission(address);
    Wire.write(code);
    Wire.endTransmission();
    delay(10);
    // start read sequence
    Wire.beginTransmission(address);
    Wire.write((byte) 0x00);
    Wire.endTransmission();
    Wire.beginTransmission(address);
    Wire.requestFrom(address, (int)3);
    if (Wire.available() >= 3)
    {
    ret = Wire.read() * (unsigned long)65536 + Wire.read() * (unsigned long)256 + Wire.read();
    }
    else {
    ret = -1;
    }
    Wire.endTransmission();
    return ret;
    }

    void initial(uint8_t address)
    {
    Serial.println();
    Serial.println("PROM COEFFICIENTS ivan");

    Wire.beginTransmission(address);
    Wire.write(0x1E); // reset
    Wire.endTransmission();
    delay(10);
    for (int i=0; i<6 ; i++) {
    Wire.beginTransmission(address);
    Wire.write(0xA2 + (i * 2));
    Wire.endTransmission();
    Wire.beginTransmission(address);
    Wire.requestFrom(address, (uint8_t) 6);
    delay(1);
    if(Wire.available())
    {
    C[i+1] = Wire.read() << 8 | Wire.read();
    }
    else {
    Serial.println("Error reading PROM 1"); // error reading the PROM or communicating with the device
    }
    Serial.println(C[i+1]);
    }
    Serial.println();
    }

    void compute(){
    D1 = getVal(ADDRESS, 0x48); // Pressure raw
    D2 = getVal(ADDRESS, 0x58);// Temperature raw
    dT = D2 - ((uint32_t)C[5] << 8);
    OFF = ((int64_t)C[2] << 16) + ((dT * C[4]) >> 7);
    SENS = ((int32_t)C[1] << 15) + ((dT * C[3]) >> 8);
    TEMP = (int64_t)dT * (int64_t)C[6] / 8388608 + 2000;

    if(TEMP < 2000) // if temperature lower than 20 Celsius
    {
    int32_t T1 = 0;
    int64_t OFF1 = 0;
    int64_t SENS1 = 0;
    T1 = pow(dT, 2) / 2147483648;
    OFF1 = 5 * pow((TEMP - 2000), 2) / 2;
    SENS1 = 5 * pow((TEMP - 2000), 2) / 4;

    if(TEMP < -1500) // if temperature lower than -15 Celsius
    {
    OFF1 = OFF1 + 7 * pow((TEMP + 1500), 2);
    SENS1 = SENS1 + 11 * pow((TEMP + 1500), 2) / 2;
    }
    TEMP -= T1;
    OFF -= OFF1;
    SENS -= SENS1;
    }

    Temperature = (float)TEMP / 100;
    f = round(Temperature*9.0/5.0 +32.0);

    P = ((int64_t)D1 * SENS / 2097152 - OFF) / 32768;
    Pressure = (float)P / 100;
    }

    void output(){
    Serial.print(" Actual TEMP= ");
    Serial.print(f);
    Serial.print(" F Actual PRESSURE= ");
    Serial.print(Pressure);
    Serial.println(" mb");
    Serial.print("D2 RAW (Temp)= ");
    Serial.print(D2);
    Serial.print(" D1 RAW (Pressure)= ");
    Serial.println(D1);
    Serial.println();
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    dataFile.print("Actual TEMP= ");
    dataFile.print(f);
    dataFile.print(" F, Actual PRESSURE= ");
    dataFile.println(Pressure);
    dataFile.print(" mb");
    dataFile.close();

    }
  • murraylmurrayl Posts: 9
    edited 2014-01-14 17:01
    I noted you are includuing SPI.h, are you using the I2C interface or SPI for the Altimeter. Didn't know if it was included due to one of the other peripherals rather than the Altimeter.
  • jim N8RHQjim N8RHQ Posts: 85
    edited 2014-01-15 06:43
    I'm using I2C for the altimeter. SPI.h is included because it's being used to talk to the Ethernet shield and handle IP connections. I'm planning to try again using only SPI for the altimeter AND the Ethernet. If that works, it should be a lot smaller and make room for some expanded functionality. If you've compiled the above code, you've probably noticed it's very nearly at the max limit.
  • murraylmurrayl Posts: 9
    edited 2014-01-15 15:58
    I did try your code and got the same response, nothing from the altimeter.
    I tried a 2nd altimeter to see if it was damaged, no joy.

    As for your 3.3v comment, did you get any data back from the altimeter at all when you were using 5V?
    It should be 5V tolerant.
    Also did you change the power and data levels, or just supply 3.3V to the power rails?

    Also one thing that still bothers me is when I put it on the oscilliscope, I didn't see the Arduino clocking the data out after sending the command. I could see the command going out on I2C, but then I expected to see it clocking to read and the altimeter as a slave would send back data.
  • jim N8RHQjim N8RHQ Posts: 85
    edited 2014-01-15 16:23
    When I was running 5v, it was returning a number that never changed, so I wasn't sure exactly where the problem was. If I remember correctly, I don't think I had to change any code after switching to 3.3v for the supply to get it to work. I know the specs say it's good for 5v. Maybe it is. I'm just relating my experience and suggesting you try 3.3v for the supply.
  • GordonMcCombGordonMcComb Posts: 3,366
    edited 2014-01-16 14:19
    You might try 5V and specifically adding a low-value pull-up resistor to both SCL and SDA -- maybe 1.8k or so. As I recall, the altimeter is designed to not require external pullups, but for the Arduino and I2C, it sometimes makes a difference.
  • aparis1983aparis1983 Posts: 22
    edited 2014-01-21 08:31
    You might want to consider sending back the sensor. I bought the Parallax altimeter MS5607 to be used with a propeller BOE and I was getting ridiculous reading of 3000 meters below sea level. After a month of troubleshooting I decided to send it back. The people at parallax had it tested and found out the sensor was assembled incorrectly. They sent me a new one and it worked perfectly.
  • murraylmurrayl Posts: 9
    edited 2014-01-21 18:30
    Thanks! I found the prime problem. I put it on a breadboard and shortened up the traces to a few inches. Apparently a foot long test lead is too long for the arduino to drive the bus. I'm surprised because we have boards with longer i2c traces. As soon as I put it the breadboard it started reading data. I know it was getting there as I'd used the oscilloscope attached to the pins on the altimeter. Also I had purchased a 2nd altimeter chip to see if it wold make any difference. It didn't. I'm suprised the bus won't drive further. It's really low speed.

    It now at least works and I can read back data from it.

    The only problem is it is reading off by about 1000 feet.
    It seems to be following the movement up/down.
    The barometric pressure doesn't agree with the national weather service pressure either. i.e. It seems to be reading off valid data that is incorrect.

    I'm going to try the other original sensor tonight to see if it works any better.

    I've used two different pieces of code written by two different people. Both worked, had similar pressure readings, the same temp readings, and both pressure readings were off from the locally measured barometric pressure.

    I also did the measurements with the sensor in a dark environment since it's marked light sensitive. I assume it has some impact on the measurements.

    Les.
Sign In or Register to comment.