Arduino Forum

Forum 2005-2010 (read only) => Software => Troubleshooting => Topic started by: maca_404 on Oct 12, 2008, 03:50 pm

Title: i2c Pressure Sensor
Post by: maca_404 on Oct 12, 2008, 03:50 pm
Hi

    Firstly thanks for the great forums have learned so much already. I am working with the HP03 pressure sensor and not having much luck with reading anything off it. Here is the data sheet for it.

http://www.oceancontrols.com.au/Sensors/pressure/HP03.pdf


I have read threw the i2c playground and several other example and they seem to have only confused me more.  I would like to know if anyone has an example for reading from this actual device or might be able to point me in the right direction.

Any help you can give me would be greatly appreciated.


Title: Re: i2c Pressure Sensor
Post by: mem on Oct 12, 2008, 05:00 pm
Here is a library I use for the HP03 pressure sensor. This code works for me but has only been run with a modified wire library on Arduino version 0011. It should be ok with the standard 0012 wire library, but not yet tested.
test sketch:
Code: [Select]

// HP03 test sketch
// Created 11 July 2008

#include <HP03.h>
#include <FrequencyTimer2.h>
#include <Wire.h>

// note that the HP03 code uses digital pin 11 for the clock and analog pins 4 and 5 for I2C

unsigned long start;
 
void setup()
{
 Serial.begin(19200);  // start serial for output  
 if(HP03.begin() == false)
   Serial.println("Error getting HP03 calibration, check sensor connection");

 for(long p = 1100; p >=310; p-= 50){
   Serial.print("pressure ");
   Serial.println(p,DEC);
   HP03.distanceUnits = METERS;
   Serial.print("   Altitude, Meters = ");
   printFloat( HP03.getAltitude(p * 100L) /10.0, 1);
   Serial.println();
   HP03.distanceUnits = FEET;
   Serial.print("   Altitude, Feet  = ");
   printFloat( HP03.getAltitude(p * 100L), 2);
   Serial.println();
   
 }
 start = millis();
 HP03.distanceUnits = METERS;
}



void loop()
{    
 if(HP03.update() == false)
   Serial.println("Error getting HP03 data, check sensor connection");
 else {  
   int dur = millis() - start;  // calculate conversion time
   output('T', HP03.Temperature/10.0, 1);  
   output('P', HP03.Pressure/100.0, 2);  
   output('A', HP03.getAltitude(HP03.Pressure)/10.0, 1);
   output('C',dur,0); // conversion time in ms
 }
  start = millis();  
}

void output( char tag, float value, int decimalPlaces){
//send the value to the serial port with the given tag, format using given number of decimal places
 Serial.print('>');   // this is our message start indicater
 Serial.print(tag);
 Serial.print('=');
 printFloat(value,decimalPlaces);
 Serial.println();
}

void printFloat( float val, byte decimalPlaces){
// prints val with the given number of decimal places
unsigned int precision;
 Serial.print( (long)val );  //prints the integer part
 if(decimalPlaces != 0){
   Serial.print("."); // print the decimal point
   for(precision=1; decimalPlaces--; precision *= 10)
       ;
   unsigned int frac;
   if(val >= 0)
       frac = (val - int(val)) * precision;
   else
       frac = (int(val)- val ) * precision;
   Serial.print(frac,DEC) ;
 }
}

HP03.h header file to go into the library directory
Code: [Select]

/*
 HP03.h - Arduino library support for HP03 Pressure sensor
 Copyright (c)2008 Michael Margolis All right reserved

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 Version:   1.0 - July14 2008
 
*/

#ifndef      HP03_H
#define HP03_H

typedef unsigned char boolean;

/*
 define some constants for errors based on the return values
 of the functions in utility/twi.c
*/
#define WIRE_OK 0
#define WIRE_ERR_NO_BUFFER_SPACE 1
#define WIRE_ERR_BAD_ADDRESS 2
#define WIRE_ERR_NOT_IN_TRNSMISSION_MODE 2
#define WIRE_ERR_DATA_NO_ACK 3
#define WIRE_ERR_BUS 4

typedef enum distanceUnits_t {METERS, FEET};

class HP03class  // shell class for HP03 glcd code
{
 private:
    // methods to send and receive data via I2C
    int i2cTransfer(unsigned char Address, const unsigned char *TxBuf, int TxBytes, unsigned char *RxBuf, int RxBytes);
    int i2cSendCommand(unsigned char Address, unsigned char Command);
    int i2cMeasure(unsigned char SubType);
    int i2cResult(unsigned int *Result);
 public:
   HP03class();
     float Temperature;
   float Pressure;
   long   Altitude;
     unsigned int rawPressure;     // D1 - raw values are only for test purposes
   unsigned int rawTemperature;  // D2  
   distanceUnits_t distanceUnits;   // METERS or FEET
   boolean begin( void );
   boolean getCalibrationData();
#ifdef PRINT_CALIBRATION_DATA
   void HPO3class::printCalibrationData();
#endif
   boolean update();
   boolean readRawData();
   void calculatePressureAndTemperature();
   long getAltitude(long pressure);  //pressure is 100 times what it should be
};

extern HP03class HP03;    
#endif

The cpp file is in the next post

Title: Re: i2c Pressure Sensor
Post by: mem on Oct 12, 2008, 05:08 pm
Code: [Select]
/*
 HP03.cpp - Arduino library support for HP03 Pressure sensor
Copyright (c)2008 Michael Margolis All right reserved

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 Version:   1.0 - July14 2008
*/

// Note that this code uses the return values in Arduino version 0012 wire.c library


extern "C" {
#include <avr/pgmspace.h>
#include <wiring.h>
#include <FrequencyTimer2.h>
#include <Wire.h>
}
#include "HP03.h"

#if !defined(NULL)
#define NULL 0
#endif

// #define PRINT_CALIBRATION_DATA  //undefine these to print low level data for debug purposes

// I2C defines
#define MCLK_pin 16   // Arduino uses analog pins 4 and 5 for I2C
#define XCLR_pin 17

#define HP03_I2C_SENSOR_ADDRESS 0x77
#define HP03_I2C_CALIBRATION_ADDRESS 0x50
#define HP03_MEASURE_COMMAND     0xff
#define HP03_RESULT_COMMAND      0xfd
#define HP03_PRESSURE_SUBTYPE    0xf0
#define HP03_TEMPERATURE_SUBTYPE 0xe8
#define HP03_RESULT_SUBTYPE      0xef

// macro to convert two bytes in an arrya to an int
#define GET_BIGENDIAN_WORD(x, y) ((((unsigned int)x[y]) << 8) | x[y+1])

// Pressure to altitude conversion defines
#define MAX_PRESSURE         1100L  // in Hpa
#define PRESSURE_ARRAY_ELEMS 80     // number of elements in pressure array
#define PRESSURE_INC         10L    // 10Hpa between array values in altitude table

#define HP03_NUM_COEFF 7
#define HP03_NUM_PARAMS 4

enum coefficients { C1,C2,C3,C4,C5,C6,C7};
enum params       { AA,BB,CC,DD};

unsigned int coeff[HP03_NUM_COEFF];  // these are marked C1 through C7 in the datasheet
byte  sensorParams[HP03_NUM_PARAMS];  // these are marked a,b,c,d in the datasheet

long int pow2(byte value){ // return value raised to the power of 2    
 long uiData = 2;  
 while(--value){
   uiData <<= 1;        
 }
 return uiData;
}

