Đếm xung với ngắt


10

Tôi đã cố gắng đếm các xung từ sóng vuông 12.500 Hz để kích hoạt đầu ra. Đây là mã tôi có cho đến nay. Khi Arduino được thiết lập lại, nó sẽ in 315 thành nối tiếp trong mẫu 25 ms. 315 x 40 = 12600. Dường như với tôi nó hoạt động hoàn hảo.

Vấn đề duy nhất của tôi là nó chỉ trả về số này một lần khi thiết lập lại bảng. Bây giờ nếu tôi chuyển cùng mã đó xuống void loop, nó sẽ liên tục trả lại cho tôi tiền lãi.

Tôi không hiểu những gì tôi cần đặt trong phần vòng lặp để tôi có thể đếm liên tục và chính xác có bao nhiêu nút bật của pin đầu vào mà tôi nhận được trong một khoảng thời gian để tôi có thể làm gì đó với đầu ra dựa trên sự hiện diện của 12.500 Tín hiệu Hz hay không.

volatile int IRQcount;
int pin = 2;
int pin_irq = 0; //IRQ that matches to pin 2

void setup() {
   // Put your setup code here, to run once:
  Serial.begin (9600);
  attachInterrupt(pin_irq, IRQcounter, RISING);
  delay(25);
  detachInterrupt(pin);
  Serial.print(F("Counted = "));
  Serial.println(IRQcount);
}

void IRQcounter() {
  IRQcount++;
}

void loop() {
  // Put your main code here, to run repeatedly:
}

Sử dụng mã trên, mỗi lần tôi nhấn nút đặt lại, tôi nhận được một dòng trong cửa sổ nối tiếp.

Counted = 441
Counted = 442
Counted = 441
Counted = 441
Counted = 441

Bây giờ tôi muốn nhận được kết quả tương tự, nhưng lặp đi lặp lại nhiều lần. Bằng cách đó, nếu tín hiệu rơi ra tôi có thể kích hoạt đầu ra để tắt (THẤP). Khi tín hiệu có mặt, đầu ra sẽ tăng cao.

Nỗ lực của tôi là chuyển phần đính kèm xuống void loop, vì vậy nó sẽ lặp lại. Đây là những gì nó trông giống như.

volatile int IRQcount;
int pin = 2;
int pin_irq = 0; //IRQ that matches to pin 2

void setup() {
  // Put your setup code here, to run once:
  Serial.begin (9600);
}

void IRQcounter() {
   IRQcount++;
}

void loop() {
  // Put your main code here, to run repeatedly:

  attachInterrupt(pin_irq, IRQcounter, RISING);
  delay(25);
  detachInterrupt(pin);
  Serial.print(F("Counted = "));
  Serial.println(IRQcount);
}

Tiền lãi tôi nhận được là tự cập nhật, nhưng "số đếm" thay vì bắt đầu từ 0 mỗi lần bắt đầu từ số trước đó. Vì vậy, nó ngày càng lớn hơn. Tôi đang tìm cách trả về một giá trị không đổi đại diện cho tín hiệu 12500 Hz của tôi để chỉ và điều đó sẽ kích hoạt đầu ra của tôi.

Counted = 442
Counted = 886
Counted = 1330
Counted = 177
Counted = 2221
Counted = 2667
Counted = 3112
Counted = 3557
Counted = 4002
Counted = 4448
Counted = 4893
Counted = 5338
Counted = 5784
Counted = 6229
Counted = 6674
Counted = 7120
Counted = 7565
Counted = 8010
Counted = 8456
Counted = 8901
Counted = 9347
Counted = 9792
Counted = 10237
Counted = 10683
Counted = 11130
Counted = 11576
Counted = 12022
Counted = 12469
Counted = 12915
Counted = 13361
Counted = 13808
Counted = 14254
Counted = 14700
Counted = 15147
Counted = 15593
Counted = 16040
Counted = 16486
Counted = 16932
Counted = 17378
Counted = 17825
Counted = 18271
Counted = 18717
Counted = 19164
Counted = 19610
Counted = 20056
Counted = 20503
Counted = 20949
Counted = 21395
Counted = 21842
Counted = 22288
Counted = 22735
Counted = 23169
Counted = 23616
Counted = 24062
Counted = 24508
Counted = 24955
Counted = 25401
Counted = 25730
Counted = 25756
Counted = 26200
Counted = 26646
Counted = 27093
Counted = 27539
Counted = 27985
Counted = 28432
Counted = 28878
Counted = 29324
Counted = 29770
Counted = 30217
Counted = 30663
Counted = 31110
Counted = 31556
Counted = 32002
Counted = 32449
Counted = -32641
Counted = -32195
Counted = -31748
Counted = -31302
Counted = -30855
Counted = -30408
Counted = -29962
Counted = -29515
Counted = -29069
Counted = -28622

