Subversion Repositories Projects

Rev

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
}