Delay() w przerwaniu - jak to zrobić?

Masz problem z Arduino? Tutaj możesz szukać pomocy.
ODPOWIEDZ
Awatar użytkownika
werewek
Młodszy majsterkowicz
Posty: 16
Rejestracja: 1 sie 2012, 19:11

Delay() w przerwaniu - jak to zrobić?

Post autor: werewek » 16 lip 2013, 00:10

Cześć!

Chciałbym, żeby przerwanie wywołane przyciskiem włączyło diodę, pozostawiło ją świecącą przez pewien, określony czas, a następnie wyłączyło.

Szperając w sieci znalazłem to, w jaki sposób wywołać przerwanie za pomocą przycisku. Dioda płynnie zapala się i gaśnie. Niestety, nie jestem w stanie zmusić przerwania do tego, żeby podtrzymało włączoną diodę. Poniżej zamieszczam kod. Czy mogę prosić o pomoc i wskazanie błędu? Może jest na to inny sposób?
Kod pisze: volatile int count0 = 0;

int ledPin = 9;
int jasniej = 1000; //czas fade in
int ciemniej = 1000; //czas fade out
int podtrzymanie = 3000; //czas między fade in i out

void setup() {
  pinMode(2, INPUT); //przycisk
  digitalWrite(2, HIGH);
  attachInterrupt(0, interrupt0, FALLING);
}

void loop() {
  Serial.println(count0);
  delay(300);
}

void interrupt0() {
  for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
  analogWrite(ledPin, fadeValue);
  delay(jasniej);
  }
  
delay(podtrzymanie); //teoretycznie tutaj powinno zatrzymać wykonanie programu
  
  for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
    analogWrite(ledPin, fadeValue);
    delay(ciemniej);
  }
}

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


Awatar użytkownika
djbuh
Majsterkowicz
Posty: 232
Rejestracja: 9 gru 2012, 19:45
Lokalizacja: Bytom
Kontakt:

Re: Delay() w przerwaniu - jak to zrobić?

Post autor: djbuh » 16 lip 2013, 01:06

Zrób coś w stylu pułapki programowej. Ustaw wartość zmiennej:

Kod: Zaznacz cały

int podtrzymanie = 300
i zastosuj w przerwaniu podobną pętlę jak te do rozjaśniania i ściemniania pomiędzy nimi:

Kod: Zaznacz cały

for(int licznik = 0 ; licznik <= 9; licznik +=1) {
  analogWrite(ledPin, fadeValue);
  delay(podtrzymanie); 
  }
Będzie to takie półsztuczne opóźnienie. Linijke z "analogWrite" możesz spróbować wyrzucić, ale najpierw przetestuj z nią.
Awatar użytkownika
werewek
Młodszy majsterkowicz
Posty: 16
Rejestracja: 1 sie 2012, 19:11

Re: Delay() w przerwaniu - jak to zrobić?

Post autor: werewek » 16 lip 2013, 16:37

Dołożyłem jeszcze 2 diody (mają zapalać się kolejno i kolejno gasnąć). Niestety, to rozwiązanie nie działa tak, jak powinno. Przykładowo - podtrzymanie(20000) podtrzymuje świecenie diod przez 5s pomiędzy fade in i fade out. Bliżej niż dalej, ale jednak nie to.

Macie jeszcze jakies pomysły?
Awatar użytkownika
rafalzaq
Majsterkowicz
Posty: 180
Rejestracja: 2 maja 2013, 23:57

Re: Delay() w przerwaniu - jak to zrobić?

Post autor: rafalzaq » 16 lip 2013, 18:21

Generalnie w przerwaniach powinny być jak najkrótsze instrukcje żeby nie blokować za długo głównego programu. Delay właśnie tak blokuje. Popatrz na to http://arduino.cc/en/Tutorial/BlinkWithoutDelay W samym przerwaniu wysyłaj tylko informację, że ma się zacząć rozjaśnianie diody, a reszta niech będzie w głównej pętli. Możesz zrobić albo kilka progów albo napisać jakąś funkcję płynnie obliczającą wartość dla analogWrite. To powinno rozwiązać problem (choć nie wiem dlaczego akurat to tak się zachowuje).
Awatar użytkownika
Marhef
Złota rączka
Posty: 1260
Rejestracja: 18 lis 2011, 02:18

Re: Delay() w przerwaniu - jak to zrobić?

Post autor: Marhef » 16 lip 2013, 21:25

Z opisu funkcji attachInterrupt:
Inside the attached function, delay() won't work and the value returned by millis() will not increment
Po polsku:
Wewnątrz funkcji obsługi przerwania nie działa funkcja delay(), a wartości funkcji millis() nie są inkrementowane
ODPOWIEDZ

Strony partnerskie: