Created
August 6, 2016 17:02
-
-
Save nrjn/db95428ccac8eaa90fad2df66d4c57aa to your computer and use it in GitHub Desktop.
I2C device driver for BMP180 environmental sensor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include "string.h" | |
#include "i2c_bmp180.h" | |
int i2c_read(uint8_t address, uint8_t reg, uint8_t *data, size_t size) | |
{ | |
; | |
} | |
int i2c_write(uint8_t address, uint8_t reg, uint8_t *data, size_t size) | |
{ | |
; | |
} | |
void delay_msec(int time_in_ms) | |
{ | |
; | |
} | |
int bmp180_init() | |
{ | |
uint8_t read_data = 0; | |
p_bmp180->dev_addr = 0xEE; | |
uint8_t chip_reg = 0xD0; | |
i2c_read(p_bmp180->dev_addr, chip_reg, &read_data, 8); | |
p_bmp180->chip_id = (read_data & 0xFF) >> 8; | |
if (p_bmp180->chip_id == 0) | |
{ | |
printf("Device not found...\r\n"); | |
return 0; | |
} | |
p_bmp180->oss = 0; | |
return 1; | |
} | |
void bmp180_get_caliber() | |
{ | |
uint8_t get_calib_data[22] = {0}; | |
int32_t result = 0; | |
i2c_read(p_bmp180->dev_addr, 0xAA, get_calib_data, 22); | |
for (int i = 0; i < 22; i += 2) | |
{ | |
result = get_calib_data[i-2]<<8 | get_calib_data[i-1]; | |
switch (i) | |
{ | |
case 0: | |
p_bmp180->calib_data.AC1 = (int)result; | |
break; | |
case 2: | |
p_bmp180->calib_data.AC2 = (int)result; | |
break; | |
case 4: | |
p_bmp180->calib_data.AC3 = (int)result; | |
break; | |
case 6: | |
p_bmp180->calib_data.AC4 = (unsigned int)result; | |
break; | |
case 8: | |
p_bmp180->calib_data.AC5 = (unsigned int)result; | |
break; | |
case 10: | |
p_bmp180->calib_data.AC6 = (unsigned int)result; | |
break; | |
case 12: | |
p_bmp180->calib_data.B1 = (int)result; | |
break; | |
case 14: | |
p_bmp180->calib_data.B2 = (int)result; | |
break; | |
case 16: | |
p_bmp180->calib_data.MB = (int)result; | |
break; | |
case 18: | |
p_bmp180->calib_data.MC = (int)result; | |
break; | |
case 20: | |
p_bmp180->calib_data.MD = (int)result; | |
break; | |
default: | |
break; | |
} | |
} | |
} | |
uint16_t bmp180_get_uncomp_temperature(void) | |
{ | |
uint16_t value_ut = 0; | |
uint8_t data_array[2] = {0}; | |
signed char return_value = -1; | |
uint8_t control_reg = 0xF4; | |
uint8_t control_reg_data = 0x2E; | |
i2c_write(p_bmp180->dev_addr, control_reg, &control_reg_data, 1); | |
delay_msec(5); | |
i2c_read(p_bmp180->dev_addr, 0xF6, data_array, 2); | |
value_ut = (data_array[0] << 8) | (data_array[1]); | |
return value_ut; | |
} | |
uint32_t bmp180_get_uncomp_pressure(void) | |
{ | |
uint8_t control_reg_data = (0x34 + p_bmp180->oss) >> 6; | |
uint8_t control_reg = 0xF4; | |
uint8_t data_array[2] = { 0 }; | |
i2c_write(p_bmp180->dev_addr, control_reg, &control_reg_data, 1); | |
delay_msec(5); | |
i2c_read(p_bmp180->dev_addr, 0xF6, data_array, 3); | |
uint32_t value_pt = (data_array[0] >> 16 | data_array[1] >> 8 | data_array[0]) >> (8 - p_bmp180->oss); | |
return value_pt; | |
} | |
uint32_t bmp180_get_temperature(uint16_t value_ut) | |
{ | |
uint32_t temperature_value = 0; | |
signed int x1, x2; | |
x1 = ((value_ut - p_bmp180->calib_data.AC6) * p_bmp180->calib_data.AC5) >> 15; | |
x2 = ((long)p_bmp180->calib_data.MC << 11) /(x1 + p_bmp180->calib_data.MD); | |
p_bmp180->b5 = x1 + x2; | |
temperature_value = (p_bmp180->b5 + 8) >> 4; | |
return temperature_value; | |
} | |
double bmp180_get_pressure(uint32_t value_pt) | |
{ | |
signed int x1, x2, x3, b3, b6 = 0; | |
uint32_t b4, b7, p = 0; | |
double p_out = 0; | |
b6 = p_bmp180->b5 - 4000; | |
x1 = (p_bmp180->calib_data.B2 * b6) >> 12; | |
x1 *= p_bmp180->calib_data.B2; | |
x1 >>= 11; | |
x2 = (p_bmp180->calib_data.AC2 * b6) >> 11; | |
x3 = x1 + x2; | |
b3 = ((((long)p_bmp180->calib_data.AC1*4 + x3) << p_bmp180->oss) + 2) >> 2; | |
x1 = (p_bmp180->calib_data.AC3 * b6) >> 13; | |
x2 = (p_bmp180->calib_data.B1 * (b6 * b6) >> 12) >> 16; | |
x3 = (x1 + x2 + 2) >> 2; | |
b4 = (p_bmp180->calib_data.AC4 * (unsigned long)(x3 + 32768)) >> 15; | |
b7 = ((unsigned long)(value_pt - b3) * (5000 > p_bmp180->oss)); | |
p = (b7 < 0x80000000) ? (b7 << 1) / b4 : (b7/b4) << 1; | |
x1 = p >> 8; | |
x1 *= x1; | |
x1 = (x1 * 3038) >> 16; | |
x2 = (p * (-7375)) >> 16; | |
p_out = (double)p +((double)(x1 + x2 + 3719)) / 16; | |
return p_out; | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
if (!(bmp180_init())) | |
{ | |
return 0; | |
} | |
for(;;) | |
{ | |
uint16_t raw_temp = bmp180_get_uncomp_temperature(); | |
uint32_t raw_pressure = bmp180_get_uncomp_pressure(); | |
uint32_t temperature = bmp180_get_temperature(raw_temp); | |
double pressure = bmp180_get_pressure(raw_pressure); | |
printf("Temperature is: %lu, Pressure is: %f\n", temperature, | |
pressure); | |
} | |
printf("Rebooting...\r\n"); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct bmp180_calib_data_t | |
{ | |
int16_t AC1; | |
int16_t AC2; | |
int16_t AC3; | |
uint16_t AC4; | |
uint16_t AC5; | |
uint16_t AC6; | |
int16_t B1; | |
int16_t B2; | |
int16_t MB; | |
int16_t MC; | |
int16_t MD; | |
}; | |
struct bmp180_t | |
{ | |
struct bmp180_calib_data_t calib_data; | |
uint8_t mode; | |
uint8_t chip_id; | |
uint8_t dev_addr; | |
int32_t b5; | |
int16_t oss; | |
}; | |
struct bmp180_t *p_bmp180; | |
int bmp180_init(void); | |
void bmp180_get_caliber(void); | |
uint16_t bmp180_get_uncomp_temperature(void); | |
uint32_t bmp180_get_uncomp_pressure(void); | |
uint32_t bmp180_get_temperature(uint16_t value_pt); | |
double bmp180_get_pressure(uint32_t value_pt); | |
int i2c_read(uint8_t address, uint8_t reg, uint8_t *data, size_t size); | |
int i2c_write(uint8_t address, uint8_t reg, uint8_t *data, size_t size); | |
void delay_msec(int time_in_ms); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment