Last active
October 27, 2022 06:56
-
-
Save cho0h5/2a9fa8e9827664a7a31c8cb43e6f1ef9 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 "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