成为订阅者(免费)

加入29,000名其他订阅者以获得用户销售折扣和 其他免费资源。
:
:
大学教师'担心 - 您的邮件地址完全是 安全的。我保证使用它 只要 to send you MicroZine.

arduino. Planein.

arduino. Planein. 功能测量a的时间段 high or 低脉冲输入信号。典型用途是测量来自的 超声波距离模块(HC-SR04)输出信号时段 与往返声反射时间成比例,您可以从中计算距离。

以下实施例显示了脉冲素和PlainiNlong的正确用途(需要打开中断)。

测量高脉冲

Nointerrupts();
脉冲素(<pin>, HIGH);
中断();
or
Playsinlong(<pin>, HIGH);
笔记: 高/低参数让您测量 高或低时期的信号。您只能执行高低或低 测量并不同时进行。

测量频率使用脉冲素

您还可以使用此功能来测量频率(两次测量 需要一个来测量低期间和一个测量高位 时期 - 除非您知道空间率的标志甚至是在这种情况下 你只需要一个测量)。 该项目使用Pulsein来测量TCS320频率输出.

脉冲可以测量脉冲 2-3us至3分钟。它 提供了一种在任何引脚上测量信号周期的简单方法。有 事实上,下面探索的功能的两个版本(Pulsein和 Playsinlong)一个使用中断,一个是在汇编器中编码的。 

笔记: 脉冲素测量高或低时间段,而信号连续重复。

该功能也有超时 - 如果这到期 然后该函数返回零(默认超时为1秒)。

对于不同的超时,请使用最后一个参数的无符号长值:

Nointerrupts();
pulseIn( <pin>,高,10000000UL); // 10秒超时。
interrupts();

arduino. 脉冲宽度测量例

以下代码预计PIN 7上的信号并使用脉冲素 衡量它的功能。然后将其报告给串行接口。

超时值设置为3秒钟,并且代码还报告何时触发指示不存在信号。

// pulseIn Example

const byte INPIN = 7;

void setup() {
   Serial.begin(9600);
   别针Mode(INPIN, INPUT);
}

void loop() {
unsigned long res;

  Serial.print("Time: ");
  Serial.println(millis());
  Serial.println("Measuring...");
  Serial.flush(); // Needed since serial requires interrupts to operate.

  noInterrupts();
  res =  脉动 (INPIN, HIGH, 3000000UL);
   在 terrupts();

  if (res) {
     Serial.print("Time high (us): ");
     Serial.println(res);
  } else
     Serial.println("No signal present");

}

这里'S没有信号输入的程序输出:

时间:0
测量...
没有信号存在
时间:24
测量...
没有信号存在
时间:70
测量...
没有信号存在
时间:116

你看到了什么'错了? - 没有中断所以millis()无法工作 事实,值应该在读数之间至少增加3000ms 脉冲素超时时间为3000ms。

这向您展示了您可能想要使用的原因原因 除非中断是活跃的,否则Planeinlong - Millis将起作用。改变 以上代码使用PlaneInlong来检查(不要忘记评论 中断控制功能)。

这里'S带有1kHz信号输入到PIN7的输出:

测量...
时间高(美国):499
时间:11817
测量...
时间高(美国):501
时间:11869
测量...
时间高(美国):500
时间:11919
测量...
时间高(美国):500
时间:11970
测量...
时间高(美国):500
时间:12020

这仍然使用脉冲素,但毫无威尔的原因 工作是脉冲函数不是时机,它正在服用 返回结果最多1.5ms。

结论 - 它'很容易忘记脉冲不允许 中断 - 如果您使用Plablein和 Millis()。上面的最后一页不是中断以来的真时 脉冲in完成时,关闭了〜1.5ms。

脉冲和脉冲长的差异

脉冲或脉冲隆?

有两个版本的脉冲素:

  • 脉动
  • 脉冲龙

