Skip to content

Instantly share code, notes, and snippets.

@cho0h5
Last active October 27, 2022 06:56
Show Gist options
  • Save cho0h5/2a9fa8e9827664a7a31c8cb43e6f1ef9 to your computer and use it in GitHub Desktop.
Save cho0h5/2a9fa8e9827664a7a31c8cb43e6f1ef9 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
struct calibration_data {
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;
int32_t B3;
uint32_t B4;
int32_t B5;
int32_t B6;
uint32_t B7;
};
void get_calibration_data(struct calibration_data *data) {
uint8_t buf[22];
buf[0] = 0xAA;
i2c_write_blocking(i2c_default, 0x77, buf, 1, true);
i2c_read_blocking(i2c_default, 0x77, buf, 22, false);
data->AC1 = (buf[0] << 8) | buf[1];
data->AC2 = (buf[2] << 8) | buf[3];
data->AC3 = (buf[4] << 8) | buf[5];
data->AC4 = (buf[6] << 8) | buf[7];
data->AC5 = (buf[8] << 8) | buf[9];
data->AC6 = (buf[10] << 8) | buf[11];
data->B1 = (buf[12] << 8) | buf[13];
data->B2 = (buf[14] << 8) | buf[15];
data->MB = (buf[16] << 8) | buf[17];
data->MC = (buf[18] << 8) | buf[19];
data->MD = (buf[20] << 8) | buf[21];
}
int32_t read_uncompensated_temperature_value() {
uint8_t buf[2];
buf[0] = 0xF4;
buf[1] = 0x2E;
i2c_write_blocking(i2c_default, 0x77, buf, 2, false);
sleep_ms(5);
buf[0] = 0xF6;
i2c_write_blocking(i2c_default, 0x77, buf, 1, true);
i2c_read_blocking(i2c_default, 0x77, buf, 2, false);
return (buf[0] << 8) | buf[1];
}
int32_t read_uncompensated_pressure_value() {
uint8_t buf[3];
int16_t oss = 0;
buf[0] = 0xF4;
buf[1] = 0x34 + (oss << 6);
i2c_write_blocking(i2c_default, 0x77, buf, 2, false);
sleep_ms(26);
buf[0] = 0xF6;
i2c_write_blocking(i2c_default, 0x77, buf, 1, true);
i2c_read_blocking(i2c_default, 0x77, buf, 3, false);
return (buf[0] << 16 | buf[1] << 8 | buf[2]) >> (8 - oss);
}
int32_t calculate_true_temperature(struct calibration_data *data, int32_t raw_temp) {
int32_t X1 = ((raw_temp - data->AC6) * data->AC5) >> 15;
int32_t X2 = (data->MC << 11) / (X1 + data->MD);
data->B5 = X1 + X2;
int32_t true_temp = (data->B5 + 8) >> 4;
return true_temp;
}
int32_t calculate_true_pressure(struct calibration_data *data, int32_t raw_pres) {
int16_t oss = 0;
data->B6 = data->B5 - 4000;
int32_t X1 = (data->B2 * ((data->B6 * data->B6) >> 12)) >> 11;
int32_t X2 = (data->AC2 * data->B6) >> 11;
int32_t X3 = X1 + X2;
data->B3 = (((data->AC1 << 2 + X3) << oss) + 2) >> 2;
X1 = (data->AC3 * data->B6) >> 13;
X2 = (data->B1 * ((data->B6 * data->B6) >> 12)) >> 16;
X3 = ((X1 + X2) + 2) >> 2;
data->B4 = (data->AC4 * (uint32_t)(X3 + 32768)) >> 15;
data->B7 = ((uint32_t)raw_pres - data->B3) * (50000 >> oss);
int32_t p;
if(data->B7 < 0x80000000) p = (data->B7 << 1) / data->B4;
else p = (data->B7 / data->B4) << 1;
X1 = (p >> 8) * (p >> 8);
X1 = (X1 * 3038) >> 16;
X2 = (-7357 * p) >> 16;
int32_t true_pres = p + ((X1 + X2 + 3791) >> 4);
return true_pres;
}
int main()
{
stdio_init_all();
sleep_ms(3000);
i2c_init(i2c_default, 100 * 1000);
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
struct calibration_data data;
get_calibration_data(&data);
int32_t raw_temp = read_uncompensated_temperature_value();
int32_t raw_pres = read_uncompensated_pressure_value();
printf("raw_temp: %d\n", raw_temp);
printf("raw_pres: %d\n\n", raw_pres);
int32_t true_temp = calculate_true_temperature(&data, raw_temp);
int32_t true_pres = calculate_true_pressure(&data, raw_temp);
printf("true_temp: %d\n", true_temp);
printf("true_pres: %d\n", true_pres);
return 0;
}
// stdio
// raw_temp: 27964
// raw_pres: 42984
//
// true_temp: 232
// true_pres: 83113
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment