gavin beardall
/
hsc
main.cpp@1:d01abb5e6f52, 2011-10-17 (annotated)
- Committer:
- gbeardall
- Date:
- Mon Oct 17 10:41:37 2011 +0000
- Revision:
- 1:d01abb5e6f52
- Parent:
- 0:2fdc6095d7b4
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gbeardall | 1:d01abb5e6f52 | 1 | /* |
gbeardall | 1:d01abb5e6f52 | 2 | * Honeywell Pressure Sensor |
gbeardall | 1:d01abb5e6f52 | 3 | * |
gbeardall | 1:d01abb5e6f52 | 4 | */ |
gbeardall | 1:d01abb5e6f52 | 5 | |
gbeardall | 1:d01abb5e6f52 | 6 | #include <math.h> |
gbeardall | 1:d01abb5e6f52 | 7 | |
gbeardall | 0:2fdc6095d7b4 | 8 | #include "mbed.h" |
gbeardall | 0:2fdc6095d7b4 | 9 | |
gbeardall | 0:2fdc6095d7b4 | 10 | DigitalOut myled(LED1); |
gbeardall | 0:2fdc6095d7b4 | 11 | |
gbeardall | 0:2fdc6095d7b4 | 12 | // http://sensing.honeywell.com/index.cfm/ci_id/157750/la_id/1/document/1/re_id/0 |
gbeardall | 0:2fdc6095d7b4 | 13 | // http://sensing.honeywell.com/index.cfm/ci_id/156988/la_id/1/document/1/re_id/0 |
gbeardall | 0:2fdc6095d7b4 | 14 | |
gbeardall | 0:2fdc6095d7b4 | 15 | #define HSC_2A 0x28 |
gbeardall | 0:2fdc6095d7b4 | 16 | |
gbeardall | 0:2fdc6095d7b4 | 17 | int main() { |
gbeardall | 0:2fdc6095d7b4 | 18 | |
gbeardall | 0:2fdc6095d7b4 | 19 | // BMP085 bmp085(p28, p27); //bmp085(p9, p10); // sda, scl |
gbeardall | 0:2fdc6095d7b4 | 20 | |
gbeardall | 0:2fdc6095d7b4 | 21 | printf("\rhsc\n\r"); |
gbeardall | 0:2fdc6095d7b4 | 22 | |
gbeardall | 0:2fdc6095d7b4 | 23 | I2C i2c(p28, p27); |
gbeardall | 0:2fdc6095d7b4 | 24 | |
gbeardall | 0:2fdc6095d7b4 | 25 | int id = HSC_2A; |
gbeardall | 0:2fdc6095d7b4 | 26 | |
gbeardall | 0:2fdc6095d7b4 | 27 | i2c.frequency(100000); // 100k - 400k |
gbeardall | 0:2fdc6095d7b4 | 28 | |
gbeardall | 0:2fdc6095d7b4 | 29 | while(1) { |
gbeardall | 0:2fdc6095d7b4 | 30 | |
gbeardall | 0:2fdc6095d7b4 | 31 | #if 0 |
gbeardall | 0:2fdc6095d7b4 | 32 | i2c.start(); |
gbeardall | 0:2fdc6095d7b4 | 33 | i2c.write((id<<1) | 1); |
gbeardall | 0:2fdc6095d7b4 | 34 | int b1 = i2c.read(1); |
gbeardall | 0:2fdc6095d7b4 | 35 | int b2 = i2c.read(1); |
gbeardall | 0:2fdc6095d7b4 | 36 | int t1 = i2c.read(1); |
gbeardall | 0:2fdc6095d7b4 | 37 | int t2 = i2c.read(0); |
gbeardall | 0:2fdc6095d7b4 | 38 | i2c.stop(); |
gbeardall | 0:2fdc6095d7b4 | 39 | printf("%02X %02X %02X %02X\n\r", b1, b2, t1, t2); |
gbeardall | 0:2fdc6095d7b4 | 40 | #else |
gbeardall | 0:2fdc6095d7b4 | 41 | unsigned char data[4]; |
gbeardall | 0:2fdc6095d7b4 | 42 | i2c.read((id<<1)|1, (char*)data, sizeof(data)); |
gbeardall | 0:2fdc6095d7b4 | 43 | //printf("%02X %02X %02X %02X\n\r", data[0], data[1], data[2], data[3]); |
gbeardall | 1:d01abb5e6f52 | 44 | |
gbeardall | 0:2fdc6095d7b4 | 45 | int st = data[0]>>6; // status |
gbeardall | 0:2fdc6095d7b4 | 46 | int bd = ((data[0] & 0x3f) << 8) | data[1]; // bridge data |
gbeardall | 0:2fdc6095d7b4 | 47 | int td = ((data[2]<<8) | data[3]) >> 5; // temp data |
gbeardall | 0:2fdc6095d7b4 | 48 | |
gbeardall | 1:d01abb5e6f52 | 49 | // P: 14 bits |
gbeardall | 1:d01abb5e6f52 | 50 | // Cmin=2^14-1*.1 Cmax=2^14-1*.9 |
gbeardall | 1:d01abb5e6f52 | 51 | // Pmin=0 Pmax=15 |
gbeardall | 1:d01abb5e6f52 | 52 | float p = (((float)bd-1638)*(15-0)/(14745-1638))+0; // convert raw data to psi |
gbeardall | 1:d01abb5e6f52 | 53 | p = p * 68.9475729; // convert psi to hPa |
gbeardall | 0:2fdc6095d7b4 | 54 | |
gbeardall | 1:d01abb5e6f52 | 55 | // T: 11 bits (Cmax=2047=2^11-1) |
gbeardall | 1:d01abb5e6f52 | 56 | float t = (((float)td*200)/2047)-50; // convert raw data to deg C |
gbeardall | 0:2fdc6095d7b4 | 57 | printf("%d: %.2f hPa %.2f C\n\r", st, p, t); |
gbeardall | 0:2fdc6095d7b4 | 58 | |
gbeardall | 0:2fdc6095d7b4 | 59 | wait(1); |
gbeardall | 0:2fdc6095d7b4 | 60 | #endif |
gbeardall | 0:2fdc6095d7b4 | 61 | |
gbeardall | 0:2fdc6095d7b4 | 62 | myled = 1; |
gbeardall | 0:2fdc6095d7b4 | 63 | wait(0.2); |
gbeardall | 0:2fdc6095d7b4 | 64 | myled = 0; |
gbeardall | 0:2fdc6095d7b4 | 65 | wait(0.2); |
gbeardall | 0:2fdc6095d7b4 | 66 | |
gbeardall | 0:2fdc6095d7b4 | 67 | } // while |
gbeardall | 0:2fdc6095d7b4 | 68 | |
gbeardall | 0:2fdc6095d7b4 | 69 | } // main |
gbeardall | 1:d01abb5e6f52 | 70 | |
gbeardall | 1:d01abb5e6f52 | 71 | |
gbeardall | 1:d01abb5e6f52 | 72 | // http://en.wikipedia.org/wiki/Barometric_formula |
gbeardall | 1:d01abb5e6f52 | 73 | const float layers[][4] = { |
gbeardall | 1:d01abb5e6f52 | 74 | // Height[m], Pressure[Pa], Temp[K], Lapse[K/m], Subscript |
gbeardall | 1:d01abb5e6f52 | 75 | 0, 101325.0, 288.15, -0.0065, // 0 |
gbeardall | 1:d01abb5e6f52 | 76 | 11000, 22632.1, 216.65, 0.0, // 1 |
gbeardall | 1:d01abb5e6f52 | 77 | 20000, 5474.89, 216.65, 0.001, // 2 |
gbeardall | 1:d01abb5e6f52 | 78 | 32000, 868.019, 228.65, 0.0028, // 3 |
gbeardall | 1:d01abb5e6f52 | 79 | 47000, 110.906, 270.65, 0.0, // 4 |
gbeardall | 1:d01abb5e6f52 | 80 | 51000, 66.9389, 270.65, -0.0028, // 5 |
gbeardall | 1:d01abb5e6f52 | 81 | 71000, 3.95642, 214.65, -0.002 // 6 |
gbeardall | 1:d01abb5e6f52 | 82 | }; |
gbeardall | 1:d01abb5e6f52 | 83 | |
gbeardall | 1:d01abb5e6f52 | 84 | enum { L_HEIGHT=0, L_PRESS, L_TEMP, L_LAPSE }; |
gbeardall | 1:d01abb5e6f52 | 85 | |
gbeardall | 1:d01abb5e6f52 | 86 | const float g = 9.80665; |
gbeardall | 1:d01abb5e6f52 | 87 | const float M = 0.0289644; |
gbeardall | 1:d01abb5e6f52 | 88 | const float R = 8.31432; |
gbeardall | 1:d01abb5e6f52 | 89 | const float Ta = -273.15; // Absolute zero [deg C] |
gbeardall | 1:d01abb5e6f52 | 90 | |
gbeardall | 1:d01abb5e6f52 | 91 | // Search for subscript which matches pressure range |
gbeardall | 1:d01abb5e6f52 | 92 | // Choose appropriate formula and plug in values |
gbeardall | 1:d01abb5e6f52 | 93 | // Lookup derived h in table and check subscript is still same, otherwise recalculate |
gbeardall | 1:d01abb5e6f52 | 94 | // Add height correction |
gbeardall | 1:d01abb5e6f52 | 95 | |
gbeardall | 1:d01abb5e6f52 | 96 | // Pass in pressure and temperature from sensor |
gbeardall | 1:d01abb5e6f52 | 97 | // Return height[m] |
gbeardall | 1:d01abb5e6f52 | 98 | float pressureToHeight(float p, float t) { |
gbeardall | 1:d01abb5e6f52 | 99 | float h = -999; // error |
gbeardall | 1:d01abb5e6f52 | 100 | int b; |
gbeardall | 1:d01abb5e6f52 | 101 | int tries; |
gbeardall | 1:d01abb5e6f52 | 102 | |
gbeardall | 1:d01abb5e6f52 | 103 | // Search backwards thru layers for our pressure |
gbeardall | 1:d01abb5e6f52 | 104 | for(b = 6; b >= 0; --b) { |
gbeardall | 1:d01abb5e6f52 | 105 | if(p <= layers[b][1]) break; |
gbeardall | 1:d01abb5e6f52 | 106 | } |
gbeardall | 1:d01abb5e6f52 | 107 | if(b < 0) b = 0; // adjust so can have -ve heights |
gbeardall | 1:d01abb5e6f52 | 108 | int b1 = b; |
gbeardall | 1:d01abb5e6f52 | 109 | |
gbeardall | 1:d01abb5e6f52 | 110 | // Only retry limited times |
gbeardall | 1:d01abb5e6f52 | 111 | for(tries = 10; tries; --tries) { |
gbeardall | 1:d01abb5e6f52 | 112 | |
gbeardall | 1:d01abb5e6f52 | 113 | float Hb = layers[b][0]; |
gbeardall | 1:d01abb5e6f52 | 114 | float Pb = layers[b][1]; |
gbeardall | 1:d01abb5e6f52 | 115 | float Tb = layers[b][2]; //??? Tb = t - Ta; |
gbeardall | 1:d01abb5e6f52 | 116 | float Lb = layers[b][3]; |
gbeardall | 1:d01abb5e6f52 | 117 | |
gbeardall | 1:d01abb5e6f52 | 118 | if(Lb != 0.0) |
gbeardall | 1:d01abb5e6f52 | 119 | //h = (log(g*M/R/Lb)/log(p/Pb)*Tb - Tb)/Lb + Hb; // Equation 1 (non-zero lapse rate) |
gbeardall | 1:d01abb5e6f52 | 120 | h = (Tb/exp(R*Lb/g/M*log(p/Pb))-Tb)/Lb + Hb; |
gbeardall | 1:d01abb5e6f52 | 121 | else |
gbeardall | 1:d01abb5e6f52 | 122 | h = -log(p/Pb)*R*Tb/g/M + Hb; // Equation 2 (zero lapse rate) |
gbeardall | 1:d01abb5e6f52 | 123 | |
gbeardall | 1:d01abb5e6f52 | 124 | // Search again for derived height |
gbeardall | 1:d01abb5e6f52 | 125 | for(b = 6; b >= 0; --b) { |
gbeardall | 1:d01abb5e6f52 | 126 | if(h <= layers[b][0]) break; |
gbeardall | 1:d01abb5e6f52 | 127 | } |
gbeardall | 1:d01abb5e6f52 | 128 | |
gbeardall | 1:d01abb5e6f52 | 129 | if(b == b1) break; // gave same subscript, so we can stop |
gbeardall | 1:d01abb5e6f52 | 130 | b1 = b; |
gbeardall | 1:d01abb5e6f52 | 131 | |
gbeardall | 1:d01abb5e6f52 | 132 | } // for - tries |
gbeardall | 1:d01abb5e6f52 | 133 | |
gbeardall | 1:d01abb5e6f52 | 134 | if(tries <= 0) h = -999; // error |
gbeardall | 1:d01abb5e6f52 | 135 | |
gbeardall | 1:d01abb5e6f52 | 136 | |
gbeardall | 1:d01abb5e6f52 | 137 | return h; |
gbeardall | 1:d01abb5e6f52 | 138 | |
gbeardall | 1:d01abb5e6f52 | 139 | } // pressureToHeight |
gbeardall | 1:d01abb5e6f52 | 140 | |
gbeardall | 1:d01abb5e6f52 | 141 | /*end*/ |
gbeardall | 1:d01abb5e6f52 | 142 |