3

我正在尝试以时间量子计算HB100 微波传感器脉冲的数量。200ms

这是代码:

#include <SoftwareSerial.h>
#include <elapsedMillis.h>
elapsedMillis ElapsedTime;

#define Sensor A0
#define TimeQuanta 200

int Counter = 0;
boolean LastState;

void setup()
{
  Serial.begin(250000);
  pinMode(Sensor, INPUT);  
}

void loop()
{
  Counter = 0;
  ElapsedTime = 0;
  while (ElapsedTime < TimeQuanta ){
    LastState = digitalRead(Sensor);
    if (LastState == LOW && digitalRead(Sensor) == HIGH ){
      Counter += 1;  //Compare Last state with current state 
    }
  }
  Serial.print(digitalRead(Sensor));
  Serial.print("\t");
  Serial.println(Counter);
}

我需要知道数字读取周期。我正在将传感器的最后状态与当前状态进行比较,如果进行了更改(从低到高),则计数器会增加。但是,我的柜台总是0

  • 代码是否正确(if条件)?
  • 我需要一些延迟吗?
  • 可以计算这些脉冲吗?

这是微波传感器的逻辑分析仪输出:

在此处输入图像描述


编辑:如果我delay(1);之前添加,if那么计数器不再是 0。

4

3 回答 3

3

由于这些脉冲似乎比微秒短,您不能使用digitalRead需要大约 80 个机器周期(大约 5us @16MHz)的功能。

更不用说在每次循环迭代中打印这么多数据了!!!!

所以你的频率超过了1MHz,你的代码可能可以计算10kHz(充其量,也许更少)

无论如何,您应该在输入端使用Timer/Counter 1带有时钟源的硬件。T1这个能够以主时钟频率的一半(50%脉冲宽度)计算脉冲

使用Timer/Counter 1非常简单:

TCCR1A = 0; // default mode, no output compare modes
TCCR1B = _BV(CS10) | _BV(CS11) | _BV(CS12); // clock select mode 7 - External clock source on T1 pin. Clock on rising edge.

每 200 毫秒读取一次 TCNT1并最终重置为 0,或者只记住最后一个值并有所作为(不要忘记它只是 16b 数字)。

于 2017-02-06T08:14:30.550 回答
3

您可以使用 timer1 来计算经过的时间。

// Set Timer1 without prescaler at CPU frequency
TCCR1A = 0; // TCCRx - Timer/Counter Control Register. The pre-scaler can be configured here. 
TCCR1B = 1;

noInterrupts ();  // Disable interrupts.

uint16_t  StartTime = TCNT1;  // TCNTx - Timer/Counter Register. The actual timer value is stored here.
digitalRead(pin); // your code.
uint16_t EndTime = TCNT1
uint16_t ElapsedTime = EndTime - StartTime;

interrupts (); //Enable interrupts.

作为第二种解决方案,您可以设置和取消设置引脚并使用逻辑分析仪计算时间。

DDRD = DDRD | B10000000; // Set digital pin 7 as output.
PORTD = PORTD | B10000000; // Set digital pin 7.
digitalRead(pin); // your code.
PORTD = PORTD & B01111111; // Unset digital pin 7.
于 2017-11-06T14:16:53.983 回答
2

KIIV 很好地解释了为什么您的代码不起作用,在这里我想提出一种实现相同目标的替代方法。


代码:

const byte interruptPin = 2;
volatile unsigned long counter = 0;                // overflow after 2^32-1 pulses

void setup() {
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), count, RISING);
  Serial.begin(19200);
}

void loop() {
  Serial.print("No. pulses: ");
  Serial.println(counter);
  delay(1000);
}

void count() {
  counter++;                                       // never use print() in an ISR!
}

请注意,我更改了输入引脚,因为可用于此技术的引脚有一些限制,具体取决于您使用的电路板:

Board                                Digital Pins Usable For Interrupts
Uno, Nano, Mini, other               2, 3
Mega, Mega2560, MegaADK              2, 3, 18, 19, 20, 21
Micro, Leonardo, other 32u4-based    0, 1, 2, 3, 7
Zero                                 all digital pins, except 4
MKR1000 Rev.1                        0, 1, 4, 5, 6, 7, 8, 9, A1, A2
Due, 101                             all digital pins
于 2017-02-06T08:32:46.143 回答