Arduino如何用NTC热敏电阻测量温度
对于像热敏电阻这样的器件,存在一般的曲线拟合公式,称为Steinhart-Hart方程。有不同的版本,其中使用了平方和立方项。这是等式的一个版本:
1 / T = A + Bln(R)+ C(ln(R))3
其中R是热敏电阻在温度T下的电阻(以开尔文为单位)。
这种通用的曲线拟合方程可以容纳所有NTC型电阻器,因为电阻和温度的关系的近似对于大多数应用来说是足够的。
注意,该等式需要三个常数:A,B和C.这些常数对于每个热敏电阻是不同的,必须给出或计算。有三个未知数,您需要在一定温度下进行三次电阻测量。从那里,这些测量产生三个方程来解决这些常数。
即使你是一个代数巫师,这也是很多工作。
幸运的是,有一个更简单的方程不太准确但只有一个常数。常数用β表示,因此该方程称为β方程。
1 / T = 1 / T O +(1 /β)⋅ln(R / R O)
其中R O指的是参考温度T O处的电阻(例如,室温下的电阻)。
β通常在数据表中提供。如果不是,您只需要一次测量(一个等式)来计算它。
所以我们找到了它。这是我们将用于热敏电阻接口的等式和方法,因为编码非常简单,同时也是我们尚未发现的最简单的方法,不需要线性化热敏电阻的响应。
用Arduino测量电阻
由于我们已经找到了正确的方法,我们现在需要弄清楚如何在我们将其插入β方程之前用Arduino实际测量电阻。这可以使用分压器完成:
以上是我们热敏电阻的接口电路。每次热敏电阻检测到温度变化时,它都会反映在输出电压中。
通常,我们使用分压器,其公式如下:
V 出 = V 小号 ⋅(R 平衡 / R 热敏电阻 + R 平衡)
但是,我们不希望V out作为答案 - 我们想要R 热敏电阻。我们将通过以下方式解决这个问题:
R 热敏电阻 = R 平衡 ⋅(V s / V out - 1)
我们即将完善,但我们需要测量电压输出和电源电压。这就是Arduino内置ADC的用武之地。
我们可以将电压表示为一定范围内的数字数字。所以,我们的等式最终结果如下:
R 热敏电阻 = R 平衡 ⋅(D max / D 测量 - 1)
这在数学上是成功的,因为无论我们如何表示电压(以伏特或数字为单位),这些单元抵消了分数中的顶部和底部,留下无量纲数。在那之后,乘以一个阻力,以欧姆为单位得出答案。
我们的D max将是1023,因为它是我们的10位ADC产生的最高数字。测量的 D 将被设置为我们测量的ADC值,范围从低至零到高达1023。
现在,让我们建立!
布线
我们将在我们的分压器中使用一个10K欧姆的热敏电阻,以及一个10k欧姆的电阻用于R 平衡。没有给出β,因此需要计算。
您将在下面找到完整的原理图。
以下是设置最终应该如下所示:
Arduino代码
下面的代码包含有用的注释,以帮助指导您完成逻辑。
该代码测量分压器的电压,计算温度,并在串行终端中显示。
还有一些“if ... then”语句可以很有趣地展示,以展示如何在一系列温度和单个数据点上采取行动。
/ * ================================================ ================================ 文件........... Thermistor_Demo_Code 目的.... ....热敏电阻演示代码 作者......... Joseph Corleto 电子邮件......... corleto.joseph@gmail.com 开始........ 7/25 / 2016 完成....... 2016年7月25日 更新........ - / - / ---- ================ ================================================== ============== 注意 =================================== ============================================= ===== ================================================== ========================= 更新 ======================== ================================================== ====== * / // ============================================== ================================= //头文件 // =========== ================================================== ================== // ============================== ================================================= / /常量 // ============================================== ================================= //热敏电阻相关: / *这里我们有几个常量可以编辑代码更容易。我将 逐一介绍它们。 来自ADC的读数可能在一个样本处给出一个值,然后 在下一次给出一点不同。为了消除噪声读数,我们可以进行采样 ADC引脚几次,然后平均样本以获得更 稳固的东西。该常数用于readThermistor功能。 * / const int SAMPLE_NUMBER = 10; / *为了使用Beta方程,我们必须知道 电阻分压器中的另一个电阻。如果您使用的是具有较大公差的物体, 例如5%或甚至1%,请测量它并将结果置于欧姆。* / const double BALANCE_RESISTOR = 9710.0; //这有助于计算热敏电阻的电阻(详见检查文章)。 const double MAX_ADC = 1023.0; / *这取决于热敏电阻,应该在数据表中,或参考 有关如何使用Beta方程计算它的文章。 我不得不这样做,但 如果你想避免经验计算,我会尝试用一个已知测试版的热敏电阻。* / const double BETA = 3974.0; / *这也是转换方程所 需要的,因为需要“典型”室温作为输入。* / const double ROOM_TEMP = 298.15; //以开尔文为单位的室温 / *热敏电阻在室温下具有典型的电阻,因此请 在此处记下。同样,需要转换方程式。* / const double RESISTOR_ROOM_TEMP = 10000.0; // ================================================ =============================== //变量 // ================================================ =============================== //这里我们将保存当前温度 double currentTemperature = 0; // ================================================ =============================== // Pin声明 // ============= ================================================== ================ //输入: int thermistorPin = 0; // ADC采样电阻分压器的输出 //输出: // ================================== ============================================= //初始化 // ================================================== ============================= void setup() { //设置串口窗口消息的端口速度 Serial.begin(9600); } // =============================================== ================================ //主要 // ============= ================================================== ================ void loop() { / *主循环非常简单,它打印 串行窗口中的温度。该程序的核心在readThermistor 函数内。* / currentTemperature = readThermistor(); 延迟(3000); / *以下是如何对温度过高, 过冷或过热的温度进行操作。* / if(currentTemperature> 21.0 && currentTemperature <24.0) { Serial.print(“它是”); Serial.print(currentTemperature); Serial.println(“C.Ahhh,非常好的温度。”); } else if(currentTemperature> = 24.0) { Serial.print(“It is”); Serial.print(currentTemperature); Serial.println(“C。我觉得自己像个热辣的女人!”); } else { Serial.print(“It is”); Serial.print(currentTemperature); Serial.println(“C.Brrrrrr,它很冷!”); } } // ============================================== ================================= //功能 // ============ ================================================== ================= ///////////////////////////// ////// readThermistor /////// /////// ////////////////////// / * 此功能读取模拟引脚,如下所示。 通过模数转换将电压信号转换为数字表示。但是,这样 做了多次,因此我们可以对其进行平均以消除测量误差。 然后使用该平均数来计算热敏电阻的电阻。 此后,电阻用于计算 热敏电阻的温度。最后,温度转换为摄氏度。 有关此 过程的详细信息和一般理论,请参阅allaboutcircuits.com文章。 快速原理图,以防你懒得看网站:P (地面)---- \ / \ / \ / ------- | ------- \ / \ / \ / - --- V_supply R_balance | R_thermistor | 模拟引脚 * / 双读取器() { //存在于此功能中的变量 双rThermistor = 0; //保持热敏电阻的电阻值为 tKelvin = 0; //保持计算温度 加倍tCelsius = 0; //以摄氏温度保持温度 double adcAverage = 0; //保持平均电压测量值 adcSamplesSAMPLE_NUMBER; //用于保持每个电压测量的阵列 / *计算热敏电阻的平均电阻: 如代码顶部所述,我们将对ADC引脚进行几次采样, 以获得一堆样本。为了正确地使用 analogRead函数样本,添加了一点延迟* / for(int i = 0; i <SAMPLE_NUMBER; i ++) { adcSamplesi = analogRead(thermistorPin); //从引脚和存储 延迟读取(10); //等待10毫秒 } / *然后,我们将简单地平均所有这些样本以进行“更硬”的 测量。* / for(int i = 0; i <SAMPLE_NUMBER; i ++) { adcAverage + = adcSamplesi; //添加所有样本。。。 } adcAverage / = SAMPLE_NUMBER; // 。。平均值w / divide / *这里我们使用 文章中讨论的公式计算热敏电阻的电阻。* / rThermistor = BALANCE_RESISTOR *((MAX_ADC / adcAverage) - 1); / *这里是使用Beta方程的地方,但它 与文章描述的不同。别担心!它已被重新排列为 代数,以提供“更好”的外观公式。我鼓励你 尝试自己操纵文章中的等式,以便 更好地学习代数。如果没有,只需使用此处显示的内容并将其 视为 理所当然,或者直接从文章中输入公式,就像 显示的那样。无论哪种方式都可行!* / tKelvin =(BETA * ROOM_TEMP)/ (BETA +(ROOM_TEMP * log(rThermistor / RESISTOR_ROOM_TEMP))); / *我将使用摄氏度单位来指示温度。我这样做是 为了让我看到典型的室温,即25 摄氏度,当我第一次尝试该程序时。我更喜欢Fahrenheit,但是 我让你更改这个功能,或者创建 另一个在两个单位之间转换的功能。* / tCelsius = tKelvin - 273.15; //将开尔文转换为摄氏温度 返回tCelsius; //以摄氏度返回温度 }