Subversion Repositories Projects

Rev

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