การนับพัลส์ด้วยการขัดจังหวะ


10

ฉันพยายามนับพัลส์จากคลื่นสี่เหลี่ยม 12,500 Hz เพื่อกระตุ้นการส่งออก นี่คือรหัสที่ฉันมี เมื่อรีเซ็ต Arduino แล้วมันจะพิมพ์ 315 ไปยังซีเรียลในตัวอย่าง 25 มิลลิวินาที 315 x 40 = 12600 ซึ่งดูเหมือนว่าฉันจะทำงานได้อย่างสมบูรณ์

ปัญหาเดียวของฉันคือมันคืนค่าหมายเลขนี้เพียงครั้งเดียวเมื่อรีเซ็ตบอร์ด ตอนนี้ถ้าฉันย้ายรหัสเดียวกันนั้นลงไปvoid loopมันนับได้ว่าให้ผลตอบแทนที่ไม่แน่นอน

ฉันไม่เข้าใจสิ่งที่ฉันต้องใส่ในส่วนวนซ้ำเพื่อให้ฉันสามารถนับซ้ำ ๆ ได้อย่างถูกต้องและนับจำนวนการสลับของขาอินพุตที่ฉันได้รับในช่วงระยะเวลาหนึ่ง สัญญาณเฮิรตซ์หรือไม่

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:
}

ใช้รหัสด้านบนทุกครั้งที่ฉันกดปุ่มรีเซ็ตฉันจะได้รับหนึ่งบรรทัดในหน้าต่างอนุกรม

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

ตอนนี้ฉันต้องการผลลัพธ์ที่เหมือนกัน แต่ซ้ำไปซ้ำมา ด้วยวิธีนี้หากสัญญาณลดลงฉันสามารถกระตุ้นเอาท์พุทให้ปิด (LOW) เมื่อสัญญาณมีการส่งออกจะไปสูง

ความพยายามของฉันคือการย้ายสิ่งที่แนบมาขัดจังหวะลงvoid loopดังนั้นมันจะทำซ้ำ นี่คือสิ่งที่ดูเหมือนว่า

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);
}

ผลตอบแทนที่ฉันได้รับคือการปรับปรุงตนเอง แต่ "นับ" แทนที่จะเริ่มจาก 0 ทุกครั้งเริ่มจากการนับก่อนหน้า ดังนั้นมันจึงใหญ่ขึ้นเรื่อย ๆ ฉันกำลังมองหาที่จะส่งคืนค่าคงที่ที่แสดงถึงสัญญาณของฉัน 12,500 Hz เพื่อที่จะทริกเกอร์เอาท์พุทของฉันเท่านั้น

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

"ตอนนี้ถ้าฉันย้ายรหัสเดียวกันนั้นลงในช่องว่างเป็นโมฆะมันนับอย่างต่อเนื่องทำให้ฉันได้รับผลตอบแทนที่ไม่แน่นอน" หมายความว่าอะไรกันแน่?
Ignacio Vazquez-Abrams

ฉันแก้ไขคำถามของฉันเพื่อพยายามอธิบายตัวเองให้ดีขึ้น
แบรนดอน Whosville

คำตอบ:


9

คุณต้องรีเซ็ต IRQCount กลับไปเป็น0ก่อนที่จะทำการอินเตอร์รัปต์อีกครั้ง มิฉะนั้นจะนับต่อจากที่หยุดครั้งสุดท้าย

จริง ๆ แล้วฉันจะให้ขัดจังหวะที่แนบมาและเพียงแค่ตั้งค่าตัวแปรก่อนที่จะล่าช้า วิธีการที่ค่าใช้จ่ายของการแนบ / detachinterrupt ไม่ได้รับการเพิ่มความล่าช้า 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);
}

เนื่องจาก int คือ 2 ไบต์การขัดจังหวะอาจเกิดขึ้นกลางการตั้งค่า / อ่านสองไบต์ สิ่งนี้อาจส่งผลให้ค่าผิดพลาดเป็นครั้งคราว เพื่อป้องกันไม่ให้คุณควรปิดการใช้งานอินเตอร์รัปต์ขณะตั้งค่า / อ่านค่า

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);
}

ขอบคุณ Gerben! ใช้รหัสที่ฉันได้รับคืนขยะเป็นครั้งคราว อะไรจะเป็นวิธีที่ง่ายที่สุดในการบอกเลิกเรื่องนี้? ตัดสินใจออกให้พูด 3 ครั้งก่อนตัดสินใจว่าจะทำอย่างไร หรือค่าเฉลี่ยพัลส์เกินช่วงแทนที่จะนับดิบ? นี่คือตัวอย่างของการกลับมาฉันได้รับความผิดปกติทุกสองสามวินาที นับ = 439, นับ = 438, นับ = 430, นับ = 48, นับ = 318, นับ = 438,
แบรนดอน Whosville

1
ฉันยืดความล่าช้าออกไปเพื่อให้ขนาดตัวอย่างใหญ่ขึ้น สิ่งนี้ทำให้ฉันกลับมาทำงานได้จากแหล่งอินพุตที่มีเสียงดังของฉัน ดูเหมือนว่าจะทำงานได้สมบูรณ์แบบ! ขอบคุณ!
Brandon Whosville

ฉันถือว่าคุณใช้รหัสกับclis และseis ในนั้น ค่อนข้างแปลกที่มีค่าผิดสองค่าติดต่อกัน
Gerben

1
Gerben ใช่ฉันใช้รหัสกับ cli และ sei ในนั้น คุณหมายความว่ามันแปลกที่จะได้รับผลตอบแทนที่ผิดสองครั้งติดต่อกัน ดูเหมือนว่าการส่งคืนนั้นถูกต้อง แต่เป็นสัญญาณขาเข้าที่ไม่เสถียรเมื่อส่งคืนขยะ หากตัวอย่างมากกว่าให้บอก 100ms มันให้พัลส์จำนวนมากต่อตัวอย่างเพื่อเปิดใช้งานหรือฆ่าวงจรอย่างปลอดภัย ผมขอขอบคุณความช่วยเหลือของคุณ!
Brandon Whosville

แต่ 48 และ 318 ที่คุณได้นั้นต่ำกว่าค่าเฉลี่ยประมาณ 435 ผมไม่ทราบวงจรที่เชื่อมต่อดังนั้นมันอาจเป็นวงจรแทนที่จะเป็นรหัส arduino อย่างไรก็ตามตราบใดที่คุณมีความสุขกับผลลัพธ์ที่ได้ ... ยินดีที่ได้ช่วย
Gerben
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.