[英]Better precision with Arduino (floats)
我正在嘗試在Arduino上進行Steinhart-Hart溫度計算。 等式是
我解決了一個由3個方程組成的系統,以獲得A,B和C的值,它們分別是:
A = 0.0164872
B = -0.00158538
C = 3.3813e-6
當我將它們插入WolframAlpha求解T
我會在Kelvins中得到一個有意義的值:
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 Kelvin,相距很遠。
那么,如何在Arduino中進行這樣的計算? 任何建議,不勝感激,謝謝。
精度不是主要問題。 甚至可以使用float
和powf()
。 熱敏電阻溫度計算不那么精確。 畢竟溫度肯定不比精確的±0.1°C好 。 熱敏電阻的自發熱是一個較大的因素。
OP的C代碼假定對數底2,使用日志以e為底log()
為常數,使用對數底2衍生@馬丁ř
// 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));
是的,浮點算術在大多數arduino上的精度有限。
您是否考慮過使用固定精度? 如果正確使用,這可能會給您帶來更好的結果。 對此的要求是具有相當窄的參數,並要小心單位轉換。
arduino上的unsigned long
也是4個字節,因此它最多可以包含2^32-1
數字。 如果使用定點,則可能要用類似於100000/T
替換此1/T
100000/T
,其中分子常數和T已根據所需精度進行了縮放。
您還需要保留每個變量包含的小數位數的(心理或紙質)模型,以優化操作順序,而不會失去精度。
對於log2
函數,我懷疑它是否可以直接使用整數。 您可以強制轉換結果或重新實現它 。 即使在SO上,也有很多資源可以解決此問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.