它们都具有相同的规范,并返回相同的结果。 测量脉冲从2-3us到3分钟,但第一个使用汇编程序 常规以进行测量,而第二个是使用Timer0中断 计算结果。

第一个:脉冲素可以使用,如果断开中断(如果是) 他们休息将返回更准确的结果 - 自赢了't be interrupted 测量),除非中断,否则不能使用第二个。 turned on!

提示: 关闭中断以获得更准确的脉冲素 result.

arduino. Planein VS Playsinlong表

Planein VS Playsinlong.
功能
用法
与中断一起使用
范围
Planein()
最好的短脉冲。 [*]
必须关闭[**]
2-3us至3min
Playsinlong() 最好的长脉冲。 必须打开。
2-3us至3min
*长脉冲测量值会有更大的错误,因为校准是经验的。
**见下面的实验显示中断对脉冲精度的影响。

似乎脉冲隆起是更好的选择,因为它依赖 在硬件中断。但是,如果其他中断火灾,那么这 例程必须等待他们完成e。一个串行港口 中断等所以您可能会随着中断而获得更好的结果 using pulseIn().

然而,脉冲素已经经验校准(通过观察)所以其 产出是一个估计,但它似乎是较低的一个很好的 脉冲宽度。脉冲宽度长的问题是错误构建 UP,因此报告的脉冲宽度中的错误将增加。

arduino. Plansin如何工作

让我们假设我们将测量信号的高部分。

要测量脉冲,该函数必须等待任何现有 脉冲消失,使其可以从一开始就开始测量 完整的脉冲。所以这个功能的第一件事是 检查输入的当前状态。

1.如果输入高,则等待信号降低。等等,直到输入处于非活动状态。

2.接下来,等待输入低于(等待活动状态高)。

3.找到高输入信号然后启动计数。

4.等待信号再次失效(低)。

5.停止计数。

计数现在表示高脉冲周期的时间段。

对于低脉冲,在上面的描述中仅换流高而低。

 arduino. 脉冲操作显示信号输入和算法操作


arduino. Planesin Delay.

从Pulsein工作(见上文)的方式可以看出它是 依赖于输入信号。如果您在输入时启动功能 有效的功能必须等待。那里'没有办法知道什么时候 信号是启动,因为信号是外部异步信号。

注意:这就是为什么存在超时参数 - 以便如果信号是 缺少函数不会永远保持输入引脚。

该功能然后等待非活动脉冲的整个时间。

因此,对于频率f的输入信号(具有相同的标记到空间 比率)你可以等待一段时间从1.5t之间到 在获得结果之前,0.5t(其中t = 1 / f)。

Planein Arduino源代码

您可以在以下目录中找到Plucein的源代码:

C:/计划 文件/ arduino /硬件/ arduino / avr / cores / arduino / wiring_pulse.c

对于汇编程序版本,您可以找到代码

C:/计划 文件/ arduino / hardware / arduino / avr / cores / arduino / wiring_pulse.s

对于32位机器,位置将从以下位置开始:

    C:/程序文件(x86)/ arduino /

以下是用于生成自动汇编程序的源代码 output:

/*
 * The following routine was generated by avr-gcc 4.8.3 with the following parameters
 * -gstabs -Wa,-ahlmsd=output.lst -dp -fverbose-asm -O2
 * on the original C function
 *
 * unsigned long pulseInSimpl(volatile uint8_t *port, uint8_t bit, uint8_t stateMask, unsigned long maxloops)
 * {
 *     unsigned long width = 0;
 *     // wait for any previous pulse to end
 *     while ((*port & bit) == stateMask)
 *         if (--maxloops == 0)
 *             return 0;
 *
 *     // wait for the pulse to start
 *     while ((*port & bit) != stateMask)
 *         if (--maxloops == 0)
 *             return 0;
 *
 *     // wait for the pulse to stop
 *     while ((*port & bit) == stateMask) {
 *         if (++width == maxloops)
 *             return 0;
 *     }
 *     return width;
 * }
 *
 * some compiler outputs were removed but the rest of the code is untouched
 */ 