//********* I2C functions ******************
int HP03class::i2cTransfer(unsigned char Address, const unsigned char *TxBuf, int TxBytes, unsigned char *RxBuf, int RxBytes){
 // send bytes to the given address and receive bytes from that address
 int ret = WIRE_OK;    

 if(TxBytes > 0){    // send data if TxBytes greater than 0
   if(TxBytes > BUFFER_LENGTH)
     ret = WIRE_ERR_NO_BUFFER_SPACE ;
   else{      
     Wire.beginTransmission(Address); // transmit to device            
     while(TxBytes--){  
       Wire.send(*TxBuf++);        
     }
     ret = Wire.endTransmission();    // stop transmitting      
   }
 }
 if (RxBytes > 0 && ret == WIRE_OK){  // receive given number of byts if send ok
   Wire.requestFrom(Address, (uint8_t)RxBytes);
   while(Wire.available() && RxBytes--)
   {
     char c = Wire.receive();
     *RxBuf++ = c;
   }        
 }  
 return ret;
}

int HP03class::i2cSendCommand(unsigned char Address, unsigned char Command){
 Wire.beginTransmission(Address); // transmit to device  
 Wire.send(Command);            
 return Wire.endTransmission();    // stop transmitting  
}

int HP03class::i2cMeasure(unsigned char SubType){
//   Start a measurement on the HP03, returns WIRE_OK on success else WIRE error code
 unsigned char TxBuf[2];

 TxBuf[0] = HP03_MEASURE_COMMAND;
 TxBuf[1] = SubType;

 return i2cTransfer(HP03_I2C_SENSOR_ADDRESS, TxBuf, sizeof(TxBuf), NULL, 0);
}

int HP03class::i2cResult(unsigned int *Result){
//   Get a measurement result from the HP03, returns WIRE_OK on success else WIRE error code
 unsigned char TxBuf[2];
 unsigned char RxBuf[2];
 int Status;

 TxBuf[0] = HP03_RESULT_COMMAND;
 TxBuf[1] = HP03_RESULT_SUBTYPE;

 Status = i2cTransfer(HP03_I2C_SENSOR_ADDRESS, TxBuf, sizeof(TxBuf), RxBuf, sizeof(RxBuf));

 *Result = (RxBuf[0] << 8) | RxBuf[1];

 return Status;
}

 HP03class::HP03class(){
 }

boolean HP03class::begin( void ){
 // set control pins for output
 pinMode(MCLK_pin, OUTPUT);
 pinMode(XCLR_pin, OUTPUT);    
 digitalWrite(XCLR_pin,LOW) ;
 
 /* set up TIMER2 to 32768Hz with 50/50 mark/space ration with output on  */
 pinMode(11,OUTPUT);  // frequencyTimer2 is hard coded to output on this pin
 FrequencyTimer2::setPeriod(31); // 31us = 32258hz
 FrequencyTimer2::enable();
 Wire.begin();
 return getCalibrationData();  // returns true if ok, if false then probably sensor not detected
}

boolean HP03class::getCalibrationData(){
 // read the calibration values from the sensor, return true if ok, false if error  
 unsigned char CalData[18];
 boolean ret;

 ret = (i2cSendCommand(HP03_I2C_CALIBRATION_ADDRESS, 16) == WIRE_OK);
 if (ret == true){
   if(i2cTransfer(HP03_I2C_CALIBRATION_ADDRESS, NULL, 0, CalData, sizeof(CalData)) == WIRE_OK) {
     for (int i = 0; i < HP03_NUM_COEFF; i++)    
       coeff[i] = GET_BIGENDIAN_WORD(CalData, i*2);

     for (int i = 0; i < HP03_NUM_PARAMS; i++)  
       sensorParams[i] = CalData[( HP03_NUM_COEFF * sizeof(int)) + i];
     ret = true;
   }
 }
#ifdef PRINT_CALIBRATION_DATA
  printCalibrationData();
#endif  
 return ret;
}
#ifdef PRINT_CALIBRATION_DATA
void HP03class::printCalibrationData(){
 int Count;
 for (Count = 0; Count < HP03_NUM_COEFF; Count++)  {  
   Serial.print("Coeff C");
   Serial.print((char)('1' + Count));
   Serial.print(" = ");
   Serial.println((unsigned long)coeff[Count],DEC);
 }
 for (Count = 0; Count < HP03_NUM_PARAMS; Count++)  {
   Serial.print("Param");
   Serial.print((char)('A' + Count));
   Serial.print(" = ");
   Serial.println( (unsigned)sensorParams[Count],DEC);
 }
 Serial.println();
}
#endif

boolean HP03class::update(){
  if(readRawData()){
     calculatePressureAndTemperature();
     return true;  
  }  
  return false;
}

boolean HP03class::readRawData(){
 digitalWrite(XCLR_pin,HIGH);
 // send temperature measurement command
 if ( i2cMeasure(HP03_TEMPERATURE_SUBTYPE) != WIRE_OK) {
   digitalWrite(XCLR_pin,LOW);
   return false;
 }
 delay(40);
 if( i2cResult(&rawTemperature) != WIRE_OK){
   digitalWrite(XCLR_pin,LOW);
   return false;
 }
 if (i2cMeasure(HP03_PRESSURE_SUBTYPE) != WIRE_OK) {
   digitalWrite(XCLR_pin,LOW);
   return false;
 }
 delay(40);
 if( i2cResult(&rawPressure) != WIRE_OK){
    digitalWrite(XCLR_pin,LOW);
    return false;
 }
 return true;  
}

void HP03class::calculatePressureAndTemperature(){
 double MiddleData1;
 double MiddleData2;
 double MiddleData3;
 double MiddleData4;
 double dUT;
 double SENS;
 double OFF;
 double X;
     
 MiddleData1 = (long)rawTemperature - coeff[C5];
 MiddleData2 = MiddleData1 * MiddleData1/16384;
 if(rawTemperature < coeff[C5])  
    MiddleData3 = MiddleData2 * sensorParams[BB];
 else
    MiddleData3 = MiddleData2 * sensorParams[AA];
 MiddleData4 = pow2(sensorParams[CC]);
 MiddleData4 = MiddleData3 / MiddleData4;
 dUT = MiddleData1 - MiddleData4;

 //OFF = (C2+(C4-1024)*DUT/Get2_x(14))*4;
 MiddleData1 = (long)coeff[C4] - 1024L;
 MiddleData2 = pow2(14);
 MiddleData3 = dUT * MiddleData1;
 MiddleData4 = MiddleData3 / MiddleData2;
 MiddleData4 = (long)coeff[C2] + MiddleData4;
 OFF = MiddleData4 * 4;

 //SENS = C1+C3*DUT/Get2
 MiddleData1 = (long)coeff[C3] * dUT;
 MiddleData2 = pow2(10);
 MiddleData3 = MiddleData1 / MiddleData2;
 SENS = coeff[C1] + MiddleData3;

 //X = SENS*(D1-7168)/ Get2_x(14)-OFF;
 MiddleData1 = pow2(14);
 MiddleData2 = (long)rawPressure - 7168;
 MiddleData3 = MiddleData2 * SENS;
 MiddleData4 = MiddleData3 / MiddleData1;
 X = MiddleData4 - OFF;  

  //Pressure = X*100/Get2_x(5)+C7*10;
 MiddleData1 = X * 100;
 MiddleData2 = pow2(5);
 MiddleData3 = MiddleData1 / MiddleData2;
 MiddleData4 = coeff[C7] * 10;
 Pressure = MiddleData3 + MiddleData4;

 Temperature = 250 + dUT * coeff[C6] / pow2(16) - dUT / pow2(sensorParams[DD]);
}

