Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Re: BMP280, датчик давления и температуры

Чт ноя 29, 2018 09:01:33

А для эксперимента пока нет возможности вынести датчик на улицу.

А что морозильника нет? Или просто куска льда в пакете чтобы приложить к датчику? )

Re: BMP280, датчик давления и температуры

Чт ноя 29, 2018 09:37:05

Получается, что ни кто не пробовал датчик BME280 при отрицательных температурах? Печалька :(

Re: BMP280, датчик давления и температуры

Чт ноя 29, 2018 09:43:03

А что морозильника нет? Или просто куска льда в пакете чтобы приложить к датчику? )

Морозильника нет. Я дома электроникой не занимаюсь, у меня мастерская отдельная для этого, либо на работе, к тому же датчик уже стоит в устройстве и закрыт в корпусе.

Re: BMP280, датчик давления и температуры

Пт ноя 30, 2018 11:27:22

Ну вроде победил проблему :) Поменял формат переменной BME280_S32_t t_fine с 32 на 64 и все поехало. Получается на положительные значения int32 хватало, а при отрицательных уходил в нирвану. В общем прихлебывая валерьянку, курим даташит. :))

Re: BMP280, датчик давления и температуры

Сб дек 15, 2018 22:32:36

Не очень понятно. t_fine вроде бы используется в конце вычислений:
t_fine = var1 + var2;
T = (t_fine * 5 +128) >> 8;
return T;
var1, var2 и T имеют тип BME_280_S32_t и они не переполняются, так как Вы их не меняли.
Неужели var1 и var2 близки к максимуму и их сумма переполняется? Или может быть засада в том, что переполнение происходит во время умножения на 5 и возможно достаточно написать по-другому последнее выражение:
T = (int32_t)((((int64_t)t_fine) * 5) >> 8 ) ;
Ну или что-то в этом роде... Впрочем, похоже что это тоже самое, что сделали Вы, только другим способом. Жаль, что я сейчас не могу вытащить датчик на мороз, надо бы погонять в отладчике пошагово и понаблюдать за вычислениями.

Re: BMP280, датчик давления и температуры

Вс янв 20, 2019 16:21:01

Самое интересное, что с ошибкой отрицательных температур библиотеки bosh судя по поиску в инете мало кто столкнулся, люди похоже в основном используют в помещениях. Я блин аж второй датчик на Али купил и упёрся в те же грабли. Как уходит Т в минус, то на входе 400 и выше градусов.
passer_by не могли бы вы выложить свой кусок кода, где приведение к 64 битам делаете.

Re: BMP280, датчик давления и температуры

Чт янв 31, 2019 22:02:49

Не очень понятно. t_fine вроде бы используется в конце вычислений:
достаточно написать по-другому последнее выражение:
T = (int32_t)((((int64_t)t_fine) * 5) >> 8 ) ;
Ну или что-то в этом роде... Впрочем, похоже что это тоже самое, что сделали Вы, только другим способом. Жаль, что я сейчас не могу вытащить датчик на мороз, надо бы погонять в отладчике пошагово и понаблюдать за вычислениями.


Попробовал. Не взлетело.. Всё также при минусах температура за 400 выходит.
Где-то на гитхабе попадалась библиотека для этого датчика полностью на 64 бита заточенная

Re: BMP280, датчик давления и температуры

Пн фев 04, 2019 19:39:23

Наконец то я нашел время и проверил работу при отрицательных температурах. У меня все нормально работает. Проблем не было.
Вот прилагаю вырезку из своего кода. В функции PreesAndTemp я просто проверяю температуру больше она или меньше ноля и убираю или добавляю соответственно знак минуса и пихаю все это на дисплей.
Расчет температуры и давления взят из datasheet, данные библиотеки не изменялись, они оригинальные.

Re: BMP280, датчик давления и температуры

Вт фев 05, 2019 14:57:35

passer_by не могли бы вы выложить свой кусок кода, где приведение к 64 битам делаете.

Вот код:
Код:
int64_t temper_int;   //глобальная переменная
...........................
.............................
float BME280_ReadTemperature(void)
{

  float temper_float = 0.0f;
   uint32_t temper_raw;
   int32_t val1, val2;
   BME280_ReadReg_BE_U24(BME280_REGISTER_TEMPDATA,&temper_raw);
   temper_raw >>= 4;
   val1 = ((((temper_raw>>3) - ((int32_t)CalibData.dig_T1 <<1))) *
      ((int32_t)CalibData.dig_T2)) >> 11;
   val2 = (((((temper_raw>>4) - ((int32_t)CalibData.dig_T1)) *
      ((temper_raw>>4) - ((int32_t)CalibData.dig_T1))) >> 12) *
      ((int32_t)CalibData.dig_T3)) >> 14;
   temper_int = val1 + val2;
   temper_int = ((temper_int * 5 + 128) >> 8);
   temper_float = temper_int/100;
   
  if (temper_float >100) // если значение температуры перевалило в отрицательные значения
  {
    temper_float = 409.6-temper_float;
    temper_float = -temper_float;
  }   
   
  return temper_float;
}

