Skocz do zawartości

Timer liczący sygnał na digital IN


radeksla

Pomocna odpowiedź

Witam.

Poszukuję timera na MEGA 2560, którym mógłbym mierzyć sumę czasów pracy urządzenia . Sygnał wyprowadziłem na digital IN. Cyklicznie, 25 sekund pracy / przerwa 50 s,  lub ciągle przez kilka minut, lub dodatkowo może być cykl przerwany przez coś tam. Po uzbieraniu 300s ma uruchomić się OUTPUT na kilka s, a licznik w międzyczasie, cały czas licząc ma się wyzerować. Próbowałem różności, ale nie znalazłem opcji zliczania czasu.

Link do komentarza
Share on other sites

Cześć,

dla "Arduino Mega 2560" można użyć biblioteki "TimerThree" do odmierzania czasu. Oto link do niej:

https://www.pjrc.com/teensy/td_libs_TimerOne.html

Nie przejmuj się opisem dotyczącym pinów PWM (ta biblioteka może też automatycznie generować sygnał PWM), ciebie to w tej chwili nie dotyczy.

Tu masz link do pobrania tej biblioteki na Github'ie:

https://github.com/PaulStoffregen/TimerThree

Przydałby się jeszcze jeden "feature" do twojego problemu: mianowicie Arduino MEGA (także UNO) ma kilka pinów, które można wykorzystać jako sygnały zewnętrznych przerwań. Oto link:

https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

Jak widzisz z opisu dla "Arduino Mega 2560" są to piny: 2, 3, 18, 19, 20, 21. Te przerwania są "nie-maskowalne", pinów jest trochę mało, czasami trzeba jeszcze więcej pinów wtedy można użyć przerwań maskowalnych PCINT, ale jest to trochę trudniejsze niż tych pinów z przerwaniami nie-maskowalnymi INT.

Ja rozwiązał bym problem w następujący sposób: do jednego z wejść zewnętrznych przerwań (piny: 2, 3, 18, 19, 20, 21) przypisałbym funkcję obsługi przerwania i ustawiał bym jakąś globalną zmienna, która mówi, że impulsy z timera (co określony czas mają być zliczane). Oczywiście, zmienna pozwalająca na zliczanie impulsów aktywna gdy stan wejścia przerwania zewnętrznego ma właściwy poziom.

Druga kwestia to timer: ustawiasz sobie czas co jaki ma być uruchamiane przerwanie od timera (np. co 100 us lub co 10 ms) i po prostu w procedurze obsługi timera aktualizujesz licznik w celu zliczania czasu. Aby zliczać czas tylko wtedy, gdy poziom na twoim wejściu przerwania zewnętrznego jest np. wysoki w przerwaniu od sygnału zewnętrznego ustawiasz sobie globalną zmienną, która mówi czy impulsy z timera mają być zliczane, czy nie.

Kod programu wyglądałby mniej więcej tak:

#include "TimerThree.h"
#include <avr/interrupt.h>

const int outerInt  = 2;  // INT4 - pin zewnetrznego przerwania

volatile unsigned long licznik;   //licznik impulsow  - czasu

volatile bool zezwalajLiczyc; //zmienna - true zliczaj impulsy , false nie zliczaj

//---------------------- Interrupts and callbacks ------------------------------------

void tim3Callback()
{
  if (zezwalajLiczyc) licznik++;
  if (licznik >= 300000UL) {
     //rób coś tam np. : digitalWrite(Pin, HIGH);
     // licznik=0UL;
  }
}

void outInterrupt() {
  if (digitalRead(outerInt) == LOW) {
     zezwalajLiczyc=true;
  } else {
     zezwalajLiczyc=false;
  }
}

//---------------------- Setup and program ------------------------------------

void setup()
{  
  pinMode(outerInt, INPUT_PULLUP); //zakladamy, ze zliczanie gdy wartosc LOW na pinie przerwania
  
  attachInterrupt(digitalPinToInterrupt(outerInt), outInterrupt,  CHANGE); //procedura obslugi zewnetrznego przerwania

  //Ustawiamy timer
  Timer3.initialize(1000);                 // initialize timer3, and set a 1000 us (1ms)second period
  Timer3.attachInterrupt(tim3Callback);  // przypisz funkcję obslugi Timera
 
  zezwalajLiczyc=false;
  licznik=0UL;
}
 
void loop()
{  
  //delay(10);
}

UWAGA: nie twierdzę, że jest to najlepszy sposób rozwiązania tego problemu. Odpowiadam, ponieważ nie było przez dość długi czas odpowiedzi. jeśli ktoś ma lepsze rozwiązanie, niech po prostu je poda.

