Zliczanie impulsów z przerwaniem


10

Próbowałem policzyć impulsy z fali prostokątnej 12 500 Hz, aby wyzwolić wyjście. Oto kod, który mam do tej pory. Po zresetowaniu Arduino drukuje 315 do portu szeregowego na próbce 25 ms. 315 x 40 = 12600. Wydaje mi się, że działa idealnie.

Moim jedynym problemem jest to, że zwraca ten numer tylko raz po zresetowaniu płyty. Teraz, gdy przeniosę ten sam kod w dół void loop, liczy się on kolejno, dając mi niestałe zwroty.

Nie rozumiem, co muszę umieścić w sekcji pętli, dzięki czemu mogę wielokrotnie i dokładnie policzyć, ile przełączników pinów wejściowych otrzymuję przez pewien czas, dzięki czemu mogę zrobić coś z wyjściem na podstawie obecności 12,500 Sygnał Hz czy nie.

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

Korzystając z powyższego kodu, za każdym razem, gdy naciskam przycisk resetowania, pojawia się jedna linia w oknie szeregowym.

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

Teraz chcę uzyskać ten sam wynik, ale powtarzam w kółko. W ten sposób, jeśli zaniknie sygnał, mogę wyzwolić wyjście (LOW). Gdy sygnał jest obecny, wyjście będzie wysokie.

Moja próba polegała na przeniesieniu przerwania dołączania w dół void loop, aby się powtórzyło. Oto jak to wygląda.

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

Zwracam się samo aktualizuje, ale „liczenie” zamiast zaczynać od 0 za każdym razem zaczyna się od poprzedniego liczenia. Więc staje się coraz większy. Chcę zwrócić stałą wartość, która reprezentuje mój sygnał 12500 Hz, aby tylko to mogło wyzwolić mój sygnał wyjściowy.

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

„Teraz, jeśli przesunę ten sam kod w dół w pustą pętlę, liczy się to kolejno, dając mi niestałe zwroty.” co dokładnie znaczy
Ignacio Vazquez-Abrams

Zredagowałem swoje pytanie, aby spróbować lepiej się wyjaśnić
Brandon Whosville,

Odpowiedzi:


9

Musisz ponownie zresetować IRQCount 0przed ponownym dołączeniem przerwania. W przeciwnym razie będzie po prostu kontynuował liczenie od miejsca, w którym zatrzymał się ostatnim razem.

Naprawdę trzymałbym przerwanie i po prostu resetuję zmienną tuż przed opóźnieniem. W ten sposób narzut związany z załączaniem / odłączaniem nie jest dodawany do opóźnienia 25 ms.

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

Ponieważ int wynosi 2 bajty, przerwanie może wystąpić w trakcie ustawiania / odczytu tych dwóch bajtów. Może to powodować sporadyczne błędne wartości. Aby temu zapobiec, należy wyłączyć przerwanie podczas ustawiania / odczytu wartości

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

Dzięki Gerben! Korzystając z tego kodu, od czasu do czasu otrzymuję śmieci. Jaki byłby najłatwiejszy sposób na to? Wykonaj zdjęcie, powiedzmy 3 odczyty, zanim podejmiesz decyzję, co robić. A może uśrednianie impulsów na rozpiętości zamiast surowej liczby? Oto przykład powrotu, co kilka sekund dostaję anomalię. Policzony = 439, Policzony = 438, Policzony = 430, Policzony = 48, Policzony = 318, Policzony = 438,
Brandon Whosville

1
Wydłużyłem opóźnienie, aby uzyskać większy rozmiar próbki. To daje mi realny zwrot z mojego głośnego źródła wejściowego. To wydaje się działać idealnie! Dziękuję Ci!
Brandon Whosville,

Zakładam, że użyłeś kodu z clisiami seis. Raczej dziwne, mając dwie kolejne błędne wartości.
Gerben

1
Gerben, tak, użyłem kodu z cli i sei w nim. Czy masz na myśli, że dziwne jest otrzymywanie dwóch błędnych zwrotów z rzędu? Wygląda na to, że zwroty są prawidłowe, to przychodzący sygnał nie jest stabilny, co daje śmieciowe zwroty. Jeśli próbuję ponad, powiedzmy 100ms, daje to dużo impulsów na próbkę, aby bezpiecznie aktywować lub zabić obwód. Doceniam twoją pomoc!
Brandon Whosville

Ale oba 48 i 318 są niższe niż średnio około 435. Nie znam podłączonego obwodu, więc równie dobrze mógłby to być obwód, zamiast kodu arduino. W każdym razie, dopóki jesteś zadowolony z efektu końcowego ... Cieszę się, że pomogłeś.
Gerben,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.