Обратите внимание. Переменная int64_t temper_int это BME280_S32_t t_fine по даташиту, используется и в расчете давления и влажности.

to DESIER
Раз работает код как у DS18B20 это говорит о том что формат значения температуры на выходе у датчиков одинаков.
К стате, как я понял Ваш код, Вы делаете ровно то же самое, только вместо двух строчек кода довольно громоздкая структура.

Re: BMP280, датчик давления и температуры

Пт фев 08, 2019 20:20:27

Код:
int64_t temper_int;   //глобальная переменная
...........................
.............................
float BME280_ReadTemperature(void)
{

  float temper_float = 0.0f;
   uint32_t temper_raw;
   int32_t val1, val2;
   BME280_ReadReg_BE_U24(BME280_REGISTER_TEMPDATA,&temper_raw);
   temper_raw >>= 4;
   val1 = ((((temper_raw>>3) - ((int32_t)CalibData.dig_T1 <<1))) *
      ((int32_t)CalibData.dig_T2)) >> 11;
   val2 = (((((temper_raw>>4) - ((int32_t)CalibData.dig_T1)) *
      ((temper_raw>>4) - ((int32_t)CalibData.dig_T1))) >> 12) *
      ((int32_t)CalibData.dig_T3)) >> 14;
   temper_int = val1 + val2;
   temper_int = ((temper_int * 5 + 128) >> 8);
   temper_float = temper_int/100;
   
  if (temper_float >100) // если значение температуры перевалило в отрицательные значения
  {
    temper_float = 409.6-temper_float;
    temper_float = -temper_float;
  }   
   
  return temper_float;
}


to DESIER
Раз работает код как у DS18B20 это говорит о том что формат значения температуры на выходе у датчиков одинаков.
К стате, как я понял Ваш код, Вы делаете ровно то же самое, только вместо двух строчек кода довольно громоздкая структура.


Да у меня абсолютно тоже самое. В datasheet на датчик есть 2 варианта кода, код для расчетов с применением переменных с плавающей запятой и вариант для расчетов с целочисленными переменными.
Для 8-bit микроконтроллера расчеты с плавающей запятой занимают больше процессорного времени. Поэтому ваш вариант мне не подходит так как у меня простой 8-bit микроконтроллер. А вот если бы я использовал какой нибудь ARM, конечно же я использовал бы вариант как у вас.

Вот мой код для расчета температуры (из datasheet), я не вижу тут огромной структуры, наоборот, у меня даже меньше получается:
Код:
int32_t bmp280_compensate_T(int32_t adc_T)
{
   int32_t var1;
   int32_t var2;
   int32_t temperature = 0;
   var1 = ((((adc_T >> 3) - ((int32_t) dig_T1 << 1))) * ((int32_t) dig_T2)) >> 11;
   var2 = (((((adc_T >> 4) - ((int32_t) dig_T1)) * ((adc_T >> 4) - ((int32_t) dig_T1))) >> 12) * ((int32_t) dig_T3)) >> 14;
   t_fine = var1 + var2;
   temperature = (t_fine * 5 + 128) >> 8;
   return temperature;
}

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 12:38:55

Здоровья читателю.
Столкнулся с такой же проблемой с выводом отрицательных или около-нулевых температур. Вот лог:
Код:
temperature = 1.32 C
raw_temperature = 0x0006F840 := 456768

temperature = 1.27 C
raw_temperature = 0x0006F7A0 := 456608

temperature = 1.19 C
raw_temperature = 0x0006F6A0 := 456352

temperature = 1.02 C
raw_temperature = 0x0006F490 := 455824

temperature = 86 C
raw_temperature = 0x0006F280 := 455296

temperature = 85 C
raw_temperature = 0x0006F260 := 455264

temperature = 91 C
raw_temperature = 0x0006F320 := 455456

temperature = 88 C
raw_temperature = 0x0006F2D0 := 455376

temperature = 63 C
raw_temperature = 0x0006EFA0 := 454560

temperature = 58 C
raw_temperature = 0x0006EF20 := 454432

temperature = 65 C
raw_temperature = 0x0006EFE0 := 454624

temperature = 68 C
raw_temperature = 0x0006F040 := 454720

temperature = 3.64 C
raw_temperature = 0x00071500 := 464128

Датчик ВМР280 под снегом в пакете. :) Код с даташита, проверял 100500 раз, сверял с выкладками в этой теме, пробовал шаман-бубен здешний с удваиванием типа t_fine - ничего не помогает...
Вот по "raw_temperature" в логе (это 20-битный компот значений соответствующих регистров ВМР280), не понятно, когда температура становится отрицательной/нулевой?
Братцы, если кому удалось цивилизовано решить эту проблему, поделитесь волшебством пожалуйста.

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 12:45:33

