使用 Linux 进行远程温度监控

作者:Steven M. Lapinskas

我启动这个项目是为了远程记录和访问温度读数,起因是我与一位从事暖通空调 (HVAC) 业务的朋友进行了一次谈话。他的工作是确保室内气候舒适——根据室外天气,不会太热也不会太冷。他发现许多新安装的系统都有启动错误,必须加以解决,因为没有两个安装是完全相同的。工作的最后阶段是最紧张的。客户在他完成工作后打电话告诉他出了问题。客户不高兴,但他不知道从哪里开始寻找问题,因为没有任何关于安装出了什么问题的客观信息。

我们一致认为,能够记录室外温度并以电子方式记录读数将有所帮助。这将是改进故障排除过程的一种方法。然后,我开始寻找购买现成的记录仪,要求它价格低廉、易于安装且易于使用。在寻找的过程中,我发现各种各样的商业产品和套件。有些是独立的,有些使用 PC 来显示和记录温度数据。我们的三个要求同等重要,我发现大多数产品对于我们的预算来说都太贵了。易于安装通常是另一个问题。有些设备布线复杂,或者要求将它们放置在测量温度的地方。许多人认为恒温器只是墙上的杂物,因此要说服他们再安装一个盒子来记录温度并不容易。

Linux 解决方案

最后,为了解决成本和安装问题,我考虑了从组件构建系统的可能性。遵循 Linux 组装和集成工具来完成任务的理念,我考虑使用数字万用表、PC 和软件来使它们协同工作。带有 RS-232 串行端口接口的数字万用表将使用传感器测量温度。PC 将从万用表收集数据并对其进行处理以进行显示。

我了解使用 Linux 的万用表串行端口接口的开源实用程序,并且早些时候购买了万用表用于一般故障排除。我们有一台退役的 PC 可用,因此所有组件都已准备就绪,可以构建温度记录系统原型。

数字万用表随附串行端口电缆和 DOS 软件。我没有使用随附的 DOS 程序。无法修改该程序以允许使用传感器进行温度测量。相反,我使用 QuickBasic 从头开始编写新软件。我掌握了有关万用表串行端口接口的必要详细信息,并且 QuickBasic 具有我需要的所有功能。我得到了一个原型通信程序来工作,但是随着应用程序规模的增长,尤其是在我开始处理显示和记录数据的需求时,我遇到了 DOS 和 QuickBasic 的内存管理问题。

在这个时候与内存管理作斗争似乎是一个很大的倒退。我知道 Linux 将提供一个我不需要担心内存管理的环境,所以我寻找一个发行版来替代 DOS。

我发现最流行的 Linux 发行版不适合此应用程序。即使是这些发行版的最小安装也会超出退役 PC 的容量。我找到的克服这些限制的发行版是 Paul Muller 的 University Linux。它对内存和磁盘的要求很小。我能够在退役的 PC 上运行它,使用的 DOS 格式化硬盘空间不到 20MB,RAM 不到 24MB。最重要的是,该发行版能够容忍电源故障。如果电源中断,PC 会重新启动,而不会导致需要手动帮助的文件损坏问题。这节省了资金并降低了复杂性,因为我不需要 UPS 来保持系统在电源故障期间运行。

一旦我在 PC 上配置好一切,就不再需要键盘或显示器。我可以将 Windows PC 和 Telnet 以及以太网连接一起使用,以便与系统 PC 进行通信以进行开发和测试。我更喜欢增量式编写和测试,所以我选择了 Perl 作为这个项目的语言。University Linux 附带 Perl 5.003 版本。我无法使用 Perl 模块,应用程序大小太小,所以这是一个小小的麻烦。University Linux 还包括 Acme Labs thttpd 服务器。这使我能够设置系统以使用 Web 浏览器来查看温度测量值。

硬件测试

我使用了 Tandy Catalog No. 22-805 数字万用表,它随附操作手册、DOS 软件、导线测试线和带有九针连接器的串行电缆。根据手册,通信设置为 600 波特、七个数据位、两个停止位且无奇偶校验。操作手册中遗漏了重要信息,但我在 Web 上找到了我需要的信息。DTR 和 RTS 线需要特别注意。必须将 DTR 线设置为低电平,将 RTS 线设置为高电平,仪表才能通过串行端口进行通信。如果两条线不这样设置,则无法从仪表获取数据。

对于此发行版,我只能使用 stty 进行串行通信,并且无法在脚本中显式控制 DTR 和 RTS 线。这意味着我需要一个硬件技巧才能使事情正常工作。

