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 | }
|