static prog_int32_t BasicAltitude[PRESSURE_ARRAY_ELEMS] PROGMEM = {
-6983,-6201,-5413,-4620,-3820,-3015,-2203,-1385,-560, 270, //0.1m
 1108, 1953, 2805, 3664, 4224, 5403, 6284, 7172, 8068, 8972,
 9885, 10805,11734,12671,13617,14572,15537,16510,17494,18486,
 19489,20502,21526,22560,23605,24662,25730,26809,27901,29005,
 30121,31251,32394,33551,34721,35906,37106,38322,39553,40800,
 42060,43345,44644,45961,47296,48652,50027,51423,52841,54281,
 55744,57231,58742,60280,61844,63436,65056,66707,68390,70105,
 71854,73639,75461,77323,79226,81172,83164,85204,87294,89438};

long altitudeValue_P(int address){
// return the value of the altitude table
 return pgm_read_dword(&BasicAltitude[address]  );
}

long  HP03class::getAltitude(long pressure){  //pressure is 100 times what it should be
  int index;
  long AltitudeDifference,PressureDifference;
  long fraction;
  long alt;

  index = (MAX_PRESSURE - pressure/100) / PRESSURE_INC + 1;
  if (index >= PRESSURE_ARRAY_ELEMS)
       index = PRESSURE_ARRAY_ELEMS-1;

  AltitudeDifference =  altitudeValue_P(index) - altitudeValue_P(index-1);
  PressureDifference = pressure - ((MAX_PRESSURE - (index* PRESSURE_INC))*100);
  fraction = (AltitudeDifference *1000) - (PressureDifference  * AltitudeDifference)    ;
  alt = ((altitudeValue_P(index-1) * 10)  + (fraction/100))/10;
  if(distanceUnits == METERS)
      return alt;
   else
      return  (long)(alt * 0.328084);
}
HP03class HP03 = HP03class();
Title: Re: i2c Pressure Sensor
Post by: maca_404 on Oct 12, 2008, 11:59 pm
Thanks so much for the info.  I have put all the libraries etc in but am getting some errors when trying to compile.

Code: [Select]

In file included from C:\arduino-0012\hardware\cores\arduino/WProgram.h:4,


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected unqualified-id before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected `)' before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:80: error: expected `)' before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected unqualified-id before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected identifier before '(' token


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected `)' before '(' token


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected ',' or '...' before '(' token


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:144: error: expected initializer before ')' token


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:176: error: '__compar_fn_t' has not been declared


In file included from C:\arduino-0012\hardware\cores\arduino/WProgram.h:6,




I have confirmed that other programs are compiling ok so could this be something to do with the mod wire library you where talking about ?.  It is prb just something I have done wrong when copying it over but  it is strange as it does not seem to be referring to any of the new includes.

P.s  Im still very new at all this  ;)
Title: Re: i2c Pressure Sensor
Post by: mem on Oct 13, 2008, 04:08 am
hmm, to test I copied the files posted back onto my computer and they compile ok for me. Are you using the test sketch I posted? Are HP03.h and HP03.cpp copied to a directory called HP03 in the hardware/libraries directory? (Note there are three files named HP03.pde, HP03.H and the third needs to be called  HP03.cpp)
Title: Re: i2c Pressure Sensor
Post by: mikalhart on Oct 13, 2008, 04:42 am
Mem, I *haven't* tried this code, but these are exactly the types of errors (stdlib.h:80) that people get when compiling old libraries with 0012.  My guess is that it works for you because you disabled or undefined those pesky "function-style" cast macros in wiring.h"?  If so, perhaps you'd care to share your method?

Mikal
Title: Re: i2c Pressure Sensor
Post by: mem on Oct 13, 2008, 04:56 am
Thanks Mikal, I had forgotten that I had removed those pesky macros in my working copy of wiring,h.

#ifdef USE_PESKY_MACROS
#define int(x)     ((int)(x))
#define char(x)    ((char)(x))
#define long(x)    ((long)(x))
#define byte(x)    ((uint8_t)(x))
#define float(x)   ((float)(x))
#endif
Title: Re: i2c Pressure Sensor
Post by: mikalhart on Oct 13, 2008, 04:58 am
Right-o!  maca, if you follow mem's example and add the #ifdef/#endif to your copy of wiring.h (effectively removing the five #defines in between), you will probably get happiness.

Mikal
Title: Re: i2c Pressure Sensor
Post by: mem on Oct 13, 2008, 05:02 am
Strange thing is that I just tried re-compiling the code I posted and even with the macros enabled it compiled ok.  hmm?
Title: Re: i2c Pressure Sensor
Post by: maca_404 on Oct 13, 2008, 05:21 am
Thanks for all your help so far guys, I have entered the info listed below and it has def reduced the amount of errors but still will not compile. Now it says

Code: [Select]
In file included from C:\arduino-0012\hardware\cores\arduino/WProgram.h:4,


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected unqualified-id before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/stdlib.h:111: error: expected `)' before 'int'


In file included from C:\arduino-0012\hardware\cores\arduino/WProgram.h:6,


Any ideas on this one ?

Thanks
Title: Re: i2c Pressure Sensor
Post by: mikalhart on Oct 13, 2008, 05:27 am
Yeah, also remove the #define of abs() in wiring.h.

Mikal
Title: Re: i2c Pressure Sensor
Post by: mem on Oct 13, 2008, 05:30 am
Well spotted Mikal, I do have that commented out as well !
Title: Re: i2c Pressure Sensor
Post by: maca_404 on Oct 13, 2008, 05:34 am
Did you mean to remove this

Code: [Select]
#define abs(x) ((x)>0?(x):-(x))

When I remove that I get

Code: [Select]
In file included from C:\arduino-0012\hardware\cores\arduino/WProgram.h:6,


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/math.h:439: error: expected unqualified-id before 'double'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/math.h:439: error: expected `)' before 'double'


c:/arduino-0012/hardware/tools/avr/lib/gcc/../../avr/include/math.h:439: error: expected `)' before 'double'


down to 3 errors  :P
Title: Re: i2c Pressure Sensor
Post by: mem on Oct 13, 2008, 05:39 am
remove this:

#define round(x)     ((x)>=0?(long)((x)+0.5) (long)((x)-0.5))

(although it compiles ok on my system as is)
Title: Re: i2c Pressure Sensor
Post by: maca_404 on Oct 13, 2008, 05:59 am
duh forgot to bring xclear high,  Working perfectly now got lost of lovely data coming threw and looks like rain is on the way  :P.  

Thanks so much for your help both of you have been a wealth of information. Also do you have any idea how accurate these things are in the real world  the temp and pressure are spot on but the altitude is out by about 450m or so, but I guess pressure i Probly not the best way to measure altitude.
Title: Re: i2c Pressure Sensor
Post by: mem on Oct 13, 2008, 09:12 am
Because the pressure is varying with atmospheric conditions, you need to set an offset in the pressure value to correct it to a known altitude (or exact pressure). I may add that function to the library,  but for now you will need to do it in your sketch.

I think my sensor was accurate to around 5 or 10 meters, but its been a while since I designed and tested the library so have forgotten that exact figure.

If you do some tests please do report on your results. I hope you enjoy using the library as much as I enjoyed writing that code.
Title: Re: i2c Pressure Sensor
Post by: msonnabaum on Oct 18, 2008, 06:47 pm
First, thanks so much for all the great information!