我发现当我调用脚本中的 stty 时,DTR 和 RTS 从低状态变为高状态。这对于 DTR 来说还可以,但 RTS 必须保持低电平。我意识到 PC 上的第二个串行端口的 RTS 为低电平,因为它没有被使用。如果我将万用表串行接口电缆 RTS 连接到第二个串行端口的 RTS 引脚,则万用表将被欺骗,认为看到了正确的线路设置。我只是从万用表上拆下了 RTS 线,并将其连接到第二个串行端口。

解决了这个问题后,我启动了万用表并编写了一个简短的测试脚本 (serialtest.pl),如下所示

# !/usr/bin/perl
#
# serialtest.pl
#
# Script for reading Tandy Model 22-805 meter
# through serial port.

$port = "/dev/ttyS1"; # set to COM1

system ("stty 600 cs7 cstopb clocal -ixon -echo < $port");

open (SERIALPORT, "+>$port") or die "can't open $port. ";

print SERIALPORT ("\n"); #  take a reading

$R = <SERIALPORT>; # read returned string

print "$R" ;

close (SERIALPORT); # close port

exit 0;

如果脚本成功运行,我将获得一个字符串,其中包含与万用表 LCD 上显示的读数相同的读数。我将万用表设置为电阻测量范围并运行脚本。结果是

OH   O.L MOhm

良好的开端!硬件技巧奏效了。现在开始使用万用表测量温度传感器。

我选择了一个 NTC(负温度系数)热敏电阻作为温度传感器。尽管名称听起来令人恐惧,但这只是一个小的双线电子元件,其电阻会随着温度而变化。使用万用表,电阻测量提供了告诉温度的信息。热敏电阻不可能反向接线,因为它对电压极性(+ 或 -)不敏感。这意味着现场安装的技术人员少了一件需要担心的事情。

热敏电阻不易碎,但连接到主体的引线可能会因过度拉扯或弯曲而断裂。我使用了一个两位接线端子块来解决这个问题,并使与布线的连接变得简单。我将一根热敏电阻引线和一根电线放在一个螺钉端子下,然后拧紧螺钉以形成牢固的机械和电气接触。

将热敏电阻连接到测试线的末端,并将测试线插入万用表后,我启动并再次运行测试脚本。结果是电阻读数

OH  34.23kOhm

读数的数字部分是 34.23,后面跟着一个 k。k 是千或 1,000 的缩写。由于万用表 LCD 没有足够的字符来显示大数字,因此它使用了乘数。在这种情况下,34.23k 是 34,230 欧姆。

我发现这个读数非常接近 0 摄氏度,参考了制造商提供的电阻-温度值表。它与另一个带有传感器的温度计在一般区域的温度读数相符,因此我确信这个组装的系统可以工作并提供准确的读数。

现在是时候创建一个脚本来使用数据并显示温度值了。

软件选择

脚本中有两种选择可以执行电阻到温度的转换。我可以使用查找表,其中包含数组中成对的电阻到温度值。此数组中元素的庞大数量将是这种方法的缺点。从 -40 摄氏度到 +40 摄氏度的跨度需要 81 对值(不要忘记 0 摄氏度)。没有简单的方法来操作热敏电阻制造商提供的文本文件,并且手动输入值将花费时间并且容易出错。

相反,我使用了所谓的 Steinhart-Hart 方程(参见侧边栏)。该方程是在 1960 年代后期开发的,旨在帮助处理使用热敏电阻收集的海洋温度数据,并提供电阻到温度的直接转换。在 Web 上找到的电子表格实用程序帮助计算了每个热敏电阻系列特有的系数,并在方程中使用。

显示数据

一旦脚本从万用表读数计算出温度,就需要显示或存储它。考虑到这一点,我扩展了测试脚本以转换和显示温度,并显示时间和电阻读数。University Linux 使用 2.0 内核,并允许通过 Telnet 进行 root 用户登录。当普通用户尝试运行 grabtemp.pl 脚本时,由于用于串行端口 /dev/ttyS1 的文件权限,会显示错误。我通过更改权限解决了这个问题,使用命令:

chmod a+x /dev/ttyS1

现在,普通用户可以登录并运行脚本来检查温度。他们不需要 root 访问权限。

以下是生成的 showtemp.pl 脚本的输出

/perlserial: perl -w showtemp.pl
01-05-2006 14:43 34 F 1.3 C 30.52 k Ohms

在这里,您可以看到日期、时间、华氏度和摄氏度温度,以及实际电阻读数。我检查了传感器所在位置的温度,发现读数是准确的,因此脚本的转换公式部分工作正常。

没有太多计算机用户习惯于使用命令行程序界面。带有点击界面的 Web 浏览器要容易得多。因此,我再次扩展了脚本,以允许用户使用 Web 浏览器操作系统。

