Hope HP03S sensor for measuring temperature and pressure

Dependencies:   mbed

main.cpp

Committer:
pvdheijden
Date:
2012-02-12
Revision:
0:ea6970015494

File content as of revision 0:ea6970015494:

#include "mbed.h"

// Program for Hope RF HP03S sensor  see www.hoperf.com
Serial pc(USBTX,USBRX);// use hyperterminal to diplay the results

DigitalOut ADCRESET(p19);// adcreset control XCLR must be pulled high before start AD conversion
// XCLR must be pulled low before start to read the coefficients from EEPROM
PwmOut MASTERCLK(p21);// pwm as clockpulse MCLK about 32KHz for the hope hp03s sensor

I2C i2c(p9,p10); // sda, scl


DigitalOut myled1(LED1);// for testing program 
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);


int i=0; // counter
int addr_EEPROM;// Address of EEPROM

char addr_ADC[2]={0xFF,0xF0};// function pressure
char addr_FUNC[1]={0xFD};
char addr_TEMP[2]={0xFF,0xE8};// function temperature

int addr_RDADC=0xEF;//read address for ADC

int addr_CDA=0xEE;// ADC address

char addr_REGISTER[1]={0x10};// first register address of the EEPROM

char pres[2];// mem two locations for ADC pressure value
char temp[2];// mem two locations for ADC temperature value
char data[18];// mem locations to store the register values

int DT;// used for calculation power to
int UT,dUT; // used as part of the calculation

float TT,Offset,Sensitivity,XP,Pressure,Pressure2;

int main() {


    while ( i<10 ) {

        MASTERCLK.period_us(32);// clock pulse with thirty one micro seconds is freq of about 32768 Hz
        wait(0.5);
        MASTERCLK=0.5;

        ADCRESET=0;// XCLR is pulled low, reset state
        wait(0.2);

        i2c.frequency(20000);// set i2c bus speed to 20Khz
        wait(0.2);

        // read register values
        addr_EEPROM=0xA0;// address EEPROM write is 0xA0, not allowed and read is 0xA1
        i2c.write(addr_EEPROM, addr_REGISTER, 1); // send address EEPROM with write bit set and send address REGISTER
        wait(0.4);
        myled1=1;
        wait(0.4);
        addr_EEPROM=0xA1;// read address of EEPROM
        i2c.read(addr_EEPROM,data, 18);// read register values 18 bytes on with EEPROM address 0xA1
        // data is registers address 0x10 if correct
        wait(1.0);
        myled1=0;

        // read ADC values

        ADCRESET=1;// XCLR is set to high to start ADC conversion cycle
        wait(0.4);
        myled2=1;// led2 is on

        // start temperature and pressure reading
        wait(0.2);
        i2c.write(addr_CDA,addr_ADC, 2); // address 0xEE on bus and 0xFF
        wait(0.5);// delay of mininum of 40 msec

        i2c.write(addr_CDA,addr_FUNC,1);// write 0xEE and 0xFD
        wait(0.2);
        // start read ADC pressure value
        i2c.read(addr_RDADC,pres, 2);// address ADC with lsb bit set, read msb and lsb from adc pressure value
        wait(0.5);

        myled2=0;// led2 is off
        wait(0.5);
        // read temperature value
        myled3=1;
        wait(0.2);

        i2c.write(addr_CDA,addr_TEMP,2);
        wait(0.5);// delay of mininum of 40 msec
        i2c.write(addr_CDA,addr_FUNC,1);
        wait(0.2);
        // start read ADC
        i2c.read(addr_RDADC,temp,2);// read msb and lsb of temperature ADC value
        wait(0.4);

        myled3=0;
        wait(0.5);

        //Calculation of Pressure and Temperature values
        // D2>=C5 dUT=D2-C5-((D2-C5)/2^7)*((D2-C5)/2^7)*A/2^C
        // D2<C5  dUT=D2-C5-((D2-C5)/2^7)*((D2-C5)/2^7)*B/2^C

        int tvalue=temp[0]*256+temp[1];// make one value out of the two bytes D2
        int C5value=data[8]*256+data[9];// make one value out of the msb and the lsb byte C5
        int Avalue=data[14];// convert to decimal
        int Bvalue=data[15];
        int Cvalue=data[16];

        UT=2;// init value of loop
        while (Cvalue>1) {
            Cvalue=Cvalue-1;
            UT=2*UT;// instead of two to the power of

        }
        if (tvalue>=C5value) {

            dUT=tvalue-C5value-((tvalue-C5value)/128)*((tvalue-C5value)/128)*Avalue/UT;

        }
        if (tvalue<C5value) {
            dUT=tvalue-C5value-((tvalue-C5value)/128)*((tvalue-C5value)/128)*Bvalue/UT;

        }
        int C6value=data[10]*256+data[11];// make one decimal value of msb and lsb of register C6
        int Dvalue=data[17];

        DT=2;// init value of loop
        while (Dvalue>1) {
            Dvalue=Dvalue-1;
            DT=2*DT;// instead of two to the power of D

        }
        // calculate temperature
        // T=250+dUT*C6/2^16-dUT/2^D

        TT=250+dUT*C6value/65536-dUT/DT;
        TT=TT*0.1;
        pc.printf("\x1B\x48\x1B\x4A");// clear screen and cursor home
        pc.printf("\n\n\rTEMPERATURE %6.2f Graden Celsius", TT);

        // Pressure calculation
        //Offset=(C2+(C4-1024)*dUT/2^14)*4
        //Sensitivity=C1+C3*dUT/2^10
        //XP=Sensitivity*(D1-7168)/2^14-Offset
        //Pressure=XP*10/2^5+C7

        //convert to decimal for the calculation
        int C1value=data[0]*256+data[1];// make one number of msb and lsb in decimal, register C1
        int C2value=data[2]*256+data[3];// make one number of msb and lsb in decimal, register C2
        int C3value=data[4]*256+data[5];// make one number of msb and lsb in decimal, register C3
        int C4value=data[6]*256+data[7];// make one number of msb and lsb in decimal, register C4
        int C7value=data[12]*256+data[13];// make one number of msb and lsb in decimal, register C7
        int D1value=pres[0]*256+pres[1];// make one number of the ADC value pressure

        Offset=(C2value+(C4value-1024)*dUT/16384)*4;

        Sensitivity=C1value+C3value*dUT/1024;

        XP=Sensitivity*(D1value-7168)/16384-Offset;

        Pressure=XP*10/32+C7value;
        pc.printf("\n\n\rPRESSURE %7.2f mbar", Pressure);

        Pressure2=XP*100/32+C7value*10;// for altitude measurement system use Pressure=XP*100/2^5+C7*10
        pc.printf("\n\n\rPressure2 %7.2f", Pressure2);
        wait(3);

        i++;//raise counter


    }
}