适用于罗姆传感器评估套件的轻量级 Arduino库

这篇文章来源于deviceplus.com英语网站的翻译稿。
@corestaff
罗姆传感器评估套件是一种兼容 arduino 的扩展板 (shield),配有以下8钟传感器:加速度计、压力传感器、地磁传感器、照度/接近传感器、颜色传感器、霍尔传感器、温度传感器和紫外线传感器。该传感器扩展板的设置指南请参阅arduino传感器 – rohm传感器评估套件概览。单个传感器的 arduino 库以及详细文档可以从官网上下载:https://www.rohm.com/web/global/sensor-shield-support
对于要用的每个传感器,官网所列的库都要求您在 arduino 程序中包含另外一个库。如果您计划只使用一个或两个传感器,那么这样做行得通,但是如果您决定让单个 arduino uno 开发板同时处理多个传感器(比如6个传感器)呢?!
硬件
arduino uno或mega
罗姆传感器评估套件
软件
arduino ide
github – 罗姆multisensor库
上述链接是一个专门用于罗姆 multisensor 的github程序库——该单个 arduino 库能够让您控制罗姆传感器评估套件中的所有传感器,不需要单独包含每个传感器库,因此可以节省时间。此外,这个库允许您根据当前要求设置传感器——这是原罗姆库目前所缺乏的特性。该库的另一个优点就是符合 arduino 1.5 ide 规范。它还包括自定义语法高亮显示功能、详细的自述 (readme) 文件和大量实例!
与罗姆提供的库比较
我们假设您想用罗姆提供的库连接所有传感器。这不仅会导致 arduino 程序相当长,而且还会造成后台运行许多不必要的运算。比如,每个库都有自己的i2c总线控制方法,但它们都相同。所有这些都会增加 arduino 程序的整体大小和内存使用量。我们能不能只用一个i2c方法呢?下图显示了使用所需6个罗姆库时的程序编译器输出:
图 1. 使用罗姆提供的库处理所有传感器时的编译器输出
9886 字节似乎不是很大,但是记住,该程序除了从传感器中提取数据并在串口上显示之外,没有做任何其他事情。这个数字告诉我们,尽管任务非常简单,但是却占用了三分之一的存储空间。这在添加更多功能时会造成空间问题。
现在,让我们比较一下使用罗姆 multisensor 库的程序的编译器输出,其功能完全一样:
图 2. 使用罗姆  multisensor 库处理所有传感器时的编译器输出。
请注意闪存存储空间和内存需求都减少了。
您可以看到,我们节省了超过 2000 字节的闪存存储空间以及100字节的内存需求 !
同时使用多个传感器的5个步骤
让我们看一下上文提到的例子——在单个arduino开发板上运行6个罗姆传感器。所用传感器包括:加速度计(kx022 – 1020)、压力传感器(bm1383glv)、照度/接近传感器(rpr-0521rs)、颜色传感器(bh1745nuc)、温度传感器(bd1020hfv) 和紫外线传感器 (ml8511a)。
图 3.同时使用6个传感器
使用这些传感器的理由非常简单:它们的工作电压都是3v。由于我们只能在扩展板上为所有传感器设置一种电压电平,因此我们必须使用大多数传感器支持的电压。使用罗姆multisensor库时,代码如下所示:
// definition #define include_kx022_1020 #define include_bm1383glv #define include_rpr_0521rs #define include_bh1745nuc #define include_bd1020hfv #define include_ml8511a // inclusion #include // instantiation kx022_1020 acc; bm1383glv bar; rpr_0521rs als; bh1745nuc rgbc; bd1020hfv temp; ml8511a uv; void setup() { serial.begin(9600); wire.begin(); // initialization acc.init(); bar.init(); als.init(); rgbc.init(); temp.init(analog_1); uv.init(analog_2); serial.println(x[g]ty[g]tz[g]tp[hpa]tps[cnt]tals[lx]tr[-]tg[-]tb[-]tc[-]tt[dg c]tuv[mw/cm^2]); void loop() { //measurement float* accelvalue = acc.measure(); float pressvalue = bar.measure(); float psvalue = als.measure(ps); float alsvalue = als.measure(als); unsigned int* rgbcvalue = rgbc.measure(); float tempvalue = temp.measure(); float uvvalue = uv.measure(); serial.print(accelvalue[0]); serial.print('t'); serial.print(accelvalue[1]); serial.print('t'); serial.print(accelvalue[2]); serial.print('t'); serial.print(pressvalue); serial.print('t'); serial.print(psvalue); serial.print('t'); serial.print(alsvalue); serial.print('t'); serial.print(rgbcvalue[0]); serial.print('t'); serial.print(rgbcvalue[1]); serial.print('t'); serial.print(rgbcvalue[2]); serial.print('t'); serial.print(rgbcvalue[3]); serial.print('t'); serial.print(tempvalue); serial.print('t'); serial.println(uvvalue); delete[] accelvalue; delete[] rgbcvalue; delay(100); }
arduino ide串行绘图仪(serial plotter)的输出如下图所示。当然,这种输出几乎无法用于任何实际用途。然而,它表明所有传感器都在工作并测量数据。
图 4. 所有6个传感器的串行绘图仪输出
使用这个库时,您必须按照以下五个步骤进行配置:定义、包含、实例化、初始化和测量。这听起来比较复杂,所以我们接下来详细解释每一步。
1.定义
第一步就#define(定义)所有要使用的传感器。下面的步骤解释了为什么必须首先执行这些定义。
为了缩短代码,您可以使用一个预编程的简化定义。#define include_all_1v8_sensors#define include_all_3v0_sensors和#define include_all_5v0_sensors。比如,#define include_all_1v8_sensors将会定义所有推荐供电电压为1.8v的传感器。而电压为3v和5v的定义语句分别为:#define include_all_3v0_sensors和#define include_all_5v0_sensors。
2.包含
这实际上就是您#include(包含)库头文件的地方。在此步骤之前必须完成所有传感器#define语句的原因很简单:头文件(罗姆multisensor.h)中包含了其他的传感器特定文件,而这必须以定义适当传感器为基础。这使得库可以根据用户需求动态改变其大小,从而节省arduino闪存存储空间和内存需求。
3.实例化
因为每个传感器都有自己的类,因此访问其方法之前,您必须创建该类的一个实例。该过程被称为实例化,您所要做的就是输入传感器类名,然后紧跟实例名。比如:
bm1383glv bar;
该语句会创建一个bm1383glv类实例,而且您可以通过名称bar访问该实例。
4.初始化
每个传感器在使用前都必须初始化。您所要做的就是为每个传感器调用.init()方法。此方法在成功完成后返回0,如有任何问题,则返回1。您可以用以下代码检查所有传感器是否都已经成功初始化:
void setup() { if(bar.init() == 1) { // there was an error, you have to fix it! } // everything went fine, you can start measuring!
.init()方法还有一个额外功能:更改传感器设置。您可以通过传递各种参数来改变传感器的行为。
比如我们想要改变压力传感器的工作模式。在默认模式下,传感器会测量200毫秒,然后返回平均值。如果我们想让传感器运行得更快(可能会变得不那么准确),我们可以使用以下参数调用.init()方法:
bar.init(bm1383glv_continuous_100_ms);
现在,测量只会在100 ms的工作模式下进行。每次重新启动传感器之后,所有设置都会被重置为默认值。这通常只与整个arduino重置(即按重置按钮)相关,所以这并不是一个问题。
请参阅github库参考 文件,以获得每个传感器当前已经实现的完整设置列表。
注:这些设置都是可选设置;通常,默认设置就已足够(即直接调用.init(),无需任何参数)。
5.测量
此时,一切准备就绪,可以开始测量数据了。您可以通过调用所用传感器的.measure()方法执行此操作。该方法无需参数,其返回数据类型取决于传感器种类。有些传感器会返回单个数值——一个浮点数或者一个整数。
float pressvalue = bar.measure();
上述语句示例会通过bm1383glv传感器测量压力,并返回单位为hpa的压力数值。
然而,有些传感器需要返回多个数值。比如,kx022-1020 加速度计会测量三个轴上的减速度:x、y和z。显然,我们需要使用一个数组,以返回所有数值。数组所用内存是动态分配的,所以当我们不需要数组时,我们必须重新释放内存。
在下面的例子中,我们定义、包含、实例化并启动kx022-1020加速度计。然后,我们创建一个名为accelvalue的浮点数动态数组。如果我们后面不再需要数组,我们可以通过delete[]释放内存。这样可以确保没有内存泄漏。内存泄漏是指动态分配的内存无法正确释放,并且只要arduino未重置就不可访问的情况。在这个例子中,您会看到如何正确释放动态分配的内存。
#define include_kx022_1020 #include kx022_1020 acc; void setup() { serial.begin(9600); wire.begin(); acc.init(); serial.println(x[g]ty[g]tz[g]”); } void loop() { // dynamically create an array float* accelvalue = acc.measure(); // now we can access the elements in accelvalue array serial.print(accelvalue[0]); serial.print('t'); serial.print(accelvalue[1]); serial.print('t'); serial.println(accelvalue[2]); //safely deallocate the memory delete[] accelvalue; delay(100); }
中断和bm1422gmv地磁传感器
如果您用过arduino,您很可能已经见过中断功能了。即使没有,也请不要担心,如果设置正确,中断用起来很简单。
简单来讲,中断就是让arduino“跳转”至代码特定部分的信号。这部分代码是一种称为中断服务程序的特殊函数,通常简称为isr。中断的最常见用途就是进行精确时序控制,所以isr函数应尽可能短。此外,中断函数不带任何参数,也不会返回任何值。
让我们来看一下需要正确设置中断的bm1422gmv地磁传感器。
#define include_bm1422gmv #include bm1422gmv mag; void isr(void) { mag.setflagdrdy(); } void setup() { serial.begin(9600); wire.begin(); mag.init(isr); serial.println(x[ut]ty[ut]tz[ut]); } void loop() { float* magvalue = mag.measure(); serial.print(magvalue[0]); serial.print('t'); serial.print(magvalue[1]); serial.print('t'); serial.println(magvalue[2]); delete[] magvalue; delay(100); }
我们需要内存释放(因为与加速度计类似,bm1422gmv会返回三个轴的数值)以及isr。您可以看到,中断只是在bm1422gmv类中形成一个标志,表示有新数据需要收集。.setflagdrdy()方法是该库的一部分。请注意,您必须向.init()方法提供isr名称。
然而,只在代码中设置中断服务程序是不够的。我们需要在扩展板上选择正确设置。
arduino uno具有两个外部中断:int0(引脚d2)和 int1(引脚d3)。我们必须将适当的引脚连到传感器上的int引脚。您可以在类的实例化中选择使用哪个中断。使用arduino引脚d2中断的默认值为int_0,或者如果arduino d2上的中断已经用于其他设置,您可以将其改为int_1。
图 5. 负责中断设置的所有引脚概览
要将传感器中断连至arduino,我们应使用j3和j4排针。j3将中断连至arduino d2,而j4则将中断连至d3。每个排针都有标记为int1至int5的引脚以及标记为intr1至intr5的引脚。这是因为传感器具有两种不同的中断输出:
cmos类型输出:kx022-1020和bm1422gmv属于这种输出。这些中断信号可以直接连至 arduino,并且使用引脚intr1-5。
需要外部上拉电阻的中断:使用这种中断的传感器为bh1745nuc和rpr-0521rs。它们会使用引脚int1-5。注:在排针j16上,相应的引脚号必须短接,以使能外部上拉电阻。比如,如果要在j3上使用int1引脚,您还必须将int1短接至j16。
我们再看一下上文给出的示例代码。我们想要把arduino的int0连至bm1422gmv的int引脚。假设传感器连到了i2c_1插槽。在这种情况下,我们应将intr1引脚短接至j3。
图 6. bm1422gmv连至i2c_1插槽时的中断设置
如果任何其他传感器需要使用中断——比如bh1745nuc颜色传感器,那么中断设置步骤如下所示:如果我们将传感器连至i2c_3并且要使用arduino的中断int1,那么我们应将引脚int3短接到j4和j16上,因为该传感器需要一个外部上拉电阻。
图 7. h1745nuc连至i2c_3插槽时的中断设置
有关中断的详细信息以及针对不同传感器的设置信息,请参考该库readme中的注释部分。
技巧和决窍
1.地磁传感器(bm1422gmv)是唯一需要中断才能工作的传感器。然而,所有其他i2c传感器也可以使用中断。库的运行不需要使能中断,但是这在一些应用程序中可能非常有用。目前,除磁力计之外,库中没有实现其他传感器的中断功能。
2.使用霍尔(bd7411g)传感器时,向arduino上传程序之前必须断开传感器。否则,您将在上传程序时收到以下错误信息:avrdude: stk500_getsync() 错误。这是因为bd7411g上的out引脚直接连至arduino引脚d0,而d0还是串行rx引脚。如果没有检测到磁场,那么bd7411g的输出为高电平(high),这会阻止串行端口的任何传入通信——包括程序上传。
图8.使用bd7411g时可能遇到的错误示例。请注意,如果您在arduino ide设置中关闭了详细输出,您将只会收到一条消息:“上传程序时出现错误(an error occurred while uploading the sketch)”。要打开详细输出信息,请转到arduino ide ->文件(file)->首选项(preferences),然后勾选“上传时显示详细输出(show verbose output during upload)”。
3.当使用其中一个模拟传感器(bd1020hfv温度传感器或ml8511a uv传感器)时,您必须提供传感器所连接的插槽名称。扩展板上有两个模拟插槽:analog_1和analog_2。为其中一个模拟传感器调用.init()方法时,您必须向.init()方法提供插槽名称(即调用.init(analog_1),以初始化连至插槽analog_1的模拟传感器)。作为安全措施,如果您没有提供任何内容,.init()的默认值将会是 analog_1,然而,传感器必须连至插槽analog_1。如果您从模拟传感器获取的数据很奇怪,那么请首先确保您提供的插槽名称与传感器相连的插槽一致。
本文的主要目的是为罗姆源代码提供一种潜在的替代方案。顾名思义,如果您需要在罗姆传感器评估套件中处理多个传感器,那么罗姆multisensor库将会非常有用——您的下一个大型项目可能会需要这个库!
如果您有任何改进建议,请github上进行分享:创建修改意见;或者在问题(issues) 选项卡中建立github问题。创建github问题非常简单,您的反馈对我们来说非常有价值。另外,如果您喜欢这个库,如果您的代码由此变得更漂亮,那么请考虑赏给罗姆multisensor程序库一颗星。尽情开发吧!
jan gromes
jan目前在布尔诺理工大学学习电气工程。他拥有多年使用arduino和其他微控制器构建项目的经验。他的特殊兴趣在于机器人系统的机械设计。


中国最新研发的“鸽子”无人机完成试飞
维护和安全在让设备和设施保持正常工作方面起着重要作用
利用SPMC65P2404A单片机做红外接收
2019年国产芯片自给率仅为30%,截止到2025年需实现70%
西门子博途中程序编辑器的功能
适用于罗姆传感器评估套件的轻量级 Arduino库
倒装LED芯片技术你了解多少
iPhone总产能较去年的订单减少20%,反映苹果对出货量看法转趋谨慎
多点触控竞争升级,鼠标2.0抢占最新商机
塑料激光焊接技术对塑料材质的实践分析
WR3000M高性能综合返修台的特点及应用
射频放大电路的优化及ADS仿真
自复式过欠压保护器参数的确定原则
DPDK如何处理物理内存
国内基础软件的发展现状及未来机遇
2010十大科技猜想:超级电容车将面世
宏碁投资打造IMAX VR娱乐产业,上海将成为试点
首个成功通过思想来控制的机械臂,它具有连续跟踪和跟随计算机光标的能力
最简单的自举电路图分析
怎样确保PLC与扩展模块的连接牢固度?