在配置并运行 thttpd 服务器后,只需将脚本的输出定向到构建 Web 页面以进行显示即可。这非常简单,如下面的代码所示:显示了

print "content-type: text/html \n\n";
print "<HTML><BODY><P>";
print "<HEAD><title>Remote Temperature Measurement Page</title></HEAD>";
print "<H2>Mechanical Room</H2> ";
print '<form action="webtemp.pl" method=post> <P> <P>';
print "Interior Air Temperature = $out_tempF<BR>";
print "<BR>";
print "<BR>";
print "Date: $out_date  <BR>";
print "Time: $out_time  <BR>";
print "<BR>";
print '<input type=submit value="Update Reading">';
print "</form>";
print "</BODY></HTML>";

从 /cgi-bin 运行 webtemp.pl 脚本为用户提供了如图 1 所示的显示。

Remote Temperature Monitoring with Linux

图 1. 温度监控器现在具有 Web 界面。

此示例显示了房间内的温度以及读数的时间和日期。您可以按“更新读数”按钮重新运行脚本并显示另一个温度值。

很容易编写脚本的扩展程序来记录一段时间内的温度。我在 rc(启动)脚本中添加了一行,用于启动数据记录脚本,该脚本然后在后台持续运行。我发现可以使用 5-10 分钟的测量间隔,因为在空调空间中,室内气温的变化很慢。

您可以使用 Telnet 通过命令行访问温度日志。由于格式是空格分隔的,因此日期文件与 Microsoft Excel 一起使用来绘制图表和查看趋势。您可以在图 2 中看到示例输出。

Remote Temperature Monitoring with Linux

图 2. 通过 Telnet 查看的温度监控日志中保存的一组示例值。

安全考虑

总体目标是创建一种可靠且易于使用的电子方式来显示和记录温度数据。当您实际部署系统时,系统的位置和网络连接可能会有很大差异。根据具体情况,您必须评估每个安装的安全问题。您可能必须实施一些解决方法来解决安全问题。例如,您可以让在后台运行的脚本以文本或 HTML 页面的形式记录温度读数,而不是通过 cgi 目录中的脚本记录,这会将日志记录过程与 Web 访问隔离。或者,您可以使用另一个安全服务器通过 FTP 或 HTTP 从此服务器收集数据。这将增加一层以防止外部世界直接访问,但仍然可以使信息可用。

未来扩展

数字万用表是通用电子测量工具。虽然我在此应用中使用了热敏电阻进行温度测量,但您可以使用其他以电阻、电压或电流作为输出的传感器。要测量的其他条件包括流量、压力、重量、光照水平和湿度。

您不需要更多的万用表来测量多个温度。您可以将单个万用表连接到切换设备。然后,您将创建一个脚本来操作切换设备,这允许您一次选择一个温度传感器。

结论

此示例说明了 Linux 背后的工具概念如何用于解决对成本和灵活性要求很重要的应用程序。与其他操作系统相比,可用的各种发行版意味着开发具有所有必要功能的系统是切实可行的。此外,您可以使用 Perl 和 University Linux 发行版提供的开发环境添加功能。

该系统可以以低于 100 美元的价格复制。万用表、热敏电阻和布线配件可从众多电子产品零售商处获得。许多零售商都有网站,因此在订购之前很容易比较功能、规格和价格。购买二手数字万用表应谨慎,因为没有简单的方法可以判断仪器的精度是否受到先前使用的影响。

热敏电阻和 Steinhart-Hart 方程

热敏电阻在图表上电阻与温度的关系图看起来很像滑雪跳台的曲线,并且每个热敏电阻系列都有自己独特的曲线。因此,简单的 y = mx + b 代数无法帮助将电阻转换为温度。曲线方程可以用多项式来描述。Steinhart-Hart 方程是一个三项式或具有三项的方程。在每个电阻测量点求解方程需要三个系数:a、b 和 c。一些制造商为其热敏电阻提供了这些系数。其他制造商仅提供电阻到温度的表格。

当系数不可用时,可以使用电子表格实用程序通过制造商的表格帮助找到它们。无需代数运算;只需将温度和电阻的三个值输入电子表格,系数就会自动计算出来。它们通常是非常小的数字,以科学计数法表示。但是,可以将计算出的系数从电子表格中剪切并粘贴到 Perl 脚本中使用,从而减少打字造成的错误

本文的资源: /article/8833

Steven M. Lapinskas 具有软件质量保证、机械设计和项目管理领域的专业背景。他的一些空闲时间用于尝试将 Linux 与计算机外部的真实世界连接起来。

加载 Disqus 评论