I'm using the HP01D and I had the exact same experience as maca_404 getting the code to compile.

I'm a bit new to the arduino though, and I'm not what it means to bring xclear high:

Quote
duh forgot to bring xclear high,  Working perfectly now got lost of lovely data coming threw and looks like rain is on the way


Here is what I'm getting now, which I'm guessing is similar to what maca_404 got at first:
Code: [Select]
Error getting HP01D calibration, check sensor connection
pressure 1100
  Altitude, Meters = -698.2
  Altitude, Feet  = -2291.0
pressure 1050
  Altitude, Meters = -301.5
  Altitude, Feet  = -989.0
pressure 1000
  Altitude, Meters = 110.8
  Altitude, Feet  = 363.0
pressure 950
  Altitude, Meters = 540.2
  Altitude, Feet  = 1772.0
pressure 900
  Altitude, Meters = 988.5
  Altitude, Feet  = 3243.0
pressure 850
  Altitude, Meters = 1457.1
  Altitude, Feet  = 4780.0
pressure 800
  Altitude, Meters = 1948.9
  Altitude, Feet  = 6394.0
pressure 750
  Altitude, Meters = 2466.1
  Altitude, Feet  = 8091.0
pressure 700
  Altitude, Meters = 3012.1
  Altitude, Feet  = 9882.0
pressure 650
  Altitude, Meters = 3590.6
  Altitude, Feet  = 11780.0
pressure 600
  Altitude, Meters = 4206.0
  Altitude, Feet  = 13799.0
pressure 550
  Altitude, Meters = 4865.2
  Altitude, Feet  = 15961.0
pressure 500
  Altitude, Meters = 5574.3
  Altitude, Feet  = 18288.0
pressure 450
  Altitude, Meters = 6343.6
  Altitude, Feet  = 20812.0
pressure 400
  Altitude, Meters = 7185.3
  Altitude, Feet  = 23574.0
pressure 350
  Altitude, Meters = 8117.2
  Altitude, Feet  = 26631.0
Error getting HP01D data, check sensor connection
Error getting HP01D data, check sensor connection
Error getting HP01D data, check sensor connection
Error getting HP01D data, check sensor connection


If anyone can explain this to me, I'd greatly appreciate it!
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 09, 2009, 08:36 am
mem, thank you for posting this library. I was able to compile the sketch under IDE 15 after fuddling with frequencytimer2 library. I have two questions though. I am using Arduino Pro Mini, which is 16MHz instead of 8MHz, and I was wondering if something needs to be changed to account for this. For example, will line 141 in HP03.cpp be still accurate?

 FrequencyTimer2::setPeriod(31); // 31us = 32258hz

Also, I actually have HP02D sensor, which is very similar, but it works with 5V. When comparing the spreadsheets I can see some differences in how the pressure is calculated. Do you happen to have a library for the HP02 sensor as well?

Thanks,
Nick
Title: Re: i2c Pressure Sensor
Post by: mem on Jun 09, 2009, 10:26 am
Hi Nick,  you should not need to change anything to use the code on 16MHz or 8MHz boards, although I have only tested on 16MHz boards. FrequencyTimer2 adjusts to a board specific clock value when it is compiled should produce the correct frequencies for your board.

I have not looked at the HP02D sensor but the HP03 code could be modified to use the calculations needed for that sensor. Unfortunately, its not an easy task and I don't have the time to do this, sorry. The HP03 costs less than $10 from Futurlec so the easiest thing may be to use that module instead of the HP02.
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 09, 2009, 09:06 pm
mem, thanks for the reply. I was trying to avoid using HP03, because it is 3V device. I am prototyping an altitude monitoring system for RC helicopter. I only have 5V rail available there and I am trying to keep the number of components to a minimum (I will need additional 3V regulator and logic level converter if HP03 is used).

Anyway, your library is very well commented, so I will try to make HP02 version. The differences I see so far are in the wait time between readings: 32ms vs 40ms, and in HP02 there are only 5 calibration constants to be read. I will post here if I run into trouble.

Do you know any other low-cost pressure sensor which is easy to integrate with Arduino?

Thanks,
Nick
Title: Re: i2c Pressure Sensor
Post by: mem on Jun 09, 2009, 10:32 pm
Modifying the library to support the hp02 is certainly possible if you are comfortable coding the math needed for the calculations.

But integrating the hp03 is not difficult if your controller board has a 3.3 volt supply (or you can use a couple of diodes to drop the 5 volts line). You can do the logic level conversion with a couple of FETs and a six resistors.

Which is easier depends on whether you are more comfortable working in software or hardware.

Have fun!
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 10, 2009, 07:19 pm
Well, I went ahead yesterday and updated the library. so far no cigar.  Arduino shoots back to the serial port some garbled symbols. Even the normal text sent from the sketch is not recognizable. I wen back to the original library and I see the same thing. Some how the serial communication is not working properly even with the sensor disconnected. I wonder it this has something to do with the fact I am using IDE 15 and Atmega 328. Your thoughts?
Title: Re: i2c Pressure Sensor
Post by: mem on Jun 10, 2009, 07:31 pm
The example sketch posted earlier in this thread uses 19200 baud, have you set that rate in the serial monitor?
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 10, 2009, 08:00 pm
Hm, no, I did not. But I can execute other sketches using this bit rate without any problem.
Title: Re: i2c Pressure Sensor
Post by: mem on Jun 10, 2009, 08:09 pm
Quote
Hm, no, I did not. But I can execute other sketches using this bit rate without any problem.

I am not sure what you are saying. My question was about ensuring the baud rate on the serial monitor viewing the serial data matches the 19200 baud being sent. If the anwswer is no then that is why you are seeing gibberish characters.
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 11, 2009, 12:36 am
OK, I'll check again when I get home. In the mean time I was looking at the sensor spreadsheet and I could not figure out where the following values are coming from:

#define HP03_I2C_SENSOR_ADDRESS 0x77
#define HP03_I2C_CALIBRATION_ADDRESS 0x50

Why 0x77 and 0x50?

Also, I assume the following code refers to PB4(MISO) and PB5(SCK) atmega pins:

#define MCLK_pin 16   // Arduino uses analog pins 4 and 5 for I2C
#define XCLR_pin 17

PB5 (17) on Atmega 328 in Arduino Pro Mini is connected to the green LED via 330 om resistor. I am not getting a good square signal there, so I am using PB3 (pin 15) instead.

In this regards, it would be nice if you could provide the pin connections, as you have them in your setup (Atmega -> HP03)?

Thanks again for your help.

Nick


Title: Re: i2c Pressure Sensor
Post by: mem on Jun 11, 2009, 06:30 am
The Arduino I2C wire library requires that you divide the datasheet address by 2. The HP03 sensor address is 0xEE, which is 0x77 after dividing by 2. See the wire library reference page here: http://www.arduino.cc/en/Reference/Wire

I have not used a Pro Mini, but according to the reference page:  "The Pro Mini has 6 analog inputs, each of which provide 10 bits of resolution (i.e. 1024 different values). Four of them are on the headers on the edge of the board; two (inputs 4 and 5) on holes in the interior of the board. "

MCLK_pin is analog pin 4  
XCLR_pin  is analog pin 5

