Skip to content

Instantly share code, notes, and snippets.

@nrjn
Created August 6, 2016 17:02
Show Gist options
  • Save nrjn/db95428ccac8eaa90fad2df66d4c57aa to your computer and use it in GitHub Desktop.
Save nrjn/db95428ccac8eaa90fad2df66d4c57aa to your computer and use it in GitHub Desktop.
I2C device driver for BMP180 environmental sensor
#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;
}
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