Преобразование 16 бит в число с плавающей запятой
Я пытаюсь связаться с AT30TS75A-MA8M-T с помощью приведенного ниже кода, проблема заключается в преобразовании 16-битного вывода в число с плавающей запятой, чтобы я мог читать temp:
На основе паспорта Я предполагаю удалить первые 5 бит, чтобы правильно читать, но я не конвертирую их правильно.
Пример: (0b001001001100000 И 0 b0111111111100000) = 0b1001001100000 0b1001001100000 >> 5 = 0b10010011 = 147
void Atemp::begin()
{
Wire.begin();
// Проверяем, доступен ли датчик температуры датчика
// если (mySensor.beginI2C() == false)
// {
// данные[9] = 5; // Код ошибки
// }
// Установить регистр для двух десятичных знаков
Wire.beginTransmission(_i2cAddress);
Wire.write(1);
Wire.write(0b01100000);
Wire.endTransmission();
}
void Atemp::read()
{
Wire.beginTransmission(_i2cAddress);
Wire.write(0);
result = Wire.endTransmission();
// результат 0-4
if (result != 0)
{
data[9] = 5; // Код ошибки
}
result = Wire.requestFrom(_i2cAddress, (uint8_t)2);
if (result != 2)
{
data[9] = 5; // Код ошибки
}
else
{
uint8_t part1 = Wire.read();
uint8_t part2 = Wire.read();
data[7] = part1;
data[8] = part2;
int16_t rawval = (part1 << 8 | part2) ;
// исходное значение >>= 6;
float temp = rawval / 256.0f;
floatconv(temp);
}
}
@Shahreza, 👍1
2 ответа
Лучший ответ:
Вам нужно сделать две вещи:
- Сдвиньте данные вправо, чтобы выровнять их справа от переменной, и
- Умножьте его на значение одного бита.
При смещении вправо обязательно делайте это в типе данных signed, чтобы C знаковое расширение значения сохраняло отрицательные значения.
Итак, взяв 12-битные примеры из таблицы, вы сдвинете вправо 4 бита, так что
SDDDDDDDDDDD0000
становится
SSSSSDDDDDDDDDDD
(где S — знаковый бит, D — допустимый бит данных, а 0 — заполнение)
Затем просто умножьте значение на 0,0625, чтобы получить реальную температуру.
В коде, который может выглядеть так:
int16_t rawval = part1 << 8 | part2;
rawval >>= 4; // Сделайте это в int16_t, чтобы сохранить знак
float temperature = rawval * 0.0625;
Для разных разрешений сдвиньте вправо на разную величину и умножьте на соответствующее однобитное значение для этого разрешения (подсказка: 11 бит удваивает значение 12 бит, 10 бит удваивает значение 11 бит и т. д.).
Просто дополнение к ответу Маженко. Регистр температуры установлен таким образом, чтобы вы могли интерпретировать его одинаково независимо от выбранное разрешение:
int16_t rawval = part1 << 8 | part2;
float temperature = rawval * (1/256.0);
Хороший план - не подумал об этом ;), @Majenko
- Как преобразовать строку в массив байтов
- Проблемы с преобразованием byte[] в String
- Как преобразовать строку в длинную?
- Как преобразовать время EPOCH во время и дату на Arduino?
- Преобразование строки в IP-адрес
- Подключите Arduino Uno RX/TX к GPS-модулю 3,3 В NEO-M8N.
- Как преобразовать char[12] в byte[6]
- cast double to long приводит к неожиданным результатам
@Shahreza Страница 10 таблицы данных.
Разрешение данных измерения температуры может быть настроено на 9, 10, 11 или 12 бит, что соответствует приращения температуры 0,5°С, 0,25°С, 0,125°С и 0,0625°С соответственно.
, @Majenko