在上述注释之后,呈现汇编程序输出。这 汇编器输出(未示出)是从显示的原始C代码生成的 在评论中,所以要了解什么 汇编程序输出正在执行读取上述C代码。

笔记: 以这种方式生成汇编程序意味着它不是 由C编译器编译,因此意味着它无法改变 C compiler is "improved"。所以即使C代码或C代码为单位,也将是一致的 编译器改变了事物。问题是它只能在AVR上运行 这就是目录结构显示AVR - 其他处理器需要的原因 不同的等效代码。

代码通过递增变量来测量脉冲'width' within the 最后一个循环。前两者在那里循环准备 measurement.

这很简单。如果你想到连续的方波脉冲,并让它 假设你想找到信号的高部分的时期,然后你会 set the variable 'state'(在下面的C代码中)高的是设置的 statemask高的对应位。

算法首先找到一个实例 信号很高(如果有,但自从你不'知道你是否找到了 高度的中间,你不能告诉你是否在开始时 脉冲。然后算法等待低,以确保下一个高输入是a的开始 pulse.

所以这就是第一个,而循环正在做准备找到的东西 信号开始,第三个在等待时执行测量 对于脉冲再次低得多。

  1. 虽然有效等待无效的脉冲极性 - 等待上一个结束 pulse.
  2. 虽然无效等待有效的脉冲极性 - 等待脉冲 start.
  3. 虽然有效的极性增量宽度脉冲 - 等待脉冲停止。

该操作如下图所示

 arduino. 脉冲操作显示信号输入和算法操作

代码生成的函数是:

countpulseasm.

从代码的C部分,我们具有以下原型(或功能 definition):

unsigned long  脉动 (uint8_t 别针, uint8_t 状态, unsigned long timeout)

其中,您可以指定用作输入和所需脉冲状态的PIN 即,您是否正在寻找有效的高或活跃低脉冲,以及 微秒中的超时参数 - 等待脉冲的最长时间 到达(以微秒为单位)。

完整代码如下所示,用作周围的包装例程 汇编程序代码并将位,端口和StateMask定义为固定数量(这样 汇编程序代码不必使用DigiteWrite等。因此 fast).

逐个第16次的软糖因子照顾从超时转换 通过汇编程序代码通过一个循环来循环微秒 - 评论说,汇编程序例程每次需要大约16个周期 iteration.

警告: 超时乳脂因子(/ 16)只允许这个 汇编程序版本的Plablein以16MHz正常运行。这可能是 为什么有一个中断驱动版本(PulseInlong) - 自那个版本以来 使用Timer0它不会使用乳脂因子。

在代码末尾,清理汇编器的输出:在事件中 汇编器代码T中的超时返回零宽度。

unsigned long  脉动 (uint8_t 别针, uint8_t 状态, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution.  calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t 状态Mask = (state ? bit : 0);

// convert the timeout from microseconds to a number of times through
// the initial loop; it takes approximately 16 clock cycles per iteration
unsigned long maxloops = microsecondsToClockCycles(timeout)/16;

unsigned long 宽度 = countpulseasm.(portInputRegister(port), bit, 状态Mask, maxloops);

// prevent clockCyclesToMicroseconds to return bogus values if countPulseASM timed out
if (width)
return clockCyclesToMicroseconds(width * 16 + 16);
else
return 0;
} 

Playsinlong Arduino源代码

函数PlainInlong遵循与汇编器代码相同的算法 以上工作以类似的方式来查找有效脉冲的开始(见上文 描述)。唯一的区别是定时机制使用该值 从micros()函数。此函数返回从Timer0计算的值 Playsinlong要求中断是活动的。

时序机制使用存储时间的标准技术 无符号长,从micros中减去它以获得经过的时间。

笔记: PlaneInlong将返回比 脉冲素可以通过运行中断来中断。
unsigned long 脉冲龙(uint8_t 别针, uint8_t 状态, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution.  calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t 状态Mask = (state ? bit : 0);

unsigned long startMicros = micros();

// wait for any previous pulse to end
while ((*portInputRegister(port) & bit) == 状态Mask) {
if (micros() - startMicros > timeout)
return 0;
}

// wait for the pulse to start
while ((*portInputRegister(port) & bit) != 状态Mask) {
if (micros() - startMicros > timeout)
return 0;
}

unsigned long start = micros();
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == 状态Mask) {
if (micros() - startMicros > timeout)
return 0;
}
return micros() - start;
} 

