在IoT专家Peter Wahr的这篇客座帖子中了解如何创建传感器项目 。
传感器的开发分为六个步骤。 这是一个简单的概述:
- 首先,您将设置控制台应用程序的基本结构。
- 然后,您将配置硬件并学习对传感器值进行采样并维护有用的历史记录。
- 将HTTP服务器功能和其他有用的Web资源添加到项目后,您将在Internet上发布收集的传感器值。
- 然后,您将处理传感器中采样数据的持久性,以便在中断或软件更新后可以恢复。
- 下一步将教您如何添加安全层,该安全层需要用户身份验证才能访问应用程序顶部的敏感信息。
- 在最后一步,您将学习如何克服HTTP使用的请求/响应模式中的主要障碍之一,即如何将事件从服务器发送到客户端。
但是,本教程仅关注前两个步骤。 要了解更多信息,请参阅《 学习物联网 》一书。
为传感器项目准备Raspberry Pi
要配置Raspberry Pi,请访问http://www.raspberrypi.org/help/faqs/#buyingWhere 。
在本教程中,您将看到模型B在以下方面的使用:
- 已安装Raspbian操作系统的SD卡
- 已配置的网络访问权限,包括Wi-Fi(如果使用)
- 用户帐户,密码,访问权限,时区等均已正确配置
传感器项目将使用C#在远程PC上开发 ,因为它是一种现代编程语言,可为IoT提供完全的灵活性。 它还允许您在Windows,Linux,Macintosh,Android和iOS平台之间交换代码。
编译项目后,可执行文件将部署到相应的Raspberry Pi中,然后执行。 由于代码在.NET上运行,因此可以使用大量与CLI兼容的语言中的任何一种语言。
小费
可以从http://xamarin.com/免费下载C#开发工具。
要为执行.NET代码准备Raspberry,您需要安装Mono,其中包含.NET的公共语言运行时,它将帮助您在Raspberry上运行.NET代码。 这可以通过在Raspberry Pi的终端窗口中执行以下命令来完成:
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install mono-complete
您的设备现在可以运行.NET代码了。
硬件:Raspberry Pi IoT项目中使用的传感器
传感器原型将测量三件事:光,温度和运动。 总结一下,这是组件的简短描述:
- 光线传感器是一个简单的ZX-LDR模拟传感器,它将连接到四通道模数转换器(Digilent Pmod AD2)。 然后这被连接到I 2 C总线,将连接到标准的GPIO引脚I 2 C.注意,I2C总线使用同步通信中,采用串行时钟线(SCL)和串行数据线(允许与多个电路通信SDA)引脚。 这是与集成电路通信的常用方法。
- 温度传感器(Texas Instruments TMP102)直接连接到同一I 2 C总线。
- I 2 C总线上的SCL和SDA引脚使用推荐的上拉电阻,以确保当没人主动将其下拉时,它们处于高状态。
- 红外运动检测器(视差PIR传感器)是一个数字输入,可以连接到GPIO 22。
- 四个LED也将添加到板上。 其中之一是绿色,并连接到GPIO23。这将在应用程序运行时显示。 第二个是黄色,并连接到GPIO24。这将在完成测量时显示。 第三个是黄色,并连接到GPIO18。这将在执行HTTP活动时显示。 最后一个为红色,并连接到GPIO25。当发生通信错误时,它将显示。
- 控制LED的引脚在连接到LED之前先连接到160电阻,然后再接地。 原型板的所有硬件均由Raspberry Pi提供的3.3 V电源供电。 在引脚和地之间串联一个160Ω电阻,可确保LED发出明亮的光。
小费
有关Raspberry Pi上的GPIO的介绍,请访问http://www.raspberrypi.org/documentation/usage/gpio/ 。
可以在http://elinux.org/RPi_Low-level_peripherals找到有关GPIO引脚的两个指南。
有关更多信息,请参阅http://pi.gadgetoid.com/pinout 。
下图显示了原型板的电路图:
与硬件交互
使用Clayster.Library.RaspberryPi库中定义的相应类与硬件进行交互。 例如,使用DigitalOutput类处理数字输出,并使用DigitalInput类处理数字输入。 连接到I 2 C总线的设备使用I 2 C类进行处理。 还有其他通用类,例如ParallelDigitalInput和ParallelDigitalOutput,它们可以一次处理一系列数字输入和输出。
SoftwarePwm类处理软件控制的脉冲宽度调制输出。 Uart类使用Raspberry Pi上可用的UART端口处理通信。 还有一个名为设备的子命名空间,其中提供了特定于设备的类。
最后,所有类都与静态GPIO类进行通信,该类用于与Raspberry Pi中的GPIO层进行交互。
每个类都有一个构造函数,用于初始化相应的硬件资源,与资源进行交互的方法和属性,以及用于释放资源的Dispose方法。
小费
在终止应用程序之前释放分配的硬件资源很重要。 由于硬件资源不受操作系统的控制,因此终止应用程序这一事实不足以释放资源。 因此,请确保在离开应用程序之前调用所有已分配硬件资源的Dispose方法。 优选地,这应该在try-finally块的最终声明中完成。
连接硬件
用于LED的硬件接口如下:
private static DigitalOutput executionLed = new DigitalOutput (23, true);
private static DigitalOutput measurementLed = new DigitalOutput (24, false);
private static DigitalOutput errorLed = new DigitalOutput (25, false);
private static DigitalOutput networkLed = new DigitalOutput (18, false);
对运动检测器使用DigitalInput
类:
private static DigitalInput motion = new DigitalInput (22);
将温度传感器放在I 2 C总线上,它将串行时钟频率限制为最大400 kHz,请按以下方式进行接口:
private static I2C i2cBus = new I2C (3, 2, 400000);
private static TexasInstrumentsTMP102 tmp102 =
new TexasInstrumentsTMP102 (0, i2cBus);
我们使用模数转换器与光传感器进行交互,如下所示:
private static AD799x adc =
new AD799x (0, true, false, false, false, i2cBus);
传感器值的内部表示
传感器数据值将由以下变量集表示:
private static bool motionDetected = false;
private static double temperatureC;
private static double lightPercent;
private static object synchObject = new object ();
还将保留历史值,以便可以分析趋势:
private static List perSecond = new List ();
private static List perMinute = new List ();
private static List perHour = new List ();
private static List perDay = new List ();
private static List perMonth = new List ();
持久数据
持久数据很简单。 这是使用对象数据库完成的 。 该对象数据库分析要保留的对象的类定义,并动态创建数据库架构以容纳要存储的对象。 对象数据库在Clayster.Library.Data library
定义。 您首先需要对对象数据库的引用,如下所示:
internal static ObjectDatabase db;
然后,您需要提供有关如何连接到基础数据库的信息。 这可以在应用程序的.config文件或代码本身中完成。 在启动过程中,指定一个SQLite数据库并在代码中提供必要的参数:
DB.BackupConnectionString = "Data Source=sensor.db;Version=3;";
DB.BackupProviderName = "Clayster.Library.Data.Providers."
+ "SQLiteServer.SQLiteServerProvider";
最后,您将获得对象数据库的代理对象。 该对象可用于存储,更新,删除和搜索数据库中的对象:
db = DB.GetDatabaseProxy ("TheSensor");
完成此操作后,如果重新启动Raspberry Pi,传感器将不会丢失数据。
传感器值的外部表示
为了促进设备之间传感器数据的交换,您需要一种基于XML的可互操作的传感器数据格式,该格式在Clayster.Library.IoT
库中提供。 在此,传感器数据由节点的集合组成,这些节点报告根据时间戳排序的数据。
对于每个时间戳,报告一组字段。 有不同类型的字段可用:数字,字符串,日期和时间,时间跨度,布尔值和枚举值字段。 每个字段都有一个字段名称,相应类型的字段值,可选的读取类型,字段状态,服务质量值和本地化信息。
Clayster.Library.IoT.SensorData
命名空间通过提供一个称为ISensorDataExport的抽象接口来帮助您导出传感器数据信息。 以后可以使用相同的逻辑导出到不同的传感器数据格式。 该库还提供了一个名为ReadoutRequest的类,该类提供有关所需数据类型的信息。 您可以使用它来调整数据导出以符合请求者的需求。
导出传感器数据
导出通过在传感器数据导出模块上调用Start()
方法开始,并以对End()
方法的调用End()
。 在这两者之间,执行一系列StartNode()
和EndNode()
调用,每个要导出的节点一个。
为了简化导出,可以调用另一个函数从包含数据的Record对象数组中输出数据。 使用相同的方法通过创建包含瞬时值的临时Record对象来导出瞬时值:
private static void ExportSensorData (ISensorDataExport Output,
ReadoutRequest Request)
{
Output.Start ();
lock (synchObject)
{
Output.StartNode ("Sensor");
Export (Output, new Record[]
{
new Record (DateTime.Now, temperatureC, lightPercent, motionDetected)
},ReadoutType.MomentaryValues, Request);
Export (Output, perSecond, ReadoutType.HistoricalValuesSecond, Request);
Export (Output, perMinute, ReadoutType.HistoricalValuesMinute, Request);
Export (Output, perHour, ReadoutType.HistoricalValuesHour, Request);
Export (Output, perDay, ReadoutType.HistoricalValuesDay, Request);
Export (Output, perMonth, ReadoutType.HistoricalValuesMonth, Request);
Output.EndNode ();
}
Output.End ();
}
请注意,在导出此类数据之前,需要检查客户端是否需要相应的读出类型。
学到更多:
如何在Raspberry Pi中使用OpenCV
如何使用Raspberry Pi和Artik构建IoT项目
Export方法导出Record对象的枚举。 在导出此类数据之前,它首先检查客户端是否需要相应的读取类型。 该方法还检查数据是否在请求的时间间隔内以及该字段是否对客户端有意义。
如果数据字段通过所有这些测试,则通过调用重载方法ExportField()的任何实例将其导出,该方法在传感器数据导出对象上可用。 字段在StartTimestamp()
和EndTimestamp()
方法调用之间导出,定义了与要导出的字段相对应的时间戳:
private static void Export(ISensorDataExport Output, IEnumerable History,
ReadoutType Type,ReadoutRequest Request)
{
if((Request.Types & Type) != 0)
{
foreach(Record Rec in History)
{
if(!Request.ReportTimestamp (Rec.Timestamp))
continue;
Output.StartTimestamp(Rec.Timestamp);
if (Request.ReportField("Temperature"))
Output.ExportField("Temperature",Rec.TemperatureC, 1,"C", Type);
if(Request.ReportField("Light"))
Output.ExportField("Light",Rec.LightPercent, 1, "%", Type);
if(Request.ReportField ("Motion"))
Output.ExportField("Motion",Rec.Motion, Type);
Output.EndTimestamp();
}
}
}
您可以通过使用SensorDataXmlExport类将一些传感器数据导出到XML中来测试该方法。 它实现了ISensorDataExport接口。 如果仅导出瞬时和历史日期值,结果将类似于以下内容:
...
如果您喜欢阅读本教程并想详细探讨物联网,则可以浏览 Peter Wahr撰写 的《 学习物联网 》一书 。 这本书采用了动手实践的方法,并演示了多个物联网项目的构建,包括执行器,摄像机,控制器等。 如果您是IoT爱好者或热衷于学习IoT基础知识的开发人员,那么这本书是您的必备工具。
翻译自: https://www.javacodegeeks.com/2018/08/iot-sensor-project-raspberry-pi-sensors.html