Jedna z nazw używanych w elektronice, które bardzo dobrze określają to co istotnie robią, jest przerwanie (ang. interrupts).
W większości przypadków chodzi o to, by móc kontrolować stan pinu, gdy procesor wykonuje główną pętlę programu. Wykonywana zostaje funkcja, którą wskazujemy w przerwaniu, po czym procesor kontynuuje działania funkcji loop().
Obsługa przerwań w arduino i w ATmega328 (Arduino UNO, nano) jest prosta. Procesor ten obsługuje przerwania na wejściach D2 i D3.
Aby się nie pomylić przydatne jest polecenie digitalPinToInterrupt().
Poniżej program, który zwraca numer przerwania na podanym pinie. W przypadku naszego procesora to 0 i 1.
/* * Demonstracja funkcji digitalPinToInterrupt(), * zwracającej w wartości numer przerwania * na podanym w argumencie pinie. * Jeśli pin nie obsługuje przerwań, zwracana jest wartość -1. * www.yarogniew.net/arduino */ void setup() { Serial.begin(9600); Serial.print("Przerwanie na pinie 2 ma numer "); Serial.println(digitalPinToInterrupt(2)); Serial.print("Przerwanie na pinie 3 ma numer "); Serial.println(digitalPinToInterrupt(3)); Serial.print("Przerwanie na pinie 4 ma numer "); Serial.println(digitalPinToInterrupt(4)); } void loop() { }
Dzięki przerwaniu możemy na przykład w czasie grania melodii zaświecić diodę. Gdybyśmy wstawili sprawdzanie stanu pinu włącznika do pętli głównej, program robiłby to ze zwłoką albo w ogóle. Użycie przerwania umożliwia prawie bezkonfliktowe wykonanie obu funkcji. Zwłaszcza że sprawdzenie stanu i zaświecenie diody trwa krótko.
Funkcja wygląda tak:
attachInterrupt(0,buttonPressed,RISING);
POŁĄCZENIE:
KOD:
/*Program świetnie pokazujący działanie przerwań w Arduino W czasie odtwarzania melodii możemy swobodnie włączać i wyłączać diodę led*/ volatile boolean ledOn = false; #include "pitches.h" void setup() { pinMode(13,OUTPUT); pinMode(2,INPUT); attachInterrupt(0,buttonPressed,RISING); } void loop() { playHoney(); } void buttonPressed() { if(ledOn) { ledOn = false; digitalWrite(13,LOW); }else { ledOn = true; digitalWrite(13,HIGH); } } void playHoney(){ //Honeysuckle rose, standard int melody[] = { NOTE_C5, NOTE_AS4, NOTE_D4, NOTE_F4, NOTE_A4, NOTE_C5, NOTE_AS4, NOTE_D4, NOTE_F4, NOTE_A4, NOTE_C5, NOTE_AS4, NOTE_D4, NOTE_F4, NOTE_A4, NOTE_A4, NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_F4, NOTE_F4, NOTE_F4, NOTE_A4, NOTE_G4, NOTE_F4, NOTE_D4, NOTE_F4, 0 }; int noteDurations[] = { 2, 1, 2, 1, 6, 2, 1, 2, 1, 6, 2, 1, 2, 1, 3, 3, 6, 2, 1, 2, 1, 3, 3, 12, 2, 1, 2, 1, 12, 12 }; for (int thisNote = 0; thisNote < sizeof(melody)/sizeof(int); thisNote++) { int noteDuration = 100 * noteDurations[thisNote]; tone(8, melody[thisNote], noteDuration); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); noTone(8); } }
Program potrzebuje biblioteki pitches.h. Jak ją założyć pisałem tu.
LINKS:
https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
http://akademia.nettigo.pl/arduino_przerwania/
https://forbot.pl/blog/kurs-arduino-ii-przerwania-kontaktron-czujnik-pir-id16792
Arduino Interrupts Tutorial, educ8s.tv