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