So the sensor connects to analog pins 4 and 5. Although you don't need the following information, you may be interested in knowing that analog pin 4 is also digital pin 16,  this is physical port PC4 on the controllers chips physical pin numbered 27.
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 11, 2009, 06:23 pm
Wow, this is getting confusing. The analog input 4 and 5 are also marked as SDA and SCL. I thought I need to connect there SDA and SCLK pins from the sensor. If you are saying I need to connect MCLK to analog 4 and XCLR to analog 5, then where the SDA and SCLK go to?

BTW, the serial communication is working now. I found I need to press the reset button, after I start the monitor. Sure enough, the message is 'Error getting HP03 data'. Not surprising, considering the mess with the pins assigment.
Title: Re: i2c Pressure Sensor
Post by: mem on Jun 11, 2009, 06:58 pm
The comment in that code is confusing ( I even forgot what I meant by it)

I2C uses analog pins 4 and 5:
SDA (data line) is on analog input pin 4
SCL (clock line) is on analog input pin 5.

MCLK is on analog pin 2 (the code uses it as digital pin  16)
XCLR is  on analog pin 3 (used as digital pin 17)

I hope that helps with the connections.

BTW, I think the wire library may have been modified slightly since I last ran this code so you if you still get errors, you  may need to fiddle with the wire error return codes.
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 11, 2009, 08:10 pm
Thanks, mem.

In the sketch, there is a comment:

// note that the HP03 code uses digital pin 11 for the clock and analog pins 4 and 5 for I2C

I understand that means MCLK should be connected to digital pin 11 (PB3,  MOSI), but your last comment puts it to analog pin 2 (PC2, ADC2). Which one is the correct assigment?
Title: Re: i2c Pressure Sensor
Post by: mem on Jun 11, 2009, 09:49 pm
The HP03 was so many projects ago I can't remember the pin assignments but suspect that I may have changed from generating the clock within the library using that analog pin to using FrequencyTimer2 which has a hard coded output pin.

Unfortunately, I am travelling for the next week or so and won't be able to check my notes until I get back.  There may also be some clues in the posts earlier in the thread.
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 12, 2009, 04:23 am
No problem. The following line pretty much describes it:
pinMode(11,OUTPUT);  // frequencyTimer2 is hard coded to output on this pin

Just to be sure, I've checked the board with oscilloscope and I confirmed the signal is on pin 11. Resoldered MCLK wire and now I am getting some data back from the sensor.

I wanted to verify the coefficient values, so I uncommented #define PRINT_CALIBRATION_DATA and tried to compile the HP03 library. I've got a bunch of errors about missing references to printCalibrationData().

After some head scratching I moved the definition line before #include "HP03.h" line. This removed some of the errors.

I also replaced

void HPO3class::printCalibrationData();
with
void printCalibrationData();

in the HP03.h file.

That helped and the errors are now reduced to the following:

HP03.cpp: In member function 'void HP03class::printCalibrationData()':
HP03.cpp:174: error: 'Serial' was not declared in this scope
HP03.cpp:177: error: 'DEC' was not declared in this scope

Any idea how to add a reference to Serial here?

Thanks,
Nick
Title: Re: i2c Pressure Sensor
Post by: mem on Jun 12, 2009, 06:49 am
if you include HardwareSerial.h you will get the definitions for Serial and DEC.
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 13, 2009, 02:34 am
Included the reference and the library compiles OK. However, no calibration information is sent to the serial port. Not a big deal, since I am getting some good data back from the sensor - 992 hPa, and 175m altitude, which seems about right . I can move forward with my project now. Thank you again for your help.
Title: Re: i2c Pressure Sensor
Post by: mem on Jun 13, 2009, 01:25 pm
You must remove the initial comment from the following line in HP03.cpp to print the calibration data:
// #define PRINT_CALIBRATION_DATA  //uncomment this to print low level data for debug purposes

Anyway, good to hear you have it working. Why not post the changes needed for the HP02 version for others that want to use this module
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 15, 2009, 07:09 am
Uncommenting that line is the first thing I did, as posted already. Still, no data is sent to the port.

Regarding my HP02 sensor, it turned out it is closer to this spec: http://www.picbasic.org/forum/attachment.php?attachmentid=2040&d=1188053824
which is different from the spreadsheet I was initially working with: http://www.futurlec.com/HP02D.shtml

This is very confusing, since both documents claim to be version 1.0, yet they contain different data.

Reverting back to the original code published here gives me good results with my HP02.
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jun 18, 2009, 08:51 am
mem, do you know if it is possible to speed up the readings from the sensor? Right now it takes 95mS to complete a sensor reading. This gives me approximately 10 readings per second, which might not be enough in my application. Any thoughts?
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 07, 2009, 05:25 pm
hi, i need help.
i'm using the HP03D , compile and works ok. But the readings are not correct, i dont know the correct altitude o pressure on my city, but when start the reading, temperature stars on 29.xx and few minutes later is 36.xx, however the real temperature is about 22 degrees. How calibrate the sensor or what i need to do. Thanks.  Greetings from puebla, Mexico.
Title: Re: i2c Pressure Sensor
Post by: Grumpy_Mike on Jul 07, 2009, 05:45 pm
Quote
do you know if it is possible to speed up the readings from the sensor


The I2C works at 100kHz, I believe it is possible to hack the library and get it to run at 400kHz. There was a post on this a few months back.
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 07, 2009, 06:31 pm
Nikivan, the spec sheet says the conversion time is 35ms and you need some time for all those floating point calculations. Its just a guess, but I would be surprised if  you could more than double the conversion rate, no matter how fast the i2c clock rate.

What is your application and how fast do you need it?

ricarDOGS, not sure what to suggest, can you post a picture of your wiring.
Title: Re: i2c Pressure Sensor
Post by: nikivan on Jul 08, 2009, 12:54 am
mem, my application is an altitude hold function for RC helicopter. So far I have the Arduino generate audio signal which indicates when the helicopter ascends, descends, or it hovers at fixed altitude. My next step is to have the board read a receiver channel (or several channels) and generate a servo impulse. This presents some challenges since the Timer 2 is already taken and I am working at the hardware limits here. Now that you mention the 35mS conversion time, I think 50mS is probably the best time I would ever achieve (after some optimization of the calculations code). This might be OK for my needs.

@ricarDOGS. I also noticed my temperature readings are a little bit high, but not as extreme as yours. Your problem could be as simple as defective sensor.
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 08, 2009, 12:17 pm
nikivan, looks like a fun project, I would like to see more. Why not start a thread in the exhibition area with more info and updates from time to time. I am sure others would also be interested in following progress.

