2016-09-23 3 views
2

Я пытаюсь сделать расчет температуры Steinhart-Hart на Arduino. Уравнение enter image description hereЛучшая точность с Arduino (поплавки)

Я решил систему из 3 уравнений для получения значения A, B и C, которые являются:

A = 0.0164872 
B = -0.00158538 
C = 3.3813e-6 

Когда я подключить их в WolframAlpha решить для T я получаю значение в Кельвинах, что имеет смысл:

T=1/(0.0164872-0.00158538*log2(10000)+3.3813E-6*(log2(10000))^3) solve for T

T = 298.145 Kelvins = 77 Fahrenheit

Однако, когда я пытаюсь использовать это уравнение на моем Arduino, я получаю очень неправильный ответ, я подозреваю, потому что в парном разряде недостаточно точности. Вот что я использую:

double temp = (1/(A + B*log(R_therm) + C*pow(log(R_therm),3)));

Это возвращает 222 Кельвина вместо этого, что далеко.

Итак, как я могу сделать вычисления, подобные этому в Arduino ?? Любые советы очень ценятся, спасибо.

+6

«log2» обозначает базис-2-логарифм и «журнал» «естественный» или базовый-логарифм. Это может уже объяснить разницу. –

+0

Также 'C = 000003.3813' и' 3.3813E-6' не совпадают. –

+0

Да, здесь 'ln', вероятно, ссылается на неперский логарифм, который будет' ln (x) = log2 (x)/log2 (exp (1)) ' – MayeulC

ответ

3

Прецизионность не является основной проблемой. Могли бы даже использовать float и powf(). Расчет температуры термистора не равен , что точно. Ведь температура, конечно, не лучше ±0.1°C accurate. Самонагрев термистора является более важным фактором. Код

OP в C предполагает журнал базу 2, использование логарифм хlog() как константы были получены с помощью журнала базы 2. @Martin R

// double temp = (1/(A + B*log(R_therm) + C*pow(log(R_therm),3))); 
double temp = (1/(A + B*log(R_therm)/log(2) + C*pow(log(R_therm)/log(2),3)));` 

реализации образца, что позволяет избежать ненужного медленно pow() вызова.

static const inv_ln2 = 1.4426950408889634073599246810019; 
double ln2_R = log(R_therm)*inv_ln2; 
double temp = 1.0/(A + ln2_R*(B + C*ln2_R*ln2_R)); 
1

Да, арифметика с плавающей запятой имеет ограниченную точность на большинстве ардуинов.

Считаете ли вы использование фиксированной точности? Если использовать правильно, это может дать вам лучшие результаты. Требование для этого состоит в том, чтобы иметь довольно узкие параметры, однако, и будьте осторожны при конвертации единиц.

unsigned long на arduino тоже 4 байта, поэтому он может содержать номера до 2^32-1. Если вы используете фиксированную точку, вы можете заменить это 1/T на что-то вроде 100000/T, где константа числителя и T были масштабированы в соответствии с требуемой точностью.

Вам также необходимо сохранить (умственную или бумажную) модель числа десятичных знаков, которые содержит каждая переменная, чтобы оптимизировать порядок операций, чтобы не потерять точность.

Для функции log2, я сомневаюсь, что она доступна из коробки для целых чисел. Вы можете либо сделать результат, либо reimplement it. Существует много ресурсов для этой проблемы, даже здесь, на SO.

+0

Я бы сказал, что арифметика с плавающей запятой имеет ограниченную точность не только для большинства Arduinos, но и для всех из них, а также для всех других компьютеров ... –

+0

@ ThomasPadron-McCarthy: каждое числовое представление имеет ограниченную точность в какой-то момент, если вы хотите nitpick. Но avr-based arduinos имеет только 4-байтовые числа с плавающей запятой. Нет двойной точности. Например, у Due есть двойные числа с плавающей запятой. Но это может быть проблемой здесь. – MayeulC

Смежные вопросы