Nie mogłem sprawdzić kodu na "Arduino Mega 2560" bo aktualnie takim nie dysponuje, ale według mnie powyższy kod powinien działać.

BTW: oczywiście bibliotekę "TimerThree" trzeba zainstalować w "Arduino IDE", tu link jak to się robi:

https://www.arduino.cc/en/guide/libraries

Pozdrawiam

 

Edytowano przez FlyingDutch
  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dziękuję za pomoc.

Nie odpowiadałem, bo odczytałem odpowiedź bez wklejonego kodu i grzecznie czekałem. Niestety powiadomienia nie dotyczą edycji, którą zrobiłeś do swojego wpisu, a ja odczytałem go z poczty, więc się nie odświeżył.  Ale nie ma tego złego; w międzyczasie odrobiłem lekcje.

Adoptowałem co nieco ze swojego szkicu i uruchomiłem twój kod w całości. Działa, powinno być bardzo dobrze. Jeszcze dopracuję czasy, bo się rozjeżdżają, ale to na spokojnie na gotowo, żeby nie robić dwa razy.

Mam pytanie na początek: - czy w 3 linii chodzi jednak o INT 0 ? choć dla mnie teraz to bez znaczenia, ale zbiło mnie z tropu i czy  Timer3 mogę ustawić też do innych zliczeń, czy tylko raz w programie, a korzystać z innych timerów. Używam Timer.h .

Tyle na szybko, teraz jeszcze doczytam i przetestuję bibliotekę. Jeszcze raz dziękuję za pomoc, jestem pod wrażeniem.

 

  • Lubię! 1
Link do komentarza
Share on other sites

6 godzin temu, radeksla napisał:

Dziękuję za pomoc.

Mam pytanie na początek: - czy w 3 linii chodzi jednak o INT 0 ? choć dla mnie teraz to bez znaczenia, ale zbiło mnie z tropu i czy  Timer3 mogę ustawić też do innych zliczeń, czy tylko raz w programie, a korzystać z innych timerów. Używam Timer.h .

Tyle na szybko, teraz jeszcze doczytam i przetestuję bibliotekę. Jeszcze raz dziękuję za pomoc, jestem pod wrażeniem.

 

Cześć,

z "pinoutu" dla "Arduino Mega 2560 " wynika, że dla pinu 2 jest przyporządkowane INT4 (ale to rzeczywiście nie powinno mieć dla Ciebie znaczenia). Możesz wykorzystać procedurę "tim3Callback" podpiętą do tej instancji timera także do innych obliczeń - trzeba tylko zmodyfikować kod. Teoretycznie możesz sobie zdefiniować kilka instancji timerów (nawet z innymi okresami), ale ich użycie musi być dobrze przemyślane w programie, bo możesz narobić sobie kłopotów i program nie będzie działał poprawnie (trzeba pamiętać, że to są przerwania).

Pozdrawiam

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Zapakowałem całość do szkicu i rozjechały się czasy: licznik z przerwania  i timer wyjścia obsługiwanego przerwaniem . Na dodatek wychodziły z nich za każdym razem inne czasy, a nieraz wyjście się nie aktywowało. O ile licznik mógł coś nie odzwierciedlać, timer dał mi do myślenia. Zastąpiłem w tim3Callback digitalWrite zmienną volatile bool i wyprowadziłem if poza funkcję przerwania. Szkic chodzi bezbłędnie, TimerThree reaguje na wszystkie przeszkadzajki i zlicza impulsy z INPUT kiedy trzeba, bez przerwy sterując wyjściem.

Wielkie dzięki.

  • Lubię! 1
Link do komentarza
Share on other sites

Dnia 11.02.2019 o 12:26, radeksla napisał:

Zapakowałem całość do szkicu i rozjechały się czasy: licznik z przerwania  i timer wyjścia obsługiwanego przerwaniem . Na dodatek wychodziły z nich za każdym razem inne czasy, a nieraz wyjście się nie aktywowało. O ile licznik mógł coś nie odzwierciedlać, timer dał mi do myślenia. Zastąpiłem w tim3Callback digitalWrite zmienną volatile bool i wyprowadziłem if poza funkcję przerwania. Szkic chodzi bezbłędnie, TimerThree reaguje na wszystkie przeszkadzajki i zlicza impulsy z INPUT kiedy trzeba, bez przerwy sterując wyjściem.

Wielkie dzięki.

Cześć,

tak było ponieważ funkcja digitalWrite "pod spodem" korzysta z przerwań - sorki zapomniałem o tym (powinienem Ci o tym napisać).

Gratuluję doprowadzenia programu do prawidłowego działania 😉

Pozdrawiam

  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.