如何测量Arduino中pin2上两个输入之间的时间间隔?

问题描述 投票:0回答:2

我想通过使用计时器中断方法来测量Arduino UNO引脚2上两个输入脉冲之间的时间间隔,并且我已经编写了这段代码,但是它无法正常工作。

此代码仅显示一个实例的时间,因此我无法测量时间间隔。我是Arduino的新手,尝试制作呼吸机。任何建议将不胜感激。谢谢!

//Three timer interrupts
//timer setup for timer0,timer1 and timer2
//this code will enable all three arduino uno timer interrupts
//timer0 will interrupts at 2 KHz
//timer1 will interrupts at 1 Hz
//timer2 will interrupts at 8 KHz

//storage variables
boolean toggle0=0;
boolean toggle1=0;
boolean toggle2=0;

long count0=0;
long count1=0;
long count2=0;
float t=0;
float iT =0;
float fT =0;
float temp=0;
int switchPin = 2;
int switchState = 0;

void setup() {

    cli(); //stop interrupts

    //set timer0 interrupts at 2 KHz
    TCCR0A = 0;//set entire TCCR0A register to 0
    TCCR0B = 0;
    TCNT0 = 0; //initialize counter value to 0

    //set compare match register for 2KHz increments
    OCR0A = 124;//=(16x10^6)/(2000x64)-1(must be <256)
    //turn on CTC mode
    TCCR0A |=(1 << WGM01);
    //set CS01 and CS00  bits for 64 prescaler
    TCCR0B |= (1 << CS01) | (1 << CS00);
    //enable timer compare interrupt
    TIMSK0 |= (1 << OCIE0A);

    //set timer0 interrupts at 1 Hz
    TCCR1A = 0;//set entire TCCR1A register to 0
    TCCR1B = 0;
    TCNT1 = 0; //initialize counter value to 0

    //set compare match register for 1 Hz increments
    OCR1A = 15624;//=(16x10^6)/(1x1024)-1(must be <65536)
    //turn on CTC mode
    TCCR1B |=(1 << WGM12);
    //set CS12 and CS10  bits for 1024 prescaler
    TCCR1B |= (1 << CS12) | (1 << CS10);
    //enable timer compare interrupt
    TIMSK1 |= (1 << OCIE1A);

    //set timer0 interrupts at 8 KHz
    TCCR2A = 0;//set entire TCCR2A register to 0
    TCCR2B = 0;
    TCNT2 = 0; //initialize counter value to 0

    //set compare match register for 2KHz increments
    OCR2A = 249;//=(16x10^6)/(8000x8)-1(must be <256)
    //turn on CTC mode
    TCCR2A |=(1 << WGM21);
    //set CS21  bits for 8 prescaler
    TCCR2B |= (1 << CS21);
    //enable timer compare interrupt
    TIMSK2 |= (1 << OCIE2A);

    sei();//allow interrupts

    pinMode(switchPin,INPUT);
    Serial.begin(9600);
}

ISR(TIMER0_COMPA_vect){

    //timer0 interrupts 2KHz toggles pin 8
    //generate pulse wave of frequency 2KHz/2 = 1KHz
    if(toggle0){
        digitalWrite(8,HIGH);
        toggle0 = 0;
        count0++;
        t = count0/1000;
    }
    else {
        digitalWrite(8,LOW);
        toggle0 = 1;
    }
}

ISR(TIMER1_COMPA_vect){

    //timer1 interrupts 1Hz toggles pin 8
    //generate pulse wave of frequency 1Hz/2 = 0.5Hz
    if(toggle1){
        digitalWrite(13,HIGH);
        toggle1 = 0;
        count1++;

    }
    else {
        digitalWrite(13,LOW);
        toggle1 = 1;
    }
}

ISR(TIMER2_COMPA_vect){

    //timer2 interrupts 8KHz toggles pin 8
    //generate pulse wave of frequency 8KHz/2 = 4KHz
    if(toggle2){
        digitalWrite(9,HIGH);
        toggle2 = 0;
        count2++;

    }
    else {
        digitalWrite(9,LOW);
        toggle2 = 1;
    }
}