I doubt the HP03 sensor has an output that can be relied on to indicate the distance a heli would move vertically in less than a tenth of a second. Bear in mind that the sensor output is not absolutely stable, mine fluctuated by at least a few feet when sitting on a desk (I can't remember the exact figure, it could have been higher) . If you are primarily looking for tight control of altitude you may want to consider adding an accelerometer through a Kalman filter to drive your altitude control ( I presume you are using a variable pitch head, I would think fixed pitch would not be responsive enough)

If timer2 is used for the 32khz signal, perhaps replace that with an external signal source (a 555 timer may be good enough - plenty of circuits can be found using google)
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 08, 2009, 05:02 pm
i use the files HP03.pde, HP03.h and HP03.ccp. I removed the lines indicates in Post #6,#10,#13. On arduino Duemilanove conected :

Vss-GND
Vdd-3.3V
MCLK-Pin 11
XCLR-Analog 3
SDA.Analog 4
SCL-Analog 5

4,7 uF between 3.3V and GND
10Kohm between 3.3V and SDA

it´s  Right??
I
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 08, 2009, 05:39 pm
The HP03 is not rated for 5 volt operation. I use FET level translators on the I2C pins and simple resistor voltage dividers on the sensor inputs (2.2k and 3.6k resistors).

I posted a diagram the FET level translator here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1225292345/6#6

I never got around to documenting the wiring but FWIW, here is a picture of the mini shield I made to test the sensor
(http://farm3.static.flickr.com/2483/3700855735_01c81d5517.jpg?v=0
)
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 08, 2009, 05:50 pm
Ok, thanks. It´s possible that i get damaged the sensor?
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 08, 2009, 06:42 pm
Driving the inputs .7 volts higher than the Vcc voltage will damage some chips, I don't know how sensitive this particular device is.  

PM me if you want to send your HP03 to me so I can try it on my test rig.



Title: Re: i2c Pressure Sensor
Post by: wlwl on Jul 09, 2009, 06:15 pm
Hi, mem. I want to use your hp03.pde to make my project. But my board is nano . I think something must be changed in hp03.pde or more. But I am a newbie in C/C++. Can you help me for that?
Best regard.

wlwl
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 09, 2009, 07:48 pm
Hi wlwl, I don't use the Nano but would think it should work just like the full size Arduino boards I do use. Why do you think something needs changing?
Title: Re: i2c Pressure Sensor
Post by: wlwl on Jul 10, 2009, 02:41 am
Oh,thanks your notice. Let  me test it in nano! ;) ;)
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 12, 2009, 03:39 am
Thanks, Mem.

I´m using IRF3205 and 10K resistors, but i dont get data. Just this:


Error getting HP03 calibration, check sensor connection

pressure 1100

  Altitude, Meters = -698.2

  Altitude, Feet  = -2291.0

pressure 1050

  Altitude, Meters = -301.5

  Altitude, Feet  = -989.0
.
.
.
.
.

pressure 350

  Altitude, Meters = 8117.2

  Altitude, Feet  = 26631.0

Error getting HP03 data, check sensor connection

Error getting HP03 data, check sensor connection

Error getting HP03 data, check s


pin 11 is a resitor voltage??  i used   R1=1.8K  and R2=3.3K and this conected to MCLK.  It´s Ok???

Analog 3 is conected to XCLR with a 10K resitor??

what´s wrong?  i bought a new sensor.
thanks.

Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 12, 2009, 04:01 am
the reisitor between 5V and Drain aren´t conected. I corrected this, but now when starts the serial comunication (19200 or other)  nothing happens. only black screen all the time.

again, whats wrong????

thanks.
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 13, 2009, 10:35 am
ricarDOGS, its very difficult to debug something like this remotely.  Because there is not much explanation on how to connect things up, it's likely that the problem lies somewhere there. Perhaps if you can take a clear picture of your wiring it may be possible to see if something is amiss.