Pulse Accuracy

arduino. 参考说明这两个函数都是从10us工作的 3分钟,而代码状态的评论是准确的 2-3us to 3minutes.

arduino. Planein精确度

如果在a期间关闭中断,则可以提高脉冲素的准确性 否则代码将由任何运行中断进行中断 例如Timer0,改变脉冲测量时间并改变输出。笔记 这仅适用于脉冲素,而不是脉冲隆(Pulseinlong依赖于 interrupts).

算法的准确性很难说,因为存在嗜好因素 分裂 - 16。你可以说的是代码将返回一致 结果相同的信号。还要记住,如果您的arduino使用a resonator it won'无论如何都是那种准确的。

arduino. Planesinlong精度

该算法仅取决于函数体积() 中断驱动定时器。它的准确性与准确性相同 在micros()函数中使用的计时器,即它将具有准确性 主系统时钟。

但请记住,任何中断都无法在另一个中断 中断正在维修。如果有很多中断射击 然后,Pulseinlong的准确性将降低。

arduino. Planein测试草图

以下草图显示了如何使用Plaulin并允许您比较 不同函数版本的操作。

以下草图测量所附信号的高低周期 引脚4 - 您可以使用任何数字引脚。代码的平均值为10 读数为高时俱进,低期间的10个读数和平均值 每套结果。然后它添加它们并使用浮点来计算 输入信号的频率。注意信号源不是非常稳定的 - 仅在1KHz输出频率下的RC振荡器。

//
// PulseIn Test program.
//
// Measures 10 high and 10 low periods
// and calculates each average. Then calculates
// The freuqnecy of the signal.
//
// Two test controls are used:
// noPulseInterrupts when high stops interrupts during
//    the measurements.
// usePulseInLong when high switches to pulseInLong function.
//
// Input is a 0~5V 1kHz squarewave to INPUTPIN.
//
// Copyright John Main - Free for non commercial use.
//
void setup() {
   Serial.begin(115200);
}

#define INPUTPIN 4

// Controls
#define noPulseInterrupts 1
#define usePulseInLong    0

// Must have interrupts for pulseInLong
#if usePulseInLong
  #define noPulseInterrupts 0
#endif

void loop() {
uint8_t i;
uint16_t avg1,avg2;
static unsigned  在 t stop=0;
unsigned long val;
float f;

  avg1=0;
  if (stop==0) {
    for(i=0;i<10;i++) {

        if(noPulseInterrupts) Nointerrupts();
           if (usePulseInLong)
              val = 脉冲龙(INPUTPIN,HIGH,10000);
           else
              val =  脉动 (INPUTPIN,HIGH,10000);
        中断();

        Serial.print(i);Serial.print(" ");
        Serial.println(val);
        avg1+=val;
    }

    avg1/=10;

    Serial.print("Avg high:");Serial.print(avg1);
    Serial.println("\n-------");

    avg2=0;
    for(i=0;i<10;i++) {

        if(noPulseInterrupts) Nointerrupts();
           if (usePulseInLong)
              val = 脉冲龙(INPUTPIN,LOW,10000);
           else
              val =  脉动 (INPUTPIN,LOW,10000);
        中断();

        Serial.print(i);Serial.print(" ");
        Serial.println(val);
        avg2+=val;
    }

    avg2/=10;

    Serial.print("Avg  low:");Serial.println(avg2);
    Serial.println("\n-------");

    f =1.0 / ( (avg1 + avg2)*1e-6 );
    Serial.print("Frequency: ");
    Serial.println(f);

  }
  stop=1;

  if (Serial.read()=='1') stop = 0;

}

