Library and demo program for MS4525DO differential pressure sensor based pitot tube, using I2C interface

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MS4525DO.cpp Source File

MS4525DO.cpp

00001 
00002 #include "mbed.h"
00003 #include "MS4525DO.h"
00004 
00005 
00006 MS4525DO::MS4525DO(PinName sda, PinName scl, char slave_adr)
00007     :
00008     i2c_p(new I2C(sda, scl)), 
00009     i2c(*i2c_p),
00010     address(slave_adr<<1)
00011 {
00012     initialize();
00013 }
00014 
00015 MS4525DO::MS4525DO(I2C &i2c_obj, char slave_adr)
00016     :
00017     i2c_p(NULL), 
00018     i2c(i2c_obj),
00019     address(slave_adr<<1)
00020 {
00021     initialize();
00022 }
00023 
00024 MS4525DO::~MS4525DO()
00025 {
00026     if (NULL != i2c_p)
00027         delete  i2c_p;
00028 }
00029 
00030 
00031 /* public functions
00032         void initialize(void);
00033         int measure(void);              // returns status of measurement
00034         float getPSI(void);             // returns the PSI of last measurement
00035         float getTemperature(void);     // returns temperature of last measurement
00036         float getAirSpeed(void);        // calculates and returns the airspeed
00037         int calibrate(void);            // attempts to calibrate and returns a status code
00038         */
00039 
00040 void MS4525DO::initialize()
00041 {
00042     // i2c writes to set up addresses, etc.
00043     
00044 }
00045 
00046 // combine measure and collect into one function that returns the status code only, and holds the results in variables
00047 // other subroutines for returning clean values should be get functions
00048 
00049 
00050 int MS4525DO::measure()
00051 {
00052     char ret;
00053     ret = fetch_pressure(P_dat, T_dat);
00054     return ret;
00055 }
00056 
00057 
00058 char MS4525DO::fetch_pressure(uint16_t &P_dat, uint16_t &T_dat)
00059 {
00060     char _status;
00061     char Press_H;
00062     char Press_L;
00063     char Temp_H;
00064     char Temp_L;
00065 
00066     char cmd[1];
00067     cmd[0] = 0x00;
00068     // So a device with a 'physical' address of 0x28, will need 'address bytes' of 0x50 for a write (R/W low), and 0x51 for a read (R/W high). 
00069     //      MS4525DAddress
00070     i2c.write(address, cmd, 1, true);  // select the register, no I2C Stop 
00071        
00072 
00073     char data[4];
00074 //    i2c.read(MS4525DAddress, static_cast<uint8_t>(4), static_cast<uint8_t>(true));  //Request 4 bytes, 2 pressure/status and 2 temperature
00075     i2c.read(address, data, 4);
00076     
00077 
00078     Press_H = data[0];
00079     Press_L = data[1];
00080     Temp_H = data[2];
00081     Temp_L = data[3];
00082    
00083      _status = (Press_H >> 6) & 0x03;
00084     Press_H = Press_H & 0x3f;
00085     P_dat = (((uint16_t)Press_H) << 8) | Press_L;
00086 
00087     Temp_L = (Temp_L >> 5);
00088     T_dat = (((uint16_t)Temp_H) << 3) | Temp_L;
00089  
00090     return _status;
00091 }
00092 
00093 
00094 
00095 float MS4525DO::getPSI(void){             // returns the PSI of last measurement
00096     // convert and store PSI
00097     psi=(static_cast<float>(static_cast<int16_t>(P_dat)-MS4525ZeroCounts))/static_cast<float>(MS4525Span)*static_cast<float>(MS4525FullScaleRange);
00098     // apply PSI calibration data
00099     //   psi = psi + 0.007f;
00100     
00101     /* Below code is Pixhawk code which doesnt seem to work correctly */
00102     // Calculate differential pressure. As its centered around 8000
00103     // and can go positive or negative
00104     /*
00105     const float P_min = -1.0f;
00106     const float P_max = 1.0f;
00107     const float PSI_to_Pa = 6894.757f;
00108     */ 
00109     /*
00110       this equation is an inversion of the equation in the
00111       pressure transfer function figure on page 4 of the datasheet
00112       We negate the result so that positive differential pressures
00113       are generated when the bottom port is used as the static
00114       port on the pitot and top port is used as the dynamic port
00115      */
00116      /*
00117     float diff_press_PSI = -((T_dat - 0.1f * 16383) * (P_max - P_min) / (0.8f * 16383) + P_min);
00118     float diff_press_pa_raw = diff_press_PSI * PSI_to_Pa;
00119     */
00120     
00121     
00122     return psi;
00123 }             
00124   
00125 float MS4525DO::getTemperature(void){     // returns temperature of last measurement
00126     // convert and store Temperature
00127     temperature= (static_cast<float>(static_cast<int16_t>(T_dat)));
00128     temperature = (temperature / 10);   // now in deg F
00129     temperature = ((temperature -32) / 1.8f);   // now in deg C
00130     
00131     /* Below code is pixhawk version which DOES work correctly */
00132     /*
00133     PX4temperature = ((200.0f * T_dat) / 2047) - 50;
00134     terminal.printf("PX4 Temperature: ");
00135     terminal.printf("%0.1f\n", PX4temperature);
00136     */
00137     
00138     return temperature;
00139 }
00140 
00141 float MS4525DO::getAirSpeed(void){        // calculates and returns the airspeed
00142     /* Velocity calculation from a pitot tube explanation */
00143     /* +/- 1PSI, approximately 100 m/s */
00144     float rho = 1.225; // density of air 
00145     // velocity = squareroot( (2*differential) / rho )
00146     float velocity;
00147     if (psi<0) {
00148         velocity = -sqrt(-(2*psi) / rho);
00149     }else{
00150         velocity = sqrt((2*psi) / rho);
00151         }
00152     velocity = velocity*10;
00153     
00154     return velocity;
00155 }
00156 
00157 
00158 int MS4525DO::calibrate(void){            // attempts to calibrate and returns a status code
00159 
00160 }