"Bây giờ nếu tôi chuyển cùng một mã xuống vòng lặp void thì nó sẽ liên tục mang lại cho tôi lợi nhuận bất thường." nghĩa là gì?
Ignacio Vazquez-Abrams

Tôi đã chỉnh sửa câu hỏi của mình để cố gắng và giải thích rõ hơn về bản thân
Brandon Whosville

Câu trả lời:


9

Bạn cần đặt lại IRQCount trở lại 0trước khi gắn lại ngắt. Nếu không, nó sẽ tiếp tục đếm từ nơi nó dừng lại lần trước.

Tôi thực sự sẽ giữ ngắt được đính kèm và chỉ cần đặt lại biến ngay trước khi trì hoãn. Bằng cách đó, chi phí đính kèm / phá hủy không được thêm vào độ trễ 25ms.

volatile int IRQcount;
int pin = 2;
int pin_irq = 0; //IRQ that matches to pin 2

void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
  attachInterrupt(pin_irq, IRQcounter, RISING);
}

void IRQcounter() {
  IRQcount++;
}

void loop() {
  // put your main code here, to run repeatedly:
  IRQcount = 0;
  delay(25);
  int result = IRQcount;
  Serial.print(F("Counted = "));
  Serial.println(result);
}

Vì một int là 2 byte, một ngắt có thể xảy ra ở giữa cài đặt / đọc hai byte đó. Điều này có thể dẫn đến một giá trị không thường xuyên. Để ngăn chặn điều đó, bạn nên tắt ngắt trong khi cài đặt / đọc giá trị

volatile int IRQcount;
int pin = 2;
int pin_irq = 0; //IRQ that matches to pin 2

void setup() {
  // put your setup code here, to run once:
  Serial.begin (9600);
  attachInterrupt(pin_irq, IRQcounter, RISING);
}

void IRQcounter() {
  IRQcount++;
}

void loop() {
  // put your main code here, to run repeatedly:

  cli();//disable interrupts
  IRQcount = 0;
  sei();//enable interrupts

  delay(25);

  cli();//disable interrupts
  int result = IRQcount;
  sei();//enable interrupts

  Serial.print(F("Counted = "));
  Serial.println(result);
}

Cảm ơn Gerben! Sử dụng mã đó tôi nhận được trả lại rác thường xuyên. Điều gì sẽ là cách dễ nhất để tố cáo điều này? Thực hiện đưa ra cho phép nói 3 bài đọc trước khi đưa ra quyết định phải làm gì. Hoặc trung bình các xung trên một nhịp thay vì số liệu thô? Đây là một ví dụ về sự trở lại, cứ sau vài giây tôi lại thấy sự bất thường. Đã đếm = 439, Đã đếm = 438, Đã đếm = 430, Đã đếm = 48, Đã đếm = 318,
Đã đếm

1
Tôi kéo dài độ trễ để cho cỡ mẫu lớn hơn. Điều này mang lại cho tôi một sự trở lại hoàn toàn khả thi từ nguồn đầu vào ồn ào của tôi. Điều này dường như làm việc hoàn hảo! Cảm ơn bạn!
Brandon Whosville

Tôi giả sử bạn đã sử dụng mã với clis và seis trong đó. Khá lạ khi có hai giá trị sai liên tiếp.
Gerben

1
Gerben, vâng tôi đã sử dụng mã với cli và sei trong đó. Bạn có nghĩa là kỳ lạ của nó nhận được hai trả lại sai liên tiếp? Có vẻ như trả về là chính xác, đó là tín hiệu đến không ổn định cho trả lại rác. Nếu tôi lấy mẫu hơn 100ms, nó sẽ cung cấp nhiều xung cho mỗi mẫu để kích hoạt hoặc giết mạch một cách an toàn. Tôi thực sự đánh giá cao sự giúp đỡ của bạn!
Brandon Whosville

Nhưng 48 và 318 bạn nhận được đều thấp hơn mức trung bình khoảng 435. Tôi không biết mạch được kết nối, vì vậy nó cũng có thể là mạch, thay vì mã arduino. Dù sao, miễn là bạn hài lòng với kết quả cuối cùng ... Rất vui vì đã giúp đỡ.
Gerben
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.