Menghitung pulsa dengan interupsi


10

Saya telah mencoba menghitung pulsa dari gelombang persegi 12.500 Hz untuk memicu output. Inilah kode yang saya miliki sejauh ini. Ketika Arduino di-reset, ia mencetak 315 ke serial di atas sampel 25 ms. 315 x 40 = 12600. Yang menurut saya itu berfungsi dengan baik.

Satu-satunya masalah saya adalah hanya mengembalikan nomor ini sekali setelah mengatur ulang papan. Sekarang jika saya memindahkan kode yang sama ke dalam void loop, itu dihitung secara berturut-turut memberi saya pengembalian tidak konstan.

Saya tidak mengerti apa yang harus saya letakkan di bagian loop sehingga saya bisa berulang kali dan akurat menghitung berapa banyak toggle dari pin input yang saya dapatkan selama periode waktu sehingga saya dapat melakukan sesuatu untuk output berdasarkan dari kehadiran 12.500 Sinyal hz atau tidak.

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

Menggunakan kode di atas, setiap kali saya menekan tombol reset saya mendapatkan satu baris di jendela serial.

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

Sekarang saya ingin mendapatkan hasil yang sama, tetapi berulang-ulang. Dengan begitu jika sinyal turun saya dapat memicu output untuk mematikan (RENDAH). Ketika sinyal hadir, output akan tinggi.

Upaya saya adalah memindahkan interupsi lampiran ke bawah void loop, jadi itu akan berulang. Begini tampilannya.

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

Pengembalian yang saya dapatkan adalah memperbarui sendiri, tetapi "menghitung" bukannya mulai dari 0 setiap kali dimulai dari penghitungan sebelumnya. Jadi semakin besar dan besar. Saya mencari untuk mengembalikan nilai konstan yang mewakili sinyal 12500 Hz saya sehingga, dan hanya itu, akan memicu output saya.

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

"Sekarang jika saya memindahkan kode yang sama itu ke dalam void loop, itu dianggap terus-menerus memberi saya pengembalian tidak konstan." artinya apa sebenarnya?
Ignacio Vazquez-Abrams

Saya mengedit pertanyaan saya untuk mencoba dan menjelaskan diri saya dengan lebih baik
Brandon Whosville

Jawaban:


9

Anda harus mengatur ulang IRQCount kembali 0sebelum memasang interupsi lagi. Kalau tidak, itu hanya akan terus menghitung dari tempat itu berhenti terakhir kali.

Saya akan benar-benar menjaga interrupt terpasang dan hanya mereset variabel sebelum penundaan. Dengan cara itu overhead attach / detachinterrupt tidak ditambahkan ke penundaan 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);
}

Karena int adalah 2 byte, interupsi mungkin terjadi di tengah pengaturan / pembacaan dua byte tersebut. Ini mungkin menghasilkan nilai yang salah sesekali. Untuk mencegahnya, Anda harus menonaktifkan interupsi saat mengatur / membaca nilai

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

Terima kasih Gerben! Dengan menggunakan kode itu saya mendapatkan pengembalian sampah sesekali. Apa cara termudah untuk mengecam ini? Lakukan take out, katakanlah 3 bacaan sebelum membuat keputusan tentang apa yang harus dilakukan. Atau rata-rata pulsa selama rentang bukannya hitungan mentah? Inilah contoh kembalinya, saya mendapatkan anomali setiap beberapa detik. Dihitung = 439, Dihitung = 438, Dihitung = 430, Dihitung = 48, Dihitung = 318, Dihitung = 438,
Brandon Whosville

1
Saya memperpanjang penundaan untuk memberikan ukuran sampel yang lebih besar. Ini memberi saya pengembalian yang bisa diterapkan dari sumber input berisik saya. Ini sepertinya bekerja dengan sempurna! Terima kasih!
Brandon Whosville

Saya berasumsi Anda menggunakan kode dengan clis dan seis di dalamnya. Agak aneh memiliki dua nilai yang salah berturut-turut.
Gerben

1
Gerben, Ya saya menggunakan kode dengan cli dan sei di dalamnya. Apakah yang Anda maksud adalah mendapatkan dua pengembalian yang salah secara berurutan? Tampaknya pengembalian sudah benar, itu adalah sinyal masuk yang tidak stabil memberikan pengembalian sampah. Jika saya sampel lebih dari katakanlah 100ms itu memberikan banyak pulsa per sampel untuk mengaktifkan atau membunuh rangkaian dengan aman. Saya sangat menghargai bantuan Anda!
Brandon Whosville

Tapi 48 dan 318 yang Anda dapatkan sama-sama lebih rendah dari rata-rata sekitar 435. Saya tidak tahu sirkuit yang terhubung, jadi itu bisa saja sirkuit, bukan kode arduino. Bagaimanapun, selama Anda senang dengan hasil akhirnya ... Senang telah membantu.
Gerben
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.