Jump to content

Tibman

Members
  • Posts

    150
  • Joined

  • Last visited

Everything posted by Tibman

  1. Tibman

    STM32 и BME280

    Да, всё верно. Из функции отправляя temper_float в терминал, показывается правильное значение, temper_float = 21.68. А возвращенное из функции через return аналогичное значение отображается через main как temper_float=1101885568.00. temper_int объявлена ранее в файле с функцией.
  2. Tibman

    STM32 и BME280

    Ой, точно, ошибся. Спасибо. Теперь функция имеет следующий вид: 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; //sprintf(str1, "Temperature RAW: 0x%08X\r\n", temper_raw); //HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); 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.00f; sprintf(str1, "Temperature: %.2f *C\r\n", temper_float); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); return temper_float; } Я сделал вывод данных в терминал непосредственно в этой функции. И в таком виде температура приходит правильная. В результате такой вот результат: Temperature: 21.68 *C Temperature: 1101885568.00 *C Верхнее значение выведено в терминал непосредственно из функции чтения температуры, а нижнее - из main.c. Но тогда я не могу понять, почему тогда аналогичная конструкция, размещенная в main.c, выдаёт неправильные значения. Там же ведь значение temper_float, рассчитанное в функции, просто приравнивается к значению переменной tf. tf = BME280_ReadTemperature(); sprintf(str1, "Temperature: %.2f *C\r\n", tf); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000);
  3. Tibman

    STM32 и BME280

    Переписал в очередной раз функцию расчета температуры: 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; sprintf(str1, "Temperature RAW: 0x%08X\r\n", temper_raw); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); 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; sprintf(str1, "Temperature predv1: 0x%08X\r\n", temper_int); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); temper_int = ((temper_int * 5 + 128) >> 8); sprintf(str1, "Temperature predv2: 0x%08X\r\n", temper_int); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); temper_float = temper_int/100; return temper_float; } Результат: Temperature RAW: 0x0007D472 - данные непосредственно с датчика Temperature predv1: 0x0001B0F9 - это val1 + val2 Temperature predv2: 0x00000875 - это уже значение temp_int перед его делением на 100 и переводом во float. Temperature: 1101529088.000 *C - полная ерунда в итоге. Если перевести 0x00000875 в десятичный формат, то получается 2165, что после деления на 100 дало бы в результате 21.65 градуса Цельсия, то есть целочисленные расчеты производятся правильно. К датчику и его работе нет никаких претензий. Остаётся только правильно поделить на 100 и вывести в терминал. Но почему-то возникает проблема со значением float. В main.c вывод значения в терминал: tf = BME280_ReadTemperature(); sprintf(str1, "Temperature: %.3f *C\r\n", tf); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); Этот код нормально работает, если на вход подавать что-то вроде 20.36 или тому подобного. Но вот значение temper_float он явно воспринимает как-то не так. Я так и не могу понять, как из 16-ричного значения датчика должно получиться 10-тичное значение, да ещё и дробное.
  4. Tibman

    STM32 и BME280

    Спасибо, действительно это отличный способ убедиться в правильности вывода в терминал. Просто вывел через терминал дробное значение: zf = 60.28; sprintf(str1, "Test: %.3f *C\r\n", zf); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); Результат: Test: 60.280 *C То есть эта часть тоже работает правильно. В таком случае получается, что вся "магия" творится в этой части кода: temper_float = ((temper_int * 5 + 128) / 256); temper_float = temper_float/100.0f; Причем, считая на калькуляторе, если temper_int сразу перевести в десятичную систему, а потом умножать и делить, то результат очень похож на правду. А если произвести все расчеты в шестнадцатиричной системе, а потом переводить в десятичную, то получается ерунда, хотя и не такая, как выводится в терминал.
  5. Tibman

    STM32 и BME280

    Благодарю за ссылку, интересная информация. Переписал формулу для расчета температуры следующим образом: 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; sprintf(str1, "Temperature RAW: 0x%08X\r\n", temper_raw); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); val1 = temper_raw/ 8 - 27746*2; val1 = (val1 * 26240) / 2048; val2 = temper_raw / 16 - 27746; val2 = ((val2*val2) / 4096) * 50 / 16384; temper_int = val1 + val2; sprintf(str1, "Temperature predv: 0x%08X\r\n", temper_int); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); temper_float = ((temper_int * 5 + 128) / 256); temper_float = temper_float/100.0f; return temper_float; } Для интереса вывожу в терминал и переменную temper_int. Вот такие результаты: Temperature RAW: 0x0007DCDB Temperature predv: 0x0001BE70 Temperature: 1102221184.000 *C Берем это число 0x0001BE70, и переводим в десятичный формат, получаем 114228. Умножаем на 5, прибавляем 128, и всё это делим на 256. Результат = 2232. Делим на 100, и получаем 22,32. Вроде по числам получается что-то вполне похожее на комнатную температуру. Правильно ли я понимаю, что сама процедура пересчета работает вполне себе корректно, как минимум при расчете temper_int? Но в терминале-то у меня отображается вовсе не такое значение, а какая-то ерунда. И похоже, проблема возникает на этапе расчета temper_float, или вывода его в терминал.
  6. Кармин Новиелло- ОсвоениеSTM32. Но тут уклон в использование HAL.
  7. Tibman

    STM32 и BME280

    Ага, как раз информацию с этого сайта и использовал для работы с датчиком.
  8. Tibman

    STM32 и BME280

    Здравствуйте! Осваиваю работу с датчиком BME280. Настраивал через Hal в CubeIDE, следуя примеру с одного из сайтов. Связь с датчиком есть, калибровочные коэффициенты считываются, и сырые данные тоже приходят. Но не могу корректно преобразовать эти результаты в адекватные значения температуры, а следовательно, и остальные параметры (влажность и давление) также рассчитываются (или отображаются) неправильно. В кубе пришлось включить в настройках проекта "use newlib-nano to print floating numbers". В терминале получаю следующие результаты: Temperature RAW: 0x0007E071 Temperature: 1102373248.000 *C Вот используемая функция для расчета температуры. Изначально в формуле были указаны переменные типа DIG_T1 и т. п. Я внёс эти прочитанные коэффициенты в формулу, так как датчик всё равно один. 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; sprintf(str1, "Temperature RAW: 0x%08X\r\n", temper_raw); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); val1 = ((((temper_raw>>3) - (27746 <<1)))*(26240)) >> 11; val2 = (((((temper_raw>>4) - (27746))*((temper_raw>>4) - (27746))) >> 12)*(50)) >> 14; temper_int = val1 + val2; temper_float = ((temper_int * 5 + 128) >> 8); temper_float = temper_float/100.0f; return temper_float; } Код для передачи по UART из файла main: tf = BME280_ReadTemperature(); sprintf(str1, "Temperature: %.3f *C\r\n", tf); HAL_UART_Transmit(&huart1,(uint8_t*)str1,strlen(str1),0x1000); Вот константы, считанные с датчика: DIG_T1: 27746 DIG_T2: 26240 DIG_T3: 50 DIG_P1: 35880 DIG_P2: -10656 DIG_P3: 3024 DIG_P4: 5317 DIG_P5: 139 DIG_P6: -7 DIG_P7: 9900 DIG_P8: -10230 DIG_P9: 4285 DIG_H1: 75 DIG_H2: 370 DIG_H3: 0 DIG_H4: 299 DIG_H5: 50 DIG_H6: 0 Прошу помочь разобраться, куда копать. У меня опыт небольшой. Датчик реагирует на изменения температуры. Явно какая-то ошибка уже на последнем этапе, при преобразовании сырого значения с датчика. Формулу сравнивал с даташитом. Либо всё же где-то в формуле что-то не так, что маловероятно, либо неправильно отправляю данные в терминал, точнее как-то неправильно их отображаю.
×
×
  • Create New...