Братцы, если кому удалось цивилизовано решить эту проблему, поделитесь волшебством пожалуйста.

Покажите ваш код, тогда подумаем. А так можно гадать долго. Я думаю что проблема в типах данных, возможно вы где то вместо int используете unsigned int в коде расчета.

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 13:19:30

DESIER, возможно "глаз замылился" и я просто не вижу ошибку.

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 14:17:32

DESIER, возможно "глаз замылился" и я просто не вижу ошибку.

А вот что вот это за функция? num2dec(_bmp280_temp, 2);
Она выводит переменную _bmp280_temp в знаковом типе?
Что то мне кажется дело в ней. Если осуществлять вывод информации в беззнаковом типе, будет вот такая байда.

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 14:44:27

DESIER писал(а):Что то мне кажется дело в ней.
Вот - да. Я на нее тоже грешу. Она самописная, а так как я не умею толком преобразовывать, вполне вероятна проблема в ней.
Код:
void num2dec(long arg, int fractionDigits){
   unsigned long dec = 1;
   int i = 0, index = 0,max = 0;
   char arr[16];
   memset(arr, 0, 16);
   while(dec < arg){
      dec *= 10;
      max ++;
   }
   if(max)   dec /= 10;
   if(fractionDigits && max > fractionDigits) max -= fractionDigits;
   while(dec){
      i = 0;
      if(index == max && fractionDigits) arr[index ++ ] = 0x2E; //   Symbol - "."
      while(dec <= arg){
         arg -= dec;
         i++;
      }
      arr[index++] = i + 48;
      dec /= 10;
   }
   uart_puts(arr);
}

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 14:57:57

MOHCTEP, я так понял это ардуино?! А в нем разве нельзя просто взять и отправить число в uart без вот таких танцев с бубнами?
Я с ардуино не работал и отладку я делаю через JTAG. Не могу понять для чего эта функция? Опишите в кратце что она делает.

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 15:27:06

DESIER Не-не, чур меня. :) Ни разу ардуино не доводилось видеть. Это Мега 8 + ВМР280 + USB-UART для отладки, а и + макетка.:)
DESIER писал(а):Не могу понять для чего эта функция? Опишите в кратце что она делает.
Задумывалась для преобразования любого числа (до 32 бит) в читабельный вид, с фиксированной точкой и отправки его в UART. Если есть какие-то стандартные вещи в си, для этого, не сильно отжирающие ресурсы и память, подскажите пожалуйста.

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 15:51:07

Ну вот например если отправлять побайтно.
допустим переменная t несет значение температуры в виде -567 на пример, это будет температура -5,67 гр.С
и какая либо функция uart(char) принимающая в качестве аргумента байт, записывая его на шину.
Код:
uint16_t t = temperatureBMP280;
if (t < 0) { t = -t; uart('-'); }
if (t >= 1000) uart(((t/1000)%10)+48);
uart(((t/100)%10)+48);
uart('.');
uart(((t/10)%10)+48);
uart((t%10)+48);
uart('°');
uart('C');


Может я что то и нагородил, но я вывожу на LCD дисплей по шине I2C именно таким методом. У меня вместо uart другая рисующая символ на дисплее функция выводит изображение в соответствии с кодировкой ASCII.
Или вот так:
Код:
void DesSend(int32_t n)
{
   uint16_t temp = 0;
   if (n < 0) { temp = -n; UDR = 45; }
        else temp = n;
   if (t >= 1000) UDR = ((temp/1000)%10)+48;
   UDR = ((temp/100)%10)+48;
   UDR = 46;
   UDR = ((temp/10)%10)+48;
   UDR = (temp%10)+48;
   UDR = 176;
   ADR = 67;
}

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 16:45:08

Я чуть откомментировал
По сути, вся верхняя возня придумана, чтоб не выводить левые нули при любой десятичной разрядности аргумента. Иначе говоря у вас код выведет температуру нормально, а давление в паскалях уже - проблема. По вашему коду есть вопросы.
1). "if (t < 0) { t = -t; uart('-'); }". Как это условие у вас срабатывает, если t - без знаковая(uint16_t)?
2) Покажите, ради хвоста, паяльника и прочих мимоз, как у вас выглядит эта самая "-567" в 16-ричном виде! Очень прошу. И главное куда этот долбаный минус засунулся в 32-битном результате даташитовских манипуляций? У вас все просто "if (n < 0)" = кайф! :) У меня, почему-то, эта самая "n" всегда больше нуля.

Re: BMP280, датчик давления и температуры

Ср мар 06, 2019 17:23:04

Не проще ли было воспользоваться если не sprintf(), то хотя бы itoa() или utoa()?
А если уж очень захотелось конвертировать из двоичку в десятичку самостоятельно, то лучше воспользоваться более быстрым алгоритмом, без деления. Например, тем же Double dabble.
Ответить