了解热敏电阻以及如何编程Arduino来衡量其数据。
您有没有想过有些设备,如恒温器,3D打印机加热床,汽车发动机或烤箱测量温度?使用这个项目,您可以找到!
了解项目中的温度可以是一个非常有用的数据来携带方便。温度知识可以帮助调节室温,为舒适的环境进行调节,确保3D打印床适用于ABS等材料,以防止其表面,防止发动机过热,并保持食物被烧焦。
对于本文,我们仅关注一种可以测量温度的一种传感器。该传感器称为热敏电阻。
热敏电阻的电阻对温度的敏感性远远高于其他类型的电阻。
我们将使用Arduino测量和处理来自热敏电阻的读数,然后将其转换为一种人友好的公共温度单位格式。
以下是我们将使用的热敏电阻的图片:
珠子热敏电阻。图片礼貌Thorlabs.。
BOM.
硬件
- arduino.
- Mega或Uno或您最喜欢的Arduino味道
- 一些跳线
- 焊锡和烙铁(可能在您的热敏电阻不适合Arduino标头的情况下)
软件
理论
在电阻的典型应用中,您不希望使用温度的抵抗力。这在现实生活中并不是可能的,但是可以确保只有大的温度变化的抵抗力的小变化。如果不是这种情况,电阻会使电路中发生奇怪的事情,例如在环境温度变化中变得更加明亮和调光的LED。
但是,如果你真的认为LED的亮度是一个温度的函数,怎么办?这是热敏电阻进入的地方。如您所猜,热敏电阻具有较大的电阻变化,具有较小的温度。为了说明这一概念,请检查热敏电阻的典型曲线:
根据热敏电阻可以根据您购买的方式定制到不同范围的单位,但不是实际值。如您所见,温度变热,电阻较低。这是负温度系数电阻(NTC短的NTC)的性质。
还有热敏电阻具有正温度系数(短路的PTC),即随着温度的增加,电阻增加。然而,PTC热敏电阻具有一种倾斜点,并且在一些温度下大大改变电阻。这使得PTC热敏电阻与界面更加困难。因此,对于大多数低成本温度测量,NTC热敏电阻是优选的。
对于文章的其余部分,您可以假设我们将参考NTC型热敏电阻。
找到曲线配合配方的四种方法
现在我们更好地了解热敏电阻的一般行为,您可能会开始怀疑我们如何使用Arduino来测量温度。上图中的曲线是非线性的,因此,简单的线性方程似乎没有可能。(实际上,我们可以解决方程,但稍后再做。)
那么该怎么办?
在继续阅读之前,想想在Arduino或者没有微处理器组件的电路中如何实现这一点。
有几种方法可以接近此问题,如下所示。这绝不是一项技术的列表,但它将向您展示一些流行的方法。
方法一:
一些制造商足够好,可以为您提供整个图表,映射某个整数温度和电阻(典型值)。可以找到一个这样的热敏电阻这个数据表,由公司vishay.。
然后你会想如何在Arduino中实现这个。你需要将所有这些值硬编码到一个巨大的查找表或一个很长的“switch…case”或“if…then”控制结构的代码中。
如果制造商不愿意提供查找表,那么您需要自己测量每个点来生成数据。对于程序员来说,这是非常糟糕的一天。但这种方法也不全是坏事,也有它的一席之地。如果手头的项目只检查几个点,甚至很小的范围,这可能是首选的方式。例如,这样的一种情况是,如果您只想测量值是否在选定的温度范围内,并设置一个LED来显示这种情况。
但对于我们的项目,我们希望测量近连续范围并将其发送到串行监视器,因此不会使用此方法。
方法二:
您可以尝试通过向其添加外部电路来“线性化”响应热敏电阻。
一种常用的方法是将一个电阻与热敏电阻并联。有些集成电路可以为您提供这种服务。
如何选择和线性化一个区域以及选择正确的值本身就是一篇文章。如果微处理器没有浮点精度(如PICAXE),这种方法非常好,因为它将温度范围简化为线性响应。它也使设计一个没有微处理器的电路变得更容易。
但我们在本文中有一个微处理器,并且希望使用整个范围。
接近三:
您可以从数据表中获取表数据,或者(如果您喜欢惩罚自己),请生成您使用独立测量的自己的数据,并在Excel中重新创建剧情。然后,您可以使用曲线拟合功能来为曲线创建公式。这不是一个坏主意,所执行的所有工作都将在您的程序中提供一个很好的公式 - 但它确实需要一些时间和预处理数据。
虽然这是一种合法的方法,但我们不想被卡住分析所有这些数据。此外,每个热敏电阻略有不同(当然,如果公差相当低),这不是一个问题。
方法四:
拒绝有一个通用曲线配件,适用于热敏电阻等装置。它被称为Steinhart-Hart方程式。它的一个版本如下所示(其他版本使用平方项和立方项):
$ $ \压裂{1}{T} = A + B \ ln (R) + C (\ ln (R)) ^ 3 $ $
其中R是热敏电阻在温度t(在keelvins)的电阻。
这是一个适用于所有NTC型电阻器的通用曲线拟合方程。对于大多数应用来说,温度和电阻关系的近似是“足够好”的。
注意,该等式需要常数A,B和C.这些是针对每个热敏电阻的不同,并且需要给出或计算。由于有三个未知数,因此需要在一定温度下进行三次电阻,然后可以用于创建三个方程以解决这些常数。
即使是那些是代数巫师的我们,这仍然是太多的工作。
相反,有一个更简单的等式,不太准确,但只有一个常数。常数由β表示,因此等式被称为β方程。
$$ \ frac {1} {t} = \ frac {1} {t_o} +(\ frac {1} {\ beta})\ cdot \ ln \ left(\ frac {r} {r_o}右)$$
其中r.o是参考温度t的电阻o(例如,室温下的电阻)。β通常在数据表中给出 - 如果没有,您只需要一个测量(一个方程)来计算它。这是我将使用热敏电阻接口的等式,因为它非常简单到代码,并且是我遇到的最简单的一个,而无需线性化热敏电阻的响应。
用Arduino测量电阻
现在我们已经脱离了我们的方法,我们需要弄清楚如何实际测量与arduino的阻力在我们可以将此信息送入β方程之前。我们可以使用分压器执行此操作:
这将是我们和热敏电阻的接口电路。当热敏电阻感应到温度的变化时,这将反映在输出电压中。
现在,通常,我们使用下面的等式的分压器:
\ [v_ {out} = v_ {s} \ cdot(\ frac {r_ {balanal}} {r_ {thermistor} + r_ {balanal}})\]
但我们不希望VOUT作为答案 - 我们想要克里医疗。所以让我们使用代数魔法来解决:
\ [r_ {thermistor} = r_ {balanal} \ cdot(\ frac {v_s} {v_ {out}} - 1)\]
这几乎是完美的,但我们需要测量我们的电压输出以及电源电压。这是我们利用Arduino内置ADC的良好使用的地方。(如果您不熟悉该概念,请参阅AAC关于adc的教科书条目对于一些背景信息。)
我们可以在一定尺度内代表电压作为数字数字。所以,我们的等式终于如下所示:
\ [r_ {thermistor} = r_ {balanal} \ cdot(\ frac {d_ {max}} {d_ {测量}} - 1)\]
这是数学上的工作,因为无论我们如何代表电压(在伏特或数字单元中),这些单元都会抵消分数的顶部和底部,留下无量纲数。然后,乘以阻力以产生欧姆的答案。
D最大限度对于我们来说将是1023,因为这是我们的10位ADC产生的最高数字。D测量将是测量的ADC值,这可能低至零,高达1023。
唷!继续构建它吧!
将其接线
我用过A.TH10K.热敏电阻。
我还用于R 10K欧姆电阻平衡在我们的分压器中。没有给出β,所以我需要计算一下。
以下是一个完整的原理图。它实际上非常简单和直截了当!
点击放大。
这就是我的设置最终看起来像:
Arduino代码
这里的代码经过了深思熟虑,并且有大量的注释来帮助您理解逻辑。
基本上,它测量分频器的电压,计算温度,然后在串行端子中显示该温度。
为了好玩,还有一些“如果...然后”的陈述,以展示如何在一系列温度和单个数据点上行事。
一如既往地评论以下问题!或者将其拍打在论坛中进行详细的回复 - 每个人都非常友好,并将帮助您解决任何问题(在论坛规则中)。
/ *================================================================================.文件........... thermistor_demo_code.目的........热敏电阻演示码作者......... Joseph Corleto电子邮件……corleto.joseph@gmail.com开始........ 7/25/2016完成....... 7/25/2016更新……--/--/----================================================================================.笔记================================================================================.================================================================================.更新================================================================================.* /// ===============================================================================// header文件// ===============================================================================// ===============================================================================//常数// ===============================================================================/ /热敏电阻相关:/*这里我们有几个常量,使编辑代码更容易。我就去逐一地穿过他们。来自ADC的读数可能在一个样本中给出一个值,然后是一点点下次不同。为了消除嘈杂的读数,我们可以样本ADC引脚几次,然后平均样本得到更多的东西坚硬的。该常数用于读取医疗功能。* /const㈡sample_number = 10;/ *为了使用β方程,我们必须知道我们的其他电阻在我们的电阻分压器中。如果您使用具有大容差的东西,就像5%甚至1%一样,测量它并将结果放在欧姆中。* /const双倍的BANACE_RESISTOR = 9710.0;//这有助于计算热敏电阻的电阻(详细检查文章)。const双倍的max_adc = 1023.0;/ *这是热敏电阻依赖,它应该在数据表中,或者参考如何使用Beta方程计算它的文章。我不得不这样做,但我会试着用一个众所周知的热敏电阻如果你想避免经验计算。* /const双倍的beta = 3974.0;/ *这也需要转换方程作为“典型”室温需要作为输入需要。* /const双倍的room_temp = 298.15;//室温在开尔文/ *热敏电阻在室温下具有典型的电阻所以写入这一点在这里。再次,转换方程所需的。* /const双倍的电阻_troom_temp = 10000.0;// ===============================================================================/ /变量// ===============================================================================//以下是我们将保存当前温度的地方双倍的CurrentTemperature = 0;// ===============================================================================// PIN声明// ===============================================================================//输入:㈡Thermistorpin = 0;// ADC采样电阻分频器的输出//输出:// ===============================================================================/ /初始化// ===============================================================================空白设置(){//设置串行窗口消息的端口速度序列号。开始(9600);}// ===============================================================================/ /主// ===============================================================================空白环形(){/ *主循环非常简单,它打印了温度的内容串行窗口。程序的核心是在读取热敏电阻功能。* /CurrentTemperature = ReadMistor();延迟(3000);/ *以下是如何在太热的温度上行动,太冷或恰到好处。* /如果(强调> 21.0 && CurrentTemperature <24.0){序列号。打印(“这是”);序列号。打印(currentTemperature);序列号。println.(“C.啊,非常不错的温度。”);}别的如果(强调> = 24.0){序列号。打印(“这是”);序列号。打印(currentTemperature);序列号。println.(“C.我觉得像一个热的漩涡!”);}别的{序列号。打印(“这是”);序列号。打印(currentTemperature);序列号。println.(“C.Brrrrrr,它很冷!”);}}// ===============================================================================// 职能// ===============================================================================///////////////////////////////// / / / / / readThermistor / / / / / / ////////////////////////////////// *此功能读取模拟引脚,如下所示。转换电压信号用模拟到数字的转换来表示数字。然而,这是完成多次,以便我们可以将其平均消除测量误差。然后用这个平均值来计算热敏电阻的电阻。此后,电阻用于计算温度热敏电阻。最后,温度转化为摄氏度。请参阅这篇文章为具体和一般的理论这过程。快速原理图,以防您懒得查看该网站:P(地面)---- \ / \ / \ / ------- | ------- \ / \ / / \ / ---- v_supplyr_balance |R_Thermistor.|模拟密码* /双倍的readThermistor () {//居住在此功能中的变量双倍的r热医疗= 0;//保持热敏电阻电阻值双倍的tkelvin = 0;//保存计算的温度双倍的tcelsius = 0;//在摄氏度中保持温度双倍的adcaverage = 0;//保持平均电压测量㈡Adcsamples [sample_number];//数组保存每个电压测量/*计算热敏电阻的平均电阻:如代码顶部所提到的,我们将几次对ADC引脚进行采样得到一堆样本。添加了略有延迟以适当地拥有analogread函数样本正确* /为(㈡我= 0;我analogread.(Thermistorpin);//从PIN和商店读取延迟(10);//等待10毫秒}/*然后,我们将简单地将所有这些样本平均起来测量。* /为(㈡我= 0;我 //添加所有样本。。。} adcAverage /= SAMPLE_NUMBER;//。。。平均其划分/*这里我们使用公式计算热敏电阻在文章中讨论。* /RITHISTOR = BANACE_RESISTOR *((max_adc / adcaverage) - 1);/ *这里是使用β方程的位置,但它是不同的从文章中描述的。别担心!它已经重新安排了代数,给出“更好”的展示配方。我鼓励你想要操纵文章中的等式,自己去得到在代数上更好。如果没有,只需使用此处显示的内容并采取它为理所当然或直接从文章中输入公式,准确无误如图所示。无论哪种方式都会起作用!* /tKelvin = (BETA * ROOM_TEMP) / (BETA + (ROOM_TEMP *日志(r热静脉/电阻_troom_temp))));/ *我将使用摄氏度的单位表示温度。我做到了这一点所以我可以看到典型的室温,这是25度Celsius,当我第一次尝试该计划时。我更喜欢华氏身,但是我将其留给您来改变此功能,或创建另一种转换在两个单元之间的功能。* /TCELSIUS = TKELVIN - 273.15;//将Kelvin转换为Celsius返回Tcelsius;//返回摄氏温度}
可能的下一步
本文中的一切都以廉价的热敏电阻测量温度的相当简单的方式。您可以在设置上提高几种方法:
- 将小电容器与输出电压并联。这将稳定电压,并且甚至可以消除平均许多样本(如代码中)的需要,至少您可以平均较少的样本。
- 使用精密电阻(优于1%)具有更一致和可预测的测量。如果您需要绝对的临界温度测量,请记住热敏电阻的自加热会影响测量值;该项目不会弥补自我加热。
当然,热敏电阻只是一个用于温度测量的传感器。另一个流行的选择是使用温度IC这一个(PDF)。这样,您永远不需要处理线性化或复杂的方程。另外两种选择是热电偶和一个IR型传感器;后者可以测量温度而没有物理接触,但它们并不便宜。
我希望这能为您提供更好的想法,如何为下一个项目测量温度!
thermistor_demonstration_code.zip.zip.
为自己提供这个项目!得到bom。
该公式不正确:
RITHIRTOROR =RBALANCE‖(DMAXDMEASUED-1)
它应该除以,而不是乘以:
RITHISTOR = RBALANCE /(DMAXDMEASUED-1)
我如何使用相同代码中的两个热敏电阻来使用两个热敏电阻来在同一时间测量单独的温度?谢谢!