Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2194 | - | 1 | /* |
2 | bmp085 lib 0x01 |
||
3 | |||
4 | copyright (c) Davide Gironi, 2012 |
||
5 | |||
6 | Released under GPLv3. |
||
7 | Please refer to LICENSE file for licensing information. |
||
8 | */ |
||
9 | |||
10 | |||
11 | #include <stdio.h> |
||
12 | #include <stdlib.h> |
||
13 | #include <string.h> |
||
14 | #include <math.h> |
||
15 | #include <avr/io.h> |
||
16 | #include <util/delay.h> |
||
17 | |||
18 | #include "bmp085.h" |
||
19 | |||
20 | //path to i2c fleury lib |
||
21 | #include BMP085_I2CFLEURYPATH |
||
22 | |||
23 | /* |
||
24 | * i2c write |
||
25 | */ |
||
26 | void bmp085_writemem(uint8_t reg, uint8_t value) { |
||
27 | i2c_start_wait(BMP085_ADDR | I2C_WRITE); |
||
28 | i2c_write(reg); |
||
29 | i2c_write(value); |
||
30 | i2c_stop(); |
||
31 | } |
||
32 | |||
33 | /* |
||
34 | * i2c read |
||
35 | */ |
||
36 | void bmp085_readmem(uint8_t reg, uint8_t buff[], uint8_t bytes) { |
||
37 | uint8_t i =0; |
||
38 | i2c_start_wait(BMP085_ADDR | I2C_WRITE); |
||
39 | i2c_write(reg); |
||
40 | i2c_rep_start(BMP085_ADDR | I2C_READ); |
||
41 | for(i=0; i<bytes; i++) { |
||
42 | if(i==bytes-1) |
||
43 | buff[i] = i2c_readNak(); |
||
44 | else |
||
45 | buff[i] = i2c_readAck(); |
||
46 | } |
||
47 | i2c_stop(); |
||
48 | } |
||
49 | |||
50 | |||
51 | #if BMP085_FILTERPRESSURE == 1 |
||
52 | #define BMP085_AVARAGECOEF 21 |
||
53 | static long k[BMP085_AVARAGECOEF]; |
||
54 | long bmp085_avaragefilter(long input) { |
||
55 | uint8_t i=0; |
||
56 | long sum=0; |
||
57 | for (i=0; i<BMP085_AVARAGECOEF; i++) { |
||
58 | k[i] = k[i+1]; |
||
59 | } |
||
60 | k[BMP085_AVARAGECOEF-1] = input; |
||
61 | for (i=0; i<BMP085_AVARAGECOEF; i++) { |
||
62 | sum += k[i]; |
||
63 | } |
||
64 | return (sum /BMP085_AVARAGECOEF) ; |
||
65 | } |
||
66 | #endif |
||
67 | |||
68 | /* |
||
69 | * read calibration registers |
||
70 | */ |
||
71 | void bmp085_getcalibration() { |
||
72 | uint8_t buff[2]; |
||
73 | memset(buff, 0, sizeof(buff)); |
||
74 | |||
75 | bmp085_readmem(BMP085_REGAC1, buff, 2); |
||
76 | bmp085_regac1 = ((int)buff[0] <<8 | ((int)buff[1])); |
||
77 | bmp085_readmem(BMP085_REGAC2, buff, 2); |
||
78 | bmp085_regac2 = ((int)buff[0] <<8 | ((int)buff[1])); |
||
79 | bmp085_readmem(BMP085_REGAC3, buff, 2); |
||
80 | bmp085_regac3 = ((int)buff[0] <<8 | ((int)buff[1])); |
||
81 | bmp085_readmem(BMP085_REGAC4, buff, 2); |
||
82 | bmp085_regac4 = ((unsigned int)buff[0] <<8 | ((unsigned int)buff[1])); |
||
83 | bmp085_readmem(BMP085_REGAC5, buff, 2); |
||
84 | bmp085_regac5 = ((unsigned int)buff[0] <<8 | ((unsigned int)buff[1])); |
||
85 | bmp085_readmem(BMP085_REGAC6, buff, 2); |
||
86 | bmp085_regac6 = ((unsigned int)buff[0] <<8 | ((unsigned int)buff[1])); |
||
87 | bmp085_readmem(BMP085_REGB1, buff, 2); |
||
88 | bmp085_regb1 = ((int)buff[0] <<8 | ((int)buff[1])); |
||
89 | bmp085_readmem(BMP085_REGB2, buff, 2); |
||
90 | bmp085_regb2 = ((int)buff[0] <<8 | ((int)buff[1])); |
||
91 | bmp085_readmem(BMP085_REGMB, buff, 2); |
||
92 | bmp085_regmb = ((int)buff[0] <<8 | ((int)buff[1])); |
||
93 | bmp085_readmem(BMP085_REGMC, buff, 2); |
||
94 | bmp085_regmc = ((int)buff[0] <<8 | ((int)buff[1])); |
||
95 | bmp085_readmem(BMP085_REGMD, buff, 2); |
||
96 | bmp085_regmd = ((int)buff[0] <<8 | ((int)buff[1])); |
||
97 | } |
||
98 | |||
99 | /* |
||
100 | * get raw temperature as read by registers, and do some calculation to convert it |
||
101 | */ |
||
102 | void bmp085_getrawtemperature() { |
||
103 | uint8_t buff[2]; |
||
104 | memset(buff, 0, sizeof(buff)); |
||
105 | long ut,x1,x2; |
||
106 | |||
107 | //read raw temperature |
||
108 | bmp085_writemem(BMP085_REGCONTROL, BMP085_REGREADTEMPERATURE); |
||
109 | _delay_ms(5); // min. 4.5ms read Temp delay |
||
110 | bmp085_readmem(BMP085_REGCONTROLOUTPUT, buff, 2); |
||
111 | ut = ((long)buff[0] << 8 | ((long)buff[1])); //uncompensated temperature value |
||
112 | |||
113 | //calculate raw temperature |
||
114 | x1 = ((long)ut - bmp085_regac6) * bmp085_regac5 >> 15; |
||
115 | x2 = ((long)bmp085_regmc << 11) / (x1 + bmp085_regmd); |
||
116 | bmp085_rawtemperature = x1 + x2; |
||
117 | } |
||
118 | |||
119 | /* |
||
120 | * get raw pressure as read by registers, and do some calculation to convert it |
||
121 | */ |
||
122 | void bmp085_getrawpressure() { |
||
123 | uint8_t buff[3]; |
||
124 | memset(buff, 0, sizeof(buff)); |
||
125 | long up,x1,x2,x3,b3,b6,p; |
||
126 | unsigned long b4,b7; |
||
127 | |||
128 | #if BMP085_AUTOUPDATETEMP == 1 |
||
129 | bmp085_getrawtemperature(); |
||
130 | #endif |
||
131 | |||
132 | //read raw pressure |
||
133 | bmp085_writemem(BMP085_REGCONTROL, BMP085_REGREADPRESSURE+(BMP085_MODE << 6)); |
||
134 | _delay_ms(2 + (3<<BMP085_MODE)); |
||
135 | bmp085_readmem(BMP085_REGCONTROLOUTPUT, buff, 3); |
||
136 | up = ((((long)buff[0] <<16) | ((long)buff[1] <<8) | ((long)buff[2])) >> (8-BMP085_MODE)); // uncompensated pressure value |
||
137 | |||
138 | //calculate raw pressure |
||
139 | b6 = bmp085_rawtemperature - 4000; |
||
140 | x1 = (bmp085_regb2* (b6 * b6) >> 12) >> 11; |
||
141 | x2 = (bmp085_regac2 * b6) >> 11; |
||
142 | x3 = x1 + x2; |
||
143 | b3 = (((((long)bmp085_regac1) * 4 + x3) << BMP085_MODE) + 2) >> 2; |
||
144 | x1 = (bmp085_regac3 * b6) >> 13; |
||
145 | x2 = (bmp085_regb1 * ((b6 * b6) >> 12)) >> 16; |
||
146 | x3 = ((x1 + x2) + 2) >> 2; |
||
147 | b4 = (bmp085_regac4 * (uint32_t)(x3 + 32768)) >> 15; |
||
148 | b7 = ((uint32_t)up - b3) * (50000 >> BMP085_MODE); |
||
149 | p = b7 < 0x80000000 ? (b7 << 1) / b4 : (b7 / b4) << 1; |
||
150 | x1 = (p >> 8) * (p >> 8); |
||
151 | x1 = (x1 * 3038) >> 16; |
||
152 | x2 = (-7357 * p) >> 16; |
||
153 | bmp085_rawpressure = p + ((x1 + x2 + 3791) >> 4); |
||
154 | |||
155 | #if BMP085_FILTERPRESSURE == 1 |
||
156 | bmp085_rawpressure = bmp085_avaragefilter(bmp085_rawpressure); |
||
157 | #endif |
||
158 | } |
||
159 | |||
160 | /* |
||
161 | * get celsius temperature |
||
162 | */ |
||
163 | double bmp085_gettemperature() { |
||
164 | bmp085_getrawtemperature(); |
||
165 | double temperature = ((bmp085_rawtemperature + 8)>>4); |
||
166 | temperature = temperature /10; |
||
167 | return temperature; |
||
168 | } |
||
169 | |||
170 | /* |
||
171 | * get pressure |
||
172 | */ |
||
173 | int32_t bmp085_getpressure() { |
||
174 | bmp085_getrawpressure(); |
||
175 | return bmp085_rawpressure + BMP085_UNITPAOFFSET; |
||
176 | } |
||
177 | |||
178 | /* |
||
179 | * get altitude |
||
180 | */ |
||
181 | double bmp085_getaltitude() { |
||
182 | bmp085_getrawpressure(); |
||
183 | return ((1 - pow(bmp085_rawpressure/(double)101325, 0.1903 )) / 0.0000225577) + BMP085_UNITMOFFSET; |
||
184 | } |
||
185 | |||
186 | /* |
||
187 | * init bmp085 |
||
188 | */ |
||
189 | void bmp085_init() { |
||
190 | #if BMP085_I2CINIT == 1 |
||
191 | //init i2c |
||
192 | i2c_init(); |
||
193 | _delay_us(10); |
||
194 | #endif |
||
195 | |||
196 | bmp085_getcalibration(); //get calibration data |
||
197 | bmp085_getrawtemperature(); //update raw temperature, at least the first time |
||
198 | |||
199 | #if BMP085_FILTERPRESSURE == 1 |
||
200 | //initialize the avarage filter |
||
201 | uint8_t i=0; |
||
202 | for (i=0; i<BMP085_AVARAGECOEF; i++) { |
||
203 | bmp085_getrawpressure(); |
||
204 | } |
||
205 | #endif |
||
206 | } |