arduino. Planein草图输出

以下结果适用于中断的脉冲素。

0 497
1 497
2 497
3 497
4 491
5 492
6 491
7 491
8 491
9 491
Avg high:493
-------
0 449
1 447
2 446
3 469
4 493
5 493
6 493
7 493
8 487
9 487
Avg  low:475

-------
Frequency: 1033.06

上述结果用于当中断运行时使用脉冲素。 发生不准确的结果。

以下一组结果显示了中断和的差异 关闭(对于脉冲素)和Pulseinlong的结果(需要中断 积极的)。在PIC频率上测量输入信号为1013至1014Hz 柜台。它稍微漂移,因为源不是很高的稳定性。

最一致的结果是汇编版本(Plaulsin) with 中断。当中断在脉冲脉冲结果上产生了很多。 有趣的是,Planeinlong结果一直稳定并比较 very well 脉冲(INTS OFF)。

如果你需要有中断,那么PlaneInlong将会接受 results.

 脉动  no ints
Frequency: 1012.15
Frequency: 1012.15
Frequency: 1013.17
Frequency: 1013.17
Frequency: 1012.15

 脉动  Ints
Frequency: 1037.34
Frequency: 1040.58
Frequency: 1028.81
Frequency: 1037.34
Frequency: 1030.93

脉冲龙
Frequency: 1015.23
Frequency: 1014.20
Frequency: 1018.33
Frequency: 1016.26
Frequency: 1016.26


新的! Comments

让你说到你刚刚阅读的东西!留下下面的框中的评论。




隐私政策 | 接触 | 关于我

网站地图 | 使用条款


 ezoic. 报告此广告

访问我们的Facebook页面:

   点击这里



最近的文章

  1. 如何使用ADS1115

    使用ADS1115精度16位ADC进行教程进行低功耗。

    阅读更多

  2. arduino. 模拟输出...易模拟输出生成

    arduino. 模拟输出:如何创建最精确的PWM模拟输出以及如何创建模拟PWM正弦波。

    阅读更多

  3. 数号和等效的快速宏。加快代码!

    了解DigitalWrite()的工作原理......现在使用17倍宏宏!

    阅读更多

  4. TCS230颜色传感芯片:如何运作以及如何使用它。

    如何使用TCS230(/ TCS3200)彩色检测器芯片并轻松将其添加到您的任何项目中。

    阅读更多

  5. 如何使用ADXL345进行运动感测等。

    使用ADXL345 Acellerometer,您可以检测到16G!您还可以了解如何使用它来点击检测等。

    阅读更多

  6. HMC5883L 3轴数字MAGENTOMTER如何运作

    HMC5883L - 如何制作数字罗盘,了解HMC5883L和QMC5883L之间的差异以及它们是否兼容。

    阅读更多



读者 Comments

"I wanted to thank
你这么好
对于所有信息
你已经提供了
你的网站's

高超 极好的 ."

- 逃亡Potthath.

"This site really is
最好的和我最喜欢的。
我发现这里有很多很有用
项目和提示。"

- 米兰

Bursach.<at>gmail.com<

"Awesome site,
非常,非常容易和好
导航!"


-
Matt_tr. <at>
wolf359.cjb.net.


学习微控制器

"Interested in
微控制器?"

注册
免费7天指南:

自由 GUIDE : CLICK HERE


"I am a newbie to PIC
我想说
 how great your
网站一直在为我。"


- 戴夫

de_scott.<at>bellsouth.net

"Your site is a great
和完美的工作。
恭喜。"


- SURESH.

IntegratedInfosys.<at>
Yahoo.com.

"I couldn't find the correct
要定义的词语
你的网页。

非常有用,揭开,
诚实明确。

非常感谢
你的时间和作品。
问候。 "


- Anon.

回到顶部