2017-08-30 199 views
-1

Arduino爱好万用表项目(存在于入门套件中)使用float来根据从TMP36读取的电压计算温度。如何提高arduino TMP36温度读数?

该Arduino Uno微控制器(ATmega328P)没有任何FPU和计算不具有良好的性能。

我们该如何改进这种计算?

// Code for 5V at the input of the TMP36 
int reading = analogRead(PIN); 
float voltage = (reading * 500.0)/1024.0; 
float celciusTemperature = voltage - 50.0; 
+0

我认为这将是更有益与语言替换[精]标签标签。 –

回答

0

表现不佳的原因是浮点值的使用。

我将展示如何摆脱它。

首先,我们谈论精度:

  • 的TMP36的范围为500℃(从-50℃至+ 450℃)。
  • 模拟读取在0到1023的10位(1024个可能值)上工作。

所以精度是500/1024。大约0.5°C。

所以,如果我们想在int上编码温度,那么这个int的较低有效位需要编码为0.5°C而不是1°C。

例子:

int celciusTemperatureByHalfDegree = +40; // +20.0°C 
int celciusTemperatureByHalfDegree = +41; // +20.5°C 
int celciusTemperatureByHalfDegree = -10; // -5.0°C 
int celciusTemperatureByHalfDegree = -15; // -5.5°C 

我们看到:

celciusTemperatureByHalfDegree = celciusTemperature * 2 

大约将有:

int reading = analogRead(PIN); 
int voltage = (reading * 500)/1024; 
int celciusTemperature = voltage - 50; 
int celciusTemperatureByHalfDegree = celciusTemperature * 2; 

此时溢出和取整的问题导致该码是无用。

让我们把它简化:

int reading = (analogRead(PIN) * 500)/1024; 
int celciusTemperatureByHalfDegree = (reading - 50) * 2; 

并再次:

int reading = (analogRead(PIN) * 500)/512; 
int celciusTemperatureByHalfDegree = reading - 100; 

并再次:

int reading = (analogRead(PIN) * 125)/128; 
int celciusTemperatureByHalfDegree = reading - 100; 

在这一点上没有更多的四舍五入问题。但是analogRead()给出了一个输出1023介于0和

而且1023 * 125比最大int16(32,767)大,所以溢出是可能的。

这里我们将使用125 = 5 * 25和128 = 4 * 32。

int reading = (analogRead(PIN) * 5 * 25)/(4 * 32); 
int celciusTemperatureByHalfDegree = reading - 100; 

将变为:

int reading = analogRead(PIN); // 0 to 1023 
reading *= 5;     // 0 to 5115 (no overflow) 
reading /= 4;     // 0 to 1278 (no overflow) 
reading *= 25;     // 0 to 31950 (no overflow) 
reading /= 32;     // 0 to 998 
int celciusTemperatureByHalfDegree = reading - 100; 

最后将其打印出来,我们将使用此代码:

// print the integer value of the temperature 
Serial.print(celciusTemperatureByHalfDegree/2); 
Serial.print("."); 
// less significant bit code for "__.0" of "__.5" 
Serial.print(celciusTemperatureByHalfDegree % 2 ? '5' : '0'); 
Serial.print("°C");