void loop() {

    switchState = digitalRead(switchPin);
    if ((switchState == 1) && (temp == 0)) {
        temp = 1;
    }
    if ((switchState == 1) && (temp == 1)) {
        temp = 0;
    }

    if(switchState){
        if(temp == 0) {
            iT = t;
        }
        if(temp == 1) {
            fT = t;
        }
    }

    //Serial.println(t);
    //Serial.print("Count0 :");
    //Serial.println(count0);

    //Serial.print("count1 :");
    //Serial.println(count1);

    //Serial.print("count2 :");
    //Serial.println(count2);

    // Serial.print("Time : ");
    //Serial.println(t);
    //Serial.println(switchState);
    Serial.print("First Ping Time :: ");
    Serial.println(iT);
    Serial.print("Second Ping Time :: ");
    Serial.println(fT);
    //Serial.print("Temp=");
    //Serial.println(temp);
}

并且输出显示:

Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
Second Ping Time :: 0.00
First Ping Time :: 4.00
timer arduino interrupt arduino-uno
2个回答
0
投票

首先,您不应该惹麻烦timer0。 Arduino使用TIMER0进行计时。您不应该对此进行更改(因此,您发现它使millis()无法正常工作)。您可以使用TIMER1和TIMER2做任何您想做的事情。 (尽管某些库使用它们)。为什么不使用attachInterrupt()?Read here for How to并看到here for example code很抱歉,您没有深入研究您的长代码。


0
投票

我将以更简单的方式解决此问题。始终尝试将问题分成较小的问题(不要过多!)。在这种情况下,我们想要:

  • 当状态改变时开始花费时间。
  • 花时间。
  • 收到其他输入后,请花点时间。

让我们开始:

状态改变时开始花费时间。

如果我们认为引脚的默认状态为LOW,则代码应考虑输入为HIGH,因此这将是我们loop()部分中的第一条语句。读取引脚状态的功能是digitalRead()。您将我们感兴趣的销钉的值提供给它,我们将收到状态HIGHLOW

if (digitalRead(pin) == HIGH){
}

花时间。

现在我们知道何时开始时间,所以现在该考虑我们将如何利用它。我们可以在if语句中编写它,也可以通过创建新函数来编写它,这取决于您要使用的代码的用法。让我们直接在if语句中实现它。我们可以在循环中将1加到变量中,例如:

elapsedTime = 0;
for (int i = 0; i <= 255; i++){
    elapsedTime = elapsedTime + 1;
}

但是我们想在一定时间(一秒钟后)增加一个。我们可以对董事会说嘿!添加一]后等待一秒钟。通过使用功能delay()等待一秒钟即可实现此目标。我们需要指定多少,在这种情况下为1000,因为一秒为1000毫秒。该功能的更多信息,here。现在,我们的代码如下所示:

elapsedTime = 0;
for (int i = 0; i <= 255; i++){
    elapsedTime = elapsedTime + 1;
    delay(1000);
}

一种更常见的添加方法如下:variable++。另一个次要编辑将等待一秒钟,然后再添加一次,因为开始存储的时间是0,否1。让我们重新编写这些行:

elapsedTime = 0;
for (int i = 0; i <= 255; i++){
    delay(1000);
    elapsedTime = elapsedTime++;
}

收到其他输入后,请花点时间。

现在,我们要执行此操作,直到再次回到引脚(HIGH)的激活状态,而不是等待255秒。在这种情况下,我们使用while,这表示类似嘿板子!进行此操作,直到发生]]

while (digitalRead(pin) == LOW){
}

现在,我们在此函数中编写的内容将完成,直到获得错误的语句为止。使用我们之前写的内容:

elapsedTime = 0;
while (digitalRead(pin) == LOW){
    delay(1000);
    elapsedTime = elapsedTime++;
}

最后,我们要在收到第一个HIGH输入时开始计数,因此我们将其包装在第一行代码中:

elapsedTime = 0;
if (digitalRead(pin) == HIGH){
    while (digitalRead(pin) == LOW){
        delay(1000);
        elapsedTime = elapsedTime++;
    }
}

全部完成!要获得结果,您可以打印结果,也可以做任何您想做的事情。您可以测量任何单位,而无需以秒为单位,只需将delay()中的值更改为所需的任何单位即可。例如,如果要测量毫秒,则为delay(1)

© www.soinside.com 2019 - 2024. All rights reserved.