如何测量Arduino中pin2上两个输入之间的时间间隔?
How to measure the time interval between two inputs on pin2 in Arduino?
我想用定时器中断的方法来测量Arduino UNO的2号脚上两个输入脉冲之间的时间间隔,我已经写了这段代码,但它不能正常工作。
此代码仅显示一个瞬间的时间,因此我无法测量时间 interval.I 我是 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
首先你不应该乱用timer0。 Arduino 使用 TIMER0 进行计时。你不应该改变它(所以当你发现它停止 millis() 工作时)。你可以用 TIMER1 和 TIMER2 做任何你想做的事。 (尽管有些图书馆使用它们)。
为什么不使用 attachInterrupt()?
Read here for How to and see here for example code 很抱歉没有深入挖掘您的长代码。
我会以更简单的方式解决这个问题。始终尝试将问题分成较小的问题(不要太多!)。在这种情况下,我们想要:
- 状态变化时开始计时。
- 抓紧时间。
- 当我们收到另一个输入时停止占用时间。
让我们开始吧:
状态变化时开始计时。
如果我们考虑引脚的默认状态是 LOW
,代码应该考虑输入是 HIGH
,所以这将是我们 loop()
中的第一条语句部分。读取引脚状态的函数是digitalRead()
。您将我们有兴趣了解其价值的 pin 赋值,我们将收到状态 HIGH
或 LOW
.
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++;
}
当我们收到另一个输入时停止占用时间。
现在,我们不想等到 255 秒,而是要执行此操作,直到我们再次进入引脚 (HIGH) 的 激活状态 。我们在这种情况下使用 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)
.
我想用定时器中断的方法来测量Arduino UNO的2号脚上两个输入脉冲之间的时间间隔,我已经写了这段代码,但它不能正常工作。
此代码仅显示一个瞬间的时间,因此我无法测量时间 interval.I 我是 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
首先你不应该乱用timer0。 Arduino 使用 TIMER0 进行计时。你不应该改变它(所以当你发现它停止 millis() 工作时)。你可以用 TIMER1 和 TIMER2 做任何你想做的事。 (尽管有些图书馆使用它们)。
为什么不使用 attachInterrupt()?
Read here for How to and see here for example code 很抱歉没有深入挖掘您的长代码。
我会以更简单的方式解决这个问题。始终尝试将问题分成较小的问题(不要太多!)。在这种情况下,我们想要:
- 状态变化时开始计时。
- 抓紧时间。
- 当我们收到另一个输入时停止占用时间。
让我们开始吧:
状态变化时开始计时。
如果我们考虑引脚的默认状态是 LOW
,代码应该考虑输入是 HIGH
,所以这将是我们 loop()
中的第一条语句部分。读取引脚状态的函数是digitalRead()
。您将我们有兴趣了解其价值的 pin 赋值,我们将收到状态 HIGH
或 LOW
.
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++;
}
当我们收到另一个输入时停止占用时间。
现在,我们不想等到 255 秒,而是要执行此操作,直到我们再次进入引脚 (HIGH) 的 激活状态 。我们在这种情况下使用 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)
.