Честно говоря, не в курсе, каков алгоритм расчетов внутри самого датчика. Да и зачем?
BMP280, датчик давления и температуры
- Сообщения: 768
- Зарегистрирован: Вс янв 19, 2014 00:55:09
t_fine используется в расчетах давления, а также влажности и качества воздуха, если датчик имеет эти плюшки, как температурный корректор. По этой причине в Вашем (и любом) коде температуру нужно считать в первую очередь, чтобы "оживить" эту переменную.
Честно говоря, не в курсе, каков алгоритм расчетов внутри самого датчика. Да и зачем?
Честно говоря, не в курсе, каков алгоритм расчетов внутри самого датчика. Да и зачем?
- Реклама
- Сообщения: 63
- Зарегистрирован: Сб янв 10, 2015 12:05:52
Только не смейтесь . . . Мне попался датчик для ардуино BMP280 и я хочу приспособить его к ПИК'у. SPI мне знаком, действия с 16разрядными числами тоже, datasheet ВМР прочитал от корки до корки. Если смогу сформулировать задачу, думаю справлюсь. Меня устроит самая низкая точность; просто интересно.
- Сообщения: 768
- Зарегистрирован: Вс янв 19, 2014 00:55:09
Да какой смех? Нормальные вопросы. Я и сам считаю себя дилетантом в этих китайских железках. 
- Сообщения: 12
- Зарегистрирован: Вт фев 21, 2023 08:01:54
Все в моей метеостанции работало отлично, но ВМ280 начал выдавать отрицательное давление и влажность 100%...
Кто-нибудь сталкивался с такими показателями ?
Кто-нибудь сталкивался с такими показателями ?
У меня после сброса питания измерение влажности не проходят и значения плавают около 72%. Но после второй инициализации (сбрасываю микроконтроллер) - измеряет корректно.
Считайте константы из датчика, затем сырые данные и результаты расчётов, чтобы было понятно, откуда может возникать ошибка.
Считайте константы из датчика, затем сырые данные и результаты расчётов, чтобы было понятно, откуда может возникать ошибка.
- Реклама
- Сообщения: 68
- Зарегистрирован: Пн май 04, 2015 12:30:18
И еще раз про проблему отрицательных температур.
Мне не понятно как 32 битном int может взяться 1 в 31 разряде при условии что данные с датчика приходят вообще в 20 битном виде?
Мне не понятно как 32 битном int может взяться 1 в 31 разряде при условии что данные с датчика приходят вообще в 20 битном виде?
[uquote="BDDW",url="/forum/viewtopic.php?p=4500459#p4500459"]Мне не понятно как 32 битном int может взяться 1 в 31 разряде при условии что данные с датчика приходят вообще в 20 битном виде?[/uquote]
Это как раз знаковый бит. Если в ём 1 - то тенпература отрицательная
Это как раз знаковый бит. Если в ём 1 - то тенпература отрицательная
Праграмный кот. Хожу по цыкалу кругом.
- Сообщения: 68
- Зарегистрирован: Пн май 04, 2015 12:30:18
Проблема отрицательных температур - РЕШЕНА!
И так, что бы понять, что и где меняет знак, я вывел данные из модуля в десятичном и двоичном коде (данные собраны с нескольких логов, которые были сгенерированы в разное время):
dig_T1 28409 0110111011111001
dig_T2 26591 0110011111011111
dig_T3 50 0000000000110010
dig_P1 36817 1000111111010001
dig_P2 -10631 1101011001111001
dig_P3 3024 0000101111010000
dig_P4 6198 0001100000110110
dig_P5 -192 1111111101000000
dig_P6 -7 1111111111111001
dig_P7 9900 0010011010101100
dig_P8 -10230 1101100000001010
dig_P9 4285 0001000010111101
dig_H1 75 01001011
dig_H2 364 0000000101101100
dig_H3 0 00000000
dig_H4 315 0000000100111011
dig_H5 50 0000000000110010
dig_H6 30 00011110
T_raw 770881 00000000000010111100001101000001
Val1 513408 00000000000001111101010110000000
Val2 291 00000000000000000000000100100011
T_fine 513699 00000000000001111101011010100011
T 10033 00000000000000000010011100110001
P 749.301
H 0.000%
T_raw 722467 00000000000010110000011000100011
Val1 434830 00000000000001101010001010001110
Val2 208 00000000000000000000000011010000
T_fine 435038 00000000000001101010001101011110
T 8497 00000000000000000010000100110001
P 749.429
H 0.000%
T_raw 691286 00000000000010101000110001010110
Val1 384219 00000000000001011101110011011011
Val2 163 00000000000000000000000010100011
T_fine 384382 00000000000001011101110101111110
T 7507 00000000000000000001110101010011
P 749.231
H 0.000%
T_raw 615507 00000000000010010110010001010011
Val1 261235 00000000000000111111110001110011
Val2 75 00000000000000000000000001001011
T_fine 261310 00000000000000111111110010111110
T 5104 00000000000000000001001111110000
P 749.240
H 6.703%
T_raw 518922 00000000000001111110101100001010
Val1 104481 00000000000000011001100000100001
Val2 12 00000000000000000000000000001100
T_fine 104493 00000000000000011001100000101101
T 2041 00000000000000000000011111111001
P 745.099
H 25.223%
T_raw 457789 00000000000001101111110000111101
Val1 5258 00000000000000000001010010001010
Val2 0 00000000000000000000000000000000
T_fine 5258 00000000000000000001010010001010
T 103 00000000000000000000000001100111
P 745.393
H 21.098%
T_raw 455064 00000000000001101111000110011000
Val1 843 00000000000000000000001101001011
Val2 0 00000000000000000000000000000000
T_fine 843 00000000000000000000001101001011
T 16 00000000000000000000000000010000
P 745.409
H 21.790%
T_raw 454396 00000000000001101110111011111100
Val1 209690 00000000000111111111111100001001
Val2 0 00000000000000000000000000000000
T_fine 209690 00000000000111111111111100001001
T 40955 00000000000000001001111111111011
P 1154.772
H 0.000%
T_raw 453091 00000000000001101110100111100011
Val1 209478 00000000000111111111011011000100
Val2 0 00000000000000000000000000000000
T_fine 209478 00000000000111111111011011000100
T 40914 00000000000000001001111111010010
P 1155.549
H 0.000%
T_raw 451810 00000000000001101110010011100010
Val1 209271 00000000000111111110111010100111
Val2 0 00000000000000000000000000000000
T_fine 209271 00000000000111111110111010100111
T 40873 00000000000000001001111110101001
P 1156.318
H 0.000%
Как видно при переходе через ноль - появляется 1 в 20 разряде вычисляемой переменной Val1. Вот тут то и кроется корень зла. Это как раз и есть знаковый бит. Если в нём 1 - то температура отрицательная. Так же при переходе через 0 начинают врать давление и влажность.
Максимум который что может вычислить модуль - это 188,5 градусов, а минимум -143 градуса (+/- с моими коэффициентами dig_T1 - dig_T3).
Так же видно, что вычисляемая переменная Val2 - не может быть меньше 0.
По этому я добавил в код следующую строчку:
val1 = (((temper_raw>>3)-((int32_t)calibration_data.dig_T1<<1)))*((int32_t)calibration_data.dig_T2)>>11;
if (val1&(0x100000)) val1 |= 0xFFF00000;
val2 = (((((temper_raw>>4)-((int32_t)calibration_data.dig_T1))*((temper_raw>>4)-((int32_t)calibration_data.dig_T1)))>> 12)*((int32_t)calibration_data.dig_T3))>>14;
получилось:
Val1 3207 00000000000000000000110010000111
Val2 0 00000000000000000000000000000000
T_fine 3207 00000000000000000000110010000111
T 63 00000000000000000000000000111111
750.693
17.638
T_raw 455337 00000000000001101111001010101001
Val1 1285 00000000000000000000010100000101
Val2 0 00000000000000000000000000000000
T_fine 1285 00000000000000000000010100000101
T 25 00000000000000000000000000011001
750.704
17.889
T_raw 454757 00000000000001101111000001100101
Val1 337 00000000000000000000000101010001
Val2 0 00000000000000000000000000000000
T_fine 337 00000000000000000000000101010001
T 7 00000000000000000000000000000111
750.711
18.020
T_raw 454180 00000000000001101110111000100100
Val1 -598 11111111111111111111110110101010
Val2 0 00000000000000000000000000000000
T_fine -598 11111111111111111111110110101010
T -12 11111111111111111111111111110100
750.719
18.130
T_raw 453045 00000000000001101110100110110101
Val1 -2441 11111111111111111111011001110111
Val2 0 00000000000000000000000000000000
T_fine -2441 11111111111111111111011001110111
T -48 11111111111111111111111111010000
750.741
18.391
T_raw 452484 00000000000001101110011110000100
Val1 -3350 11111111111111111111001011101010
Val2 0 00000000000000000000000000000000
T_fine -3350 11111111111111111111001011101010
T -65 11111111111111111111111110111111
750.748
18.511
T_raw 451931 00000000000001101110010101011011
Val1 -4246 11111111111111111110111101101010
Val2 0 00000000000000000000000000000000
T_fine -4246 11111111111111111110111101101010
T -83 11111111111111111111111110101101
750.745
18.632
T_raw 451385 00000000000001101110001100111001
Val1 -5129 11111111111111111110101111110111
Val2 0 00000000000000000000000000000000
T_fine -5129 11111111111111111110101111110111
T -100 11111111111111111111111110011100
750.773
18.751
P.S. "Особо одаренным личностям" рекомендую сначала научиться читать, а затем писать.... Ну, если не получается одновременно.
И так, что бы понять, что и где меняет знак, я вывел данные из модуля в десятичном и двоичном коде (данные собраны с нескольких логов, которые были сгенерированы в разное время):
Спойлер
Startdig_T1 28409 0110111011111001
dig_T2 26591 0110011111011111
dig_T3 50 0000000000110010
dig_P1 36817 1000111111010001
dig_P2 -10631 1101011001111001
dig_P3 3024 0000101111010000
dig_P4 6198 0001100000110110
dig_P5 -192 1111111101000000
dig_P6 -7 1111111111111001
dig_P7 9900 0010011010101100
dig_P8 -10230 1101100000001010
dig_P9 4285 0001000010111101
dig_H1 75 01001011
dig_H2 364 0000000101101100
dig_H3 0 00000000
dig_H4 315 0000000100111011
dig_H5 50 0000000000110010
dig_H6 30 00011110
T_raw 770881 00000000000010111100001101000001
Val1 513408 00000000000001111101010110000000
Val2 291 00000000000000000000000100100011
T_fine 513699 00000000000001111101011010100011
T 10033 00000000000000000010011100110001
P 749.301
H 0.000%
T_raw 722467 00000000000010110000011000100011
Val1 434830 00000000000001101010001010001110
Val2 208 00000000000000000000000011010000
T_fine 435038 00000000000001101010001101011110
T 8497 00000000000000000010000100110001
P 749.429
H 0.000%
T_raw 691286 00000000000010101000110001010110
Val1 384219 00000000000001011101110011011011
Val2 163 00000000000000000000000010100011
T_fine 384382 00000000000001011101110101111110
T 7507 00000000000000000001110101010011
P 749.231
H 0.000%
T_raw 615507 00000000000010010110010001010011
Val1 261235 00000000000000111111110001110011
Val2 75 00000000000000000000000001001011
T_fine 261310 00000000000000111111110010111110
T 5104 00000000000000000001001111110000
P 749.240
H 6.703%
T_raw 518922 00000000000001111110101100001010
Val1 104481 00000000000000011001100000100001
Val2 12 00000000000000000000000000001100
T_fine 104493 00000000000000011001100000101101
T 2041 00000000000000000000011111111001
P 745.099
H 25.223%
T_raw 457789 00000000000001101111110000111101
Val1 5258 00000000000000000001010010001010
Val2 0 00000000000000000000000000000000
T_fine 5258 00000000000000000001010010001010
T 103 00000000000000000000000001100111
P 745.393
H 21.098%
T_raw 455064 00000000000001101111000110011000
Val1 843 00000000000000000000001101001011
Val2 0 00000000000000000000000000000000
T_fine 843 00000000000000000000001101001011
T 16 00000000000000000000000000010000
P 745.409
H 21.790%
T_raw 454396 00000000000001101110111011111100
Val1 209690 00000000000111111111111100001001
Val2 0 00000000000000000000000000000000
T_fine 209690 00000000000111111111111100001001
T 40955 00000000000000001001111111111011
P 1154.772
H 0.000%
T_raw 453091 00000000000001101110100111100011
Val1 209478 00000000000111111111011011000100
Val2 0 00000000000000000000000000000000
T_fine 209478 00000000000111111111011011000100
T 40914 00000000000000001001111111010010
P 1155.549
H 0.000%
T_raw 451810 00000000000001101110010011100010
Val1 209271 00000000000111111110111010100111
Val2 0 00000000000000000000000000000000
T_fine 209271 00000000000111111110111010100111
T 40873 00000000000000001001111110101001
P 1156.318
H 0.000%
Максимум который что может вычислить модуль - это 188,5 градусов, а минимум -143 градуса (+/- с моими коэффициентами dig_T1 - dig_T3).
Так же видно, что вычисляемая переменная Val2 - не может быть меньше 0.
По этому я добавил в код следующую строчку:
val1 = (((temper_raw>>3)-((int32_t)calibration_data.dig_T1<<1)))*((int32_t)calibration_data.dig_T2)>>11;
if (val1&(0x100000)) val1 |= 0xFFF00000;
val2 = (((((temper_raw>>4)-((int32_t)calibration_data.dig_T1))*((temper_raw>>4)-((int32_t)calibration_data.dig_T1)))>> 12)*((int32_t)calibration_data.dig_T3))>>14;
получилось:
Спойлер
T_raw 456527 00000000000001101111011101001111Val1 3207 00000000000000000000110010000111
Val2 0 00000000000000000000000000000000
T_fine 3207 00000000000000000000110010000111
T 63 00000000000000000000000000111111
750.693
17.638
T_raw 455337 00000000000001101111001010101001
Val1 1285 00000000000000000000010100000101
Val2 0 00000000000000000000000000000000
T_fine 1285 00000000000000000000010100000101
T 25 00000000000000000000000000011001
750.704
17.889
T_raw 454757 00000000000001101111000001100101
Val1 337 00000000000000000000000101010001
Val2 0 00000000000000000000000000000000
T_fine 337 00000000000000000000000101010001
T 7 00000000000000000000000000000111
750.711
18.020
T_raw 454180 00000000000001101110111000100100
Val1 -598 11111111111111111111110110101010
Val2 0 00000000000000000000000000000000
T_fine -598 11111111111111111111110110101010
T -12 11111111111111111111111111110100
750.719
18.130
T_raw 453045 00000000000001101110100110110101
Val1 -2441 11111111111111111111011001110111
Val2 0 00000000000000000000000000000000
T_fine -2441 11111111111111111111011001110111
T -48 11111111111111111111111111010000
750.741
18.391
T_raw 452484 00000000000001101110011110000100
Val1 -3350 11111111111111111111001011101010
Val2 0 00000000000000000000000000000000
T_fine -3350 11111111111111111111001011101010
T -65 11111111111111111111111110111111
750.748
18.511
T_raw 451931 00000000000001101110010101011011
Val1 -4246 11111111111111111110111101101010
Val2 0 00000000000000000000000000000000
T_fine -4246 11111111111111111110111101101010
T -83 11111111111111111111111110101101
750.745
18.632
T_raw 451385 00000000000001101110001100111001
Val1 -5129 11111111111111111110101111110111
Val2 0 00000000000000000000000000000000
T_fine -5129 11111111111111111110101111110111
T -100 11111111111111111111111110011100
750.773
18.751
- Сообщения: 68
- Зарегистрирован: Пн май 04, 2015 12:30:18
Кто ни будь работал с этими модулями по SPI шине?
Не понятно как работать с R/W регистрами?
Посылка данных по SPI:
{
PORTB &= ~(1<<PORTB2); //устанавливаем в 0 ножкe выбора устройства.
SPDR = data;
while(!(SPSR & (1<<SPIF))); //подождем пока данные передадутся
}
Чтение данных из регистра:
{
uint8_t Data_bme280;
BME280_send(reg);
BME280_send(0);
Data_bme280=SPDR;
PORTB |= 1<<PORTB2;
asm ("NOP");
PORTB &= ~(1<<PORTB2);
return Data_bme280;
}
А вот как организовать запись данных в регистр?
По идее:
BME280_send(reg);
BME280_send(Data);
PORTB |= 1<<PORTB2;
asm ("NOP");
PORTB &= ~(1<<PORTB2);
Но ведь это ничем не отличается от чтения данных из регистра....
Не понятно как работать с R/W регистрами?
Посылка данных по SPI:
Спойлер
void BME280_send (uint8_t data){
PORTB &= ~(1<<PORTB2); //устанавливаем в 0 ножкe выбора устройства.
SPDR = data;
while(!(SPSR & (1<<SPIF))); //подождем пока данные передадутся
}
Спойлер
uint8_t BME280_read (uint8_t reg){
uint8_t Data_bme280;
BME280_send(reg);
BME280_send(0);
Data_bme280=SPDR;
PORTB |= 1<<PORTB2;
asm ("NOP");
PORTB &= ~(1<<PORTB2);
return Data_bme280;
}
По идее:
BME280_send(reg);
BME280_send(Data);
PORTB |= 1<<PORTB2;
asm ("NOP");
PORTB &= ~(1<<PORTB2);
Но ведь это ничем не отличается от чтения данных из регистра....
Даташит тебе прочитать влом.
Ну я прочитал. Подсказка: "Седьмой бит адреса". Дальше сам.
Ну я прочитал. Подсказка: "Седьмой бит адреса". Дальше сам.
- Сообщения: 68
- Зарегистрирован: Пн май 04, 2015 12:30:18
К сожалению я читал перевод. Плохо понимаю по англицки. А перевод оказался не полным. Там заканчивается пунктом 6.2.2 (I2C шина).....
Полез в оригинал. И, таки да, при записи обнуляется старший бит адреса регистра.... Вот уже о чем не мог подумать. И еще, что бросилось в глаза - все адреса регистров начинаются с 88, а не с 0 т.е. 1 в старшем бите всегда присутствует. и ее обнуление - не приведет к путанице с адресами регистров.
Теперь (для таких же как я) функция записи выглядит так:
{
reg &=0x7F;
BME280_send(reg);
BME280_send(data);
}
И еще вопросы
1) стоит ли дергать CS после завершения записи?
2) оверсемплинг - повышает точность измерений и увеличивает время измерения?
3) Как работает БИХ фильтр? Производится несколько измерений и вычисляется достоверное?
Полез в оригинал. И, таки да, при записи обнуляется старший бит адреса регистра.... Вот уже о чем не мог подумать. И еще, что бросилось в глаза - все адреса регистров начинаются с 88, а не с 0 т.е. 1 в старшем бите всегда присутствует. и ее обнуление - не приведет к путанице с адресами регистров.
Теперь (для таких же как я) функция записи выглядит так:
Спойлер
void BME280_write (uint8_t reg, uint8_t data){
reg &=0x7F;
BME280_send(reg);
BME280_send(data);
}
1) стоит ли дергать CS после завершения записи?
2) оверсемплинг - повышает точность измерений и увеличивает время измерения?
3) Как работает БИХ фильтр? Производится несколько измерений и вычисляется достоверное?
1) По даташиту CS опускается перед записью и поднимается после. Можно записывать несколько значений и потом поднимать CS.
2) да
3) лучше почитай мурзилку. Это фильтр с бесконечной импульсной функцией.
2) да
3) лучше почитай мурзилку. Это фильтр с бесконечной импульсной функцией.
- Сообщения: 511
- Зарегистрирован: Пт окт 28, 2011 16:01:18
Прикупил BMP180, китайская ардуинодоска.
Почитал сырые значения отладчиком - похожи на правду, но эффективная разрядность АЦП около 14 бит, как на давлении, так и на температуре, остальное - шумы.
Это для них норм? В заявленное Бошевским даташитом разрешение, вроде приблизительно укладывается.
Встроенный оверсемплинг - похоже дурь какая то, ни чего не дает, те же 14 старших бит, остальное - шум.
Третий байт читать вообще бессмысленно.
Может китайский "аналог" попался?
Надо читать много измерений и усреднять.
Будьте осторожны!
Все платы на рынке, которые посмотрел, заявляемые как якобы 5в совместимые, имели на борту только LDO, преобразователи уровней отсутствуют, датчик на 5в шине может сгореть при первом же включении!
Почитал сырые значения отладчиком - похожи на правду, но эффективная разрядность АЦП около 14 бит, как на давлении, так и на температуре, остальное - шумы.
Это для них норм? В заявленное Бошевским даташитом разрешение, вроде приблизительно укладывается.
Встроенный оверсемплинг - похоже дурь какая то, ни чего не дает, те же 14 старших бит, остальное - шум.
Третий байт читать вообще бессмысленно.
Может китайский "аналог" попался?
Надо читать много измерений и усреднять.
Будьте осторожны!
Все платы на рынке, которые посмотрел, заявляемые как якобы 5в совместимые, имели на борту только LDO, преобразователи уровней отсутствуют, датчик на 5в шине может сгореть при первом же включении!
Вот - я немножко сравнил несколько разных датчиков температуры-давления-влажности.
Точность у всех паршивая, а при влажности <20% или >90% каждый по-своему врать начинает. Например, один BME280 показывает 100% до тех пор, пока влажность ниже примерно 80% не опустится… Другой тоже привирает, но не так сильно.
BMP180 - совсем уж люто врет порой.
К 5В подключать не пробовал, т.к. микроконтроллеры с напряжением питания 5В - каменный век. Даже МК с напряжением питания 3.3В уже - какой-то бронзовый…
Точность у всех паршивая, а при влажности <20% или >90% каждый по-своему врать начинает. Например, один BME280 показывает 100% до тех пор, пока влажность ниже примерно 80% не опустится… Другой тоже привирает, но не так сильно.
BMP180 - совсем уж люто врет порой.
К 5В подключать не пробовал, т.к. микроконтроллеры с напряжением питания 5В - каменный век. Даже МК с напряжением питания 3.3В уже - какой-то бронзовый…
Windows must die!
- Сообщения: 511
- Зарегистрирован: Пт окт 28, 2011 16:01:18
Выкинул LDO, подключил к чистой 3,3в шине, значительных изменений нет.
С влажностью у всех этих датчиков беда, как я понял. Но мне пока нужно только давление.
Еще в этой теме кажется забыли напомнить, в доке сказано что датчик светочувствителен. Это может влиять на показания.
Не совсем понял про механическую развязку (рекомендации по пайке).
Это про механические напряжения, про вибрации, или дно датчика не жесткое, ему нужно куда то прогибаться?
В конечном счете, зазор под датчиком можно чем то залить, для более надежной работы на улице?
При условии, что микроплата с ним, будет закреплена на какой нибудь резинке.
С влажностью у всех этих датчиков беда, как я понял. Но мне пока нужно только давление.
Еще в этой теме кажется забыли напомнить, в доке сказано что датчик светочувствителен. Это может влиять на показания.
Не совсем понял про механическую развязку (рекомендации по пайке).
Это про механические напряжения, про вибрации, или дно датчика не жесткое, ему нужно куда то прогибаться?
В конечном счете, зазор под датчиком можно чем то залить, для более надежной работы на улице?
При условии, что микроплата с ним, будет закреплена на какой нибудь резинке.


