Kesintili darbeleri sayma


10

Bir çıkışı tetiklemek için 12,500 Hz kare dalgadan gelen darbeleri saymaya çalışıyorum. İşte şimdiye kadar sahip olduğum kod. Arduino sıfırlandığında, 25 msn'lik bir örnek üzerinden 315'e seriye yazdırır. 315 x 40 = 12600. Bana öyle geliyor ki mükemmel çalışıyor.

Tek sorunum, kartın sıfırlanmasından sonra bu sayıyı yalnızca bir kez döndürmesidir. Şimdi aynı kodu aşağıya void looptaşırsam, art arda bana tutarsız geri dönüşler verir.

Döngü bölümüne ne eklemem gerektiğini anlamıyorum, bu yüzden tekrar tekrar ve doğru bir şekilde giriş piminin kaç geçişini bir süre boyunca elde ettiğimi sayabiliyorum, böylece 12,500'ün varlığına dayanarak çıkışa bir şeyler yapabilirim Hz sinyali ya da değil.

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

Yukarıdaki kodu kullanarak, sıfırlama düğmesine her bastığımda seri penceresinde bir satır alıyorum.

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

Şimdi aynı sonucu almak istiyorum, ama tekrar tekrar. Bu şekilde sinyal düşerse bir çıkışı kapatmak için tetikleyebilirim (DÜŞÜK). Sinyal mevcut olduğunda çıkış yüksek olur.

Girişim eki kesmeyi aşağıya taşımaktı void loop, bu yüzden tekrar ederdi. İşte böyle görünüyor.

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

Aldığım dönüş kendini güncelliyor, ancak her defasında 0'dan başlamak yerine "sayım" önceki sayımdan başlıyor. Böylece daha da büyüyor. 12500 Hz sinyalimi temsil eden sabit bir değer döndürmeye çalışıyorum, böylece sadece ve benim çıkışımı tetikleyecek.

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

"Şimdi aynı kodu boşluk döngüsüne aşağı taşırsam, art arda bana tutarsız dönüşler vererek sayar." tam olarak ne demek?
Ignacio Vazquez-Abrams

Kendimi daha iyi açıklamak için sorumu düzenledim
Brandon Whosville

Yanıtlar:


9

Kesmeyi tekrar 0takmadan önce IRQCount'u tekrar sıfırlamanız gerekir . Aksi takdirde, son durduğu yerden saymaya devam eder.

Aslında kesme bağlı tutmak ve sadece gecikmeden hemen önce değişkeni sıfırlamak. Bu şekilde takma / ayırma ek yükü 25 ms gecikmeye eklenmez.

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

İnt 2 bayt olduğu için, bu iki baytı ayarlamanın / okumanın ortasında bir kesinti meydana gelebilir. Bu, zaman zaman yanlış bir değere neden olabilir. Bunu önlemek için değeri ayarlarken / okurken kesmeyi devre dışı bırakmalısınız

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

Teşekkürler Gerben! Bu kodu kullanarak ara sıra önemsiz dönüş olsun. Bunu kınamanın en kolay yolu ne olurdu? Bir çıkış yapın, ne yapacağınıza karar vermeden önce 3 okuma yapalım. Veya ham sayım yerine bir açıklık üzerinden atımların ortalaması? Heres dönüş örneği, anormalliği her birkaç saniyede bir alıyorum. Sayılan = 439, Sayılan = 438, Sayılan = 430, Sayılan = 48, Sayılan = 318, Sayılan = 438,
Brandon Whosville

1
Daha büyük bir örnek boyutu vermek için gecikmeyi uzattım. Bu bana gürültülü girdi kaynağımdan uygulanabilir bir dönüş sağlıyor. Bu mükemmel çalışıyor gibi görünüyor! Teşekkür ederim!
Brandon Whosville

İçinde clis ve seis bulunan kodu kullandığınızı varsayıyorum . Ardışık iki yanlış değere sahip olmak garip.
Gerben

1
Gerben, Evet kodu cli ve sei ile kullandım. Yani arka arkaya iki yanlış dönüş almak garip mi demek istiyorsun? Geri dönüşler doğru gibi görünüyor, önemsiz geri dönüşler veren kararlı olmayan gelen sinyal. Eğer i üzerinden örnek 100 ms diyelim, devreyi güvenli bir şekilde etkinleştirmek veya öldürmek için örnek başına bolca darbe verir. Yardımın için sağol!
Brandon Whosville

Ama sahip olduğunuz 48 ve 318 her ikisi de yaklaşık 435 ortalamasından daha düşük. Bağlı devreyi bilmiyorum, bu yüzden arduino kodu yerine devre de olabilir. Her neyse, sonuçtan memnun olduğunuz sürece ... Yardımcı olduğumuz için memnunum.
Gerben
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.