Emery Premeaux
/
MS4525_pitot_tube
Library and demo program for MS4525DO differential pressure sensor based pitot tube, using I2C interface
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Tue Jul 12 2022 21:49:13 by 1.7.2