Do you have any previous experience with interfacing 3.3v to 5v logic levels? Did any of the HP03 pins get connected directly to an arduino pin or 5 volts when you first connected things up?
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 14, 2009, 08:27 pm
is that clear?
Tahnks.
(http://hosting.udlap.mx/estudiantes/ricardoj.gonzalezmz/HP03.bmp)
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 14, 2009, 08:57 pm
That looks very much like the circuit on the board I made. I will see if I can find the actual circuit diagram I used and will double check and let you know.

By any chance, did you apply +5 volts to any of the HP03 pins, I hope the module is not damaged.

Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 14, 2009, 09:09 pm
I conected like circuit, but when you confirme if its right, i´ll buy another sensor, just to be sure.Again, thanks.
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 15, 2009, 10:04 am
That looks similar to what I did. Here is my schematic so you can double check :
(http://farm4.static.flickr.com/3498/3722488341_093c2ffebe.jpg?v=0)

Its difficult for me to tell from your diagram but note that the drains are connected to the Arduino, the sources to the sensor.

For the voltage divider resistors (R5-R8) I used 2.2k on both sides but your values are good.
The other resistors were 8.2k but 10k just as good.

Note I have a 0.1 decoupling capacitor across the 3.3v line - may not be necessary but its best to use one.
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 15, 2009, 10:50 am
Here is a board layout suitable for building on stripboard that I used to make the shield I posted earlier.

(http://farm3.static.flickr.com/2460/3723367416_bb05b7283c.jpg?v=0
)

see: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1223819446/43#43
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 15, 2009, 07:08 pm
Ok, it´s the same circuit. Surely the sensor was damaged.

i´m using IRF3205 or SUP85N06 instead of 2n7000, it doesn't matter ??

R1=R2=R3=R4=8.2K??
R5=R6=R7=R8=2.2K??

Anyway, i´ll buy another sensor and tell you what happens.Thanks.
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 15, 2009, 07:37 pm
I would think most any N channel FET would work.

Yes, those are my resistor values but yours are just as good.
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 16, 2009, 03:43 am
I changed BS170 instead of IRF3205 and now serial communication starts  correctly, however the pressure and altitude change constantly, i don´t know the real values in my city. But the temperature is  30.5 degrees and a LM35 says 28.1 degrees. These 2 degrees of difenrence are normal?? or the sensor was damaged?? thanks.
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 16, 2009, 05:08 am
By how much do the altitude readings vary? If the readings are within 10 meters or so of your actual altitude then the sensor is probably working.
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 16, 2009, 07:44 am
I found in the intertet these altitudes for my city: 2160, 2135,2220.

but, the values of HP03d changes every reading, here is the txt for the readings:
http://hosting.udlap.mx/estudiantes/ricardoj.gonzalezmz/HP03D.txt

pressure is in hPA, right??
thanks.

Title: Re: i2c Pressure Sensor
Post by: mem on Jul 16, 2009, 10:19 am
yess, pressure is in hPa

The altitude variations are higher then they should be but still close enough to the expected readings to indicate that the sensor is probably working.

Do you have a decoupling capacitor on the 3.3v line? How long are the wires connecting the sensor?

Perhaps post a photo of you layout.
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 16, 2009, 10:39 pm
These are the pictures of my circuit:
(http://hosting.udlap.mx/estudiantes/ricardoj.gonzalezmz/HP1.bmp)

(http://hosting.udlap.mx/estudiantes/ricardoj.gonzalezmz/hp2.bmp)

(http://hosting.udlap.mx/estudiantes/ricardoj.gonzalezmz/HP3.bmp)

these are  readings (today):
http://hosting.udlap.mx/estudiantes/ricardoj.gonzalezmz/Valores2.txt

Altitud must be the same almost always?? because today changes a lot from yesterday.
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 16, 2009, 10:50 pm
Quote
altitud must be the same almost always?? because today changes a lot from yesterday.


I think your wiring is sort enough not to be causing a problem. It may be worth experimenting to see if its any more stable if you keep the circuit as far from your computer as possible

If you are saying that the readings are more stable then yesterday, I agree.

I wonder if you should try smoothing the output. You should be able to find code in the playground the will provide an moving average.

It would also be interesting to note the atmospheric pressure in your location and see if the readings track the changes in pressure.
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 17, 2009, 06:20 am
ok, it´s possible change pin 11 to another that not interfere with SPI communication??

I`ll use the ethernet shield, but this communicates with pins (10,11,12,13), right?
Thanks.
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 17, 2009, 09:32 am
The HP03 needs a 32kHz signal and this is provided by the FrequencyTimer2 library. FrequencyTimer2 uses hardware PWM to create the signal and this is hard wired in the controller chip to pin 11. If you want to free up pin 11 then you need to provide another source for the 32kHz signal.

One way of doing that is to use a timer chip like the 555. There are lots of resources on the web for this part (google 555), here is one: http://www.doctronics.co.uk/555.htm  the circuit you want is called an astable (multivibrator)

To free up pin 11 you need to turn off FrequencyTimer2. In the HP03 library source file you comment out these lines as follows in the begin method:
Code: [Select]

 /* set up TIMER2 to 32768Hz with 50/50 mark/space ration with output on  */
//  pinMode(11,OUTPUT);  // frequencyTimer2 is hard coded to output on this pin
//  FrequencyTimer2::setPeriod(31); // 31us = 32258hz
//  FrequencyTimer2::enable();
Title: Re: i2c Pressure Sensor
Post by: mem on Jul 17, 2009, 03:15 pm
For  anyone looking to use the HP03 code posted earlier in this thread,  here is a new test sketch that displays the various values from the sensor. It includes a function to smooth the altitude readings. I found that individual readings could vary by plus/minus four or five meters. Smoothing the data drops the deviation down to plus/minus a meter or so.  

Code: [Select]
// HP03 example sketch
// prints the temperature, presssure and altitude to the serial port
// also shows the maximum deviation in feet from the average altitude
// Created 17 July 2009

#include <HP03.h>
#include <FrequencyTimer2.h>
#include <Wire.h>

// note that the HP03 code uses digital pin 11 for the clock and analog pins 4 and 5 for I2C

const int numReadings = 12;    // the number of readings to smooth
                             // with HP03 conversion rate of 85ms, 12 readings takes one second
                             
long count = 0;               // the number of readings taken

long minA = 9999999;          // used to show how much the altitude deviates
long maxA = 0;
long deviation;    
 
void setup()
{
 Serial.begin(9600);  // start serial for output  
 Serial.flush();
 if(HP03.begin() == false)
   Serial.println("Error getting HP03 calibration, check sensor connection");    
}

void loop()
{    
 if(HP03.update() == false)
   Serial.println("Error getting HP03 data, check sensor connection");
 else  
 {
   count++;
   showReadings();
 }
}

void showReadings()
{
   Serial.print("Temp ");
   Serial.print(HP03.Temperature/10.0);
   Serial.print(" Pressure ");
   Serial.print(HP03.Pressure/100.0);
   HP03.distanceUnits = METERS;
   Serial.print("   Altitude: Meters = ");
   Serial.print(HP03.getAltitude(HP03.Pressure)/ 10);
   HP03.distanceUnits = FEET;
   Serial.print(", Feet  = ");
   long feet = HP03.getAltitude(HP03.Pressure);
   Serial.print(feet);
   feet = smooth(feet);
   if(count >= numReadings)
   {    
     Serial.print(" smoothed = ");
     Serial.print(feet);        
     
     if(feet < minA) minA = feet;
     if(feet > maxA) maxA = feet;          
     Serial.print(", deviation = ");
     Serial.print( (maxA-minA) /2 );      
   }
   Serial.println();
}

long smooth(long value)
{
static int index = 0;
static long readings[numReadings]  ;
static boolean isPrimed = false;   // set to true when at least numReadings have been received
static long total = 0;

  total = total - readings[index];    // remove the oldest value
  readings[index] = value;            // store the new value
  total= total + readings[index];     // add the reading to the total:    
  index = index + 1;                  // advance to the next position in the array:    
 
  // if we're at the end of the array...
  if (index >= numReadings)          // check if this is the end of the array    
  {
     index = 0;                      // and wrap to the beginning if so    
     isPrimed  = true;               // enough readings received for average
  }
  if(isPrimed)
     return total / numReadings;  
  else
    return value; // return the raw value if not enough samples received;  
}
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Jul 17, 2009, 06:39 pm
With 555, whats the minimum/highest  duty cycle, or it doesn´t matter?

I compiled your new sketch, but i have these errrors. Thanks.


In function 'void showReadings()':
error: call of overloaded 'print(double)' is ambiguousC:\Documents and Settings\12ic412d06\Escritorio\arduino-0012\hardware\cores\arduino/Print.h:37: note: candidates are: void Print::print(char)


C:\Documents and Settings\12ic412d06\Escritorio\arduino-0012\hardware\cores\arduino/Print.h:39: note:                 void Print::print(uint8_t)


C:\Documents and Settings\12ic412d06\Escritorio\arduino-0012\hardware\cores\arduino/Print.h:40: note:                 void Print::print(int)


C:\Documents and Settings\12ic412d06\Escritorio\arduino-0012\hardware\cores\arduino/Print.h:41: note:                 void Print::print(unsigned int)


C:\Documents and Settings\12ic412d06\Escritorio\arduino-0012\hardware\cores\arduino/Print.h:42: note:                 void Print::print(long int)


C:\Documents and Settings\12ic412d06\Escritorio\arduino-0012\hardware\cores\arduino/Print.h:43: note:                 void Print::print(long unsigned int)



Title: Re: i2c Pressure Sensor
Post by: mem on Jul 17, 2009, 08:17 pm
It uses floating point support in the serial code. As I recall this was introduced in version 0013. Looks like you are using version 0012.

If you change 10.0 to 10 and 100.0 to 100 it should compile in 0012 but you will lose the values after the decimal point.

Why not upgrade to a later version?


I don't know if the duty cycle matters. See how close you can get to 50% and see if it works.
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Dec 17, 2009, 02:30 am
Hi, i  compare my readings whith DAVIS weather station, and i'm 8-11 hpa under the DAVIS, and that´s  much. Datasheet HP03d says that pressure accuracy is about plus/minus 1hpa.

Some idea about what´s happening?

Temperature Readings are OK comparated with DAVIS and SHT15.

thanks.
Title: Re: i2c Pressure Sensor
Post by: mem on Dec 17, 2009, 06:26 am
Are you at exactly the same altitude as that station, 8-11 hpa lower would be perhaps a hundred meters higher.

Also, the spec may be for the relative accuracy (after calibration).  You can calibrate the values by adding (subtracting) a constant to the readings.
Title: Re: i2c Pressure Sensor
Post by: ricarDOGS on Dec 17, 2009, 06:39 am
yes, DAVIS and HP03d(with metoerological shelter ) are togheter. the problem if i add a constant,  it isn´t lineal. sometimes the difference is 8.XX and sometimes is 11.XX mb. thanks.
Title: Re: i2c Pressure Sensor
Post by: mem on Dec 17, 2009, 07:04 am
Have you tried measuring at significantly different altitudes? Is the variation still +-1.5 hpa or does the error increase or decrease at different altitudes.

Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 14, 2010, 03:08 am
I've had mixed results so far with the HP03. I develop using a netbook running Ubuntu Linux, and was not able to fix compiling errors using version 0018. I tried installing 0011 and 0012 but they would not run (I guess this is a limitation of the OS--I'm a Mac guy without a lot of experience with Linux).

Next I switched to Mac OSX Leopard and loaded 0012. With the adjustments to wiring.h as described earlier in this thread, I was able to get the data stream in the serial monitor. According to Google Earth I'm located at 77m but the HP03 says I'm -44m, and although Environment Canada gives the pressure at 1031, the HP03 says it's 1018.

I'm interested in the barometric pressure delta so absolutes are not necessary, but it is troubling that I can't get accuracy as close as is claimed by the datasheet.

Later on in this thread mem offers another sketch, which I loaded and tried to run with 0012 but had similar compile errors to ricarDOGS. mem suggests upgrading to 0013. Has anyone had success using this library with the most recent distribution 0018?
Title: Re: i2c Pressure Sensor
Post by: mem on Mar 14, 2010, 09:31 am
Quote
Has anyone had success using this library with the most recent distribution 0018?


The code posted compiles without errors on 0018, although I have only tested this on a windows machine.

What errors did you get?
Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 14, 2010, 01:25 pm
I get two errors with the newer sketch. I'm running Ubuntu Linux 9.04 and Arduino release 0018 (with the revisions to Wiring.h as prescribed earlier in this thread):

/home/mbl/Desktop/arduino-0018/hardware/arduino/cores/arduino/HardwareSerial.cpp: In member function 'void HardwareSerial::begin(long int)':

/home/mbl/Desktop/arduino-0018/hardware/arduino/cores/arduino/HardwareSerial.cpp:144: error: 'abs' was not declared in this scope


Thanks for the quick response... I'm anxious to get the new sketch working since, as you say, it may give more reliable data than the original one through averaging.
Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 14, 2010, 01:41 pm
The changes that I made to wiring.h broke other sketches in 0018, so I restored wiring.h back to its original state.

With the original wiring.h, I receive a different set of errors:

/usr/lib/gcc/avr/4.3.2/../../../avr/include/stdlib.h:111: error: expected unqualified-id before 'int'

/usr/lib/gcc/avr/4.3.2/../../../avr/include/stdlib.h:111: error: expected `)' before 'int'

/usr/lib/gcc/avr/4.3.2/../../../avr/include/stdlib.h:111: error: expected `)' before 'int'


These errors look familiar to me but I don't know my way around things well enough to make sense of this.
Title: Re: i2c Pressure Sensor
Post by: mem on Mar 14, 2010, 02:45 pm
the errors are because there are some definitions in wiring.h that cause conflicts with the standard C libraries.

try replacing the includes in the HP03.cpp library  so just the following are included:

#include <avr/pgmspace.h>
#include <WProgram.h>
#include <FrequencyTimer2.h>
#include <Wire.h>
#include "HP03.h"


The top of the file should look like this:
Code: [Select]
/*
 HP03.cpp - Arduino library support for HP03 Pressure sensor
Copyright (c)2008 Michael Margolis All right reserved

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 Version:   1.0 - July14 2008
*/

// Note that this code uses the return values in Arduino version 0012 wire.c library

#include <avr/pgmspace.h>
#include <WProgram.h>
#include <FrequencyTimer2.h>
#include <Wire.h>
#include "HP03.h"

#if !defined(NULL)
#define NULL 0
#endif


The rest of the file should be unchanged
Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 14, 2010, 03:10 pm
Thanks! I'll take a look later today.

Is it easy to explain why the second include does not have a "#" in front of it?
Title: Re: i2c Pressure Sensor
Post by: mem on Mar 14, 2010, 03:24 pm
its a cut and paste errror

I have modifed the post to show the correct includes
Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 14, 2010, 07:44 pm
No joy. Precisely the same errors (as I last mentioned in reply 77) remain. One thing I did not notice earlier is that in the upper sketch code portion of the window, the FrequencyTimer2 include is highlighted, suggesting that the problem is there...?

[glow]#include <FrequencyTimer2.h>[/glow]
Title: Re: i2c Pressure Sensor
Post by: mem on Mar 14, 2010, 08:29 pm
If the problem is in FrequencyTimer2 then try moving this include:
 #include <wiring.h>
from FrequencyTimer2.h to  FrequencyTimer2.cpp
Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 14, 2010, 08:47 pm
When I moved the include as instructed, I encountered these errors:

/home/mbl/sketchbook/libraries/FrequencyTimer2/FrequencyTimer2.h:30: error: 'uint8_t' does not name a type

/home/mbl/sketchbook/libraries/FrequencyTimer2/FrequencyTimer2.cpp:27: error: 'uint8_t FrequencyTimer2::enabled' is not a static member of 'class FrequencyTimer2'

/home/mbl/sketchbook/libraries/FrequencyTimer2/FrequencyTimer2.cpp: In static member function 'static void FrequencyTimer2::setPeriod(long unsigned int)':

/home/mbl/sketchbook/libraries/FrequencyTimer2/FrequencyTimer2.cpp:96: error: 'enabled' is not a member of 'FrequencyTimer2'

/home/mbl/sketchbook/libraries/FrequencyTimer2/FrequencyTimer2.cpp: In static member function 'static void FrequencyTimer2::enable()':

/home/mbl/sketchbook/libraries/FrequencyTimer2/FrequencyTimer2.cpp:146: error: 'enabled' is not a member of 'FrequencyTimer2'

/home/mbl/sketchbook/libraries/FrequencyTimer2/FrequencyTimer2.cpp: In static member function 'static void FrequencyTimer2::disable()':

/home/mbl/sketchbook/libraries/FrequencyTimer2/FrequencyTimer2.cpp:156: error: 'enabled' is not a member of 'FrequencyTimer2'


I thought that maybe I should have not removed the include from FrequencyTimer2.h, so I put it back in, but this did not change the situation from the three errors encountered before.
Title: Re: i2c Pressure Sensor
Post by: mem on Mar 14, 2010, 09:01 pm
try including only <WProgram.h> in FrequencyTimer2.h
Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 14, 2010, 09:27 pm
Thanks mem, it works, and it's a beautiful thing! If I'm ever in London I'll buy you a beer.
Title: Re: i2c Pressure Sensor
Post by: mem on Mar 14, 2010, 11:05 pm
good to hear you have it going.

Have fun
Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 15, 2010, 01:34 pm
I ran the sketch overnight but at some point it hung, giving an indeterminate number of error statements in red. I had hoped to be able to transcribe the error but Arduino 0018 has frozen and the window is now white. I remember that it mentioned that it was a JAVA out of memory error.

I realize that this could be caused by a wide variety of factors, but we did make some changes to some of the libraries and I thought I should mention it.
Title: Re: i2c Pressure Sensor
Post by: mem on Mar 15, 2010, 01:59 pm
Sounds like its the Serial monitor, do you have another serial program you could use to view the serial output  to ensure that is ok.

I don't think anything that was changed on the arduino side would cause the Serial Monitor to freeze.
Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 15, 2010, 11:14 pm
I think you're right; I restarted 0018 and left the Serial Monitor open. When I returned about 6 hours later the program had hung again.

I just installed a program called "GtkTerm"--also known as "Serial Port Terminal"--and when I started it up and selected the USB port that connects to my Duemilanove, the data streamed right in.

I'll be jettisoning the Serial Monitor anyway in favour of an LCD display (for now anyway). Thanks again.
Title: Re: i2c Pressure Sensor
Post by: MLeBlanc on Mar 16, 2010, 01:29 am
Another question relating to Arduino's Digital Pin 11, which is used to drive the MCLK on the HP03: I want to use the liquidcrystal library, which uses pin 11 for LCD Enable.

The frequencytimer2 page in the Playground says that (if it's running on an atmega168) this library uses pin 11 and pin 3. I've looked at the frequencytimer2.cpp code to see if there is any mention of pin allocations but if it's there, it's not in clear text. Simply changing the pin in HP03.cpp from 11 to 3 doesn't seem to work.

I'm wondering if this is a case of diminished returns--should I just rig up a 32kHz 555 timer and be done with it?
Title: Re: i2c Pressure Sensor
Post by: PaulS on Mar 16, 2010, 10:12 am
The LiquidCrystal library uses ANY 6 pins. No need to work around any special pins. Just plug the LCD into 6 pins, and tell the library WHICH 6 pins you used.