Читаем Изучаем Arduino: инструменты и методы технического волшебства полностью

Важно понимать, что с помощью Arduino нельзя реализовать "истинную" многозадачность. Прерывания создают лишь видимость одновременного выполнения нескольких операций, позволяя переключаться между несколькими задачами чрезвычайно быстро. Использование библиотеки TimerOne позволит заставить мигать светодиод по таймеру, пока в цикле loop() выполняются другие задачи. В конце главы мы опишем проект, где в основном цикле loop() данные выводятся в последовательный порт с задержкой delay(), а по прерываниям таймера осуществляется управление светодиодом и пьезозуммером. Чтобы убедиться, что библиотека работает правильно, можно загрузить программу, приведенную в листинге 12.2, на плату Arduino Uno. Светодиод, подключенный к контакту 13 платы Arduino, будет мигать раз в секунду и управляться с помощью таймера. Если вставить какой-либо фрагмент кода в цикл loop(), то он будет выполняться одновременно.

// Использование прерывания по таймеру

Листинг 12.2. Прерывания по таймеру для проврки blink-timer1.ino

#include

const int LED=13;

void setup()

{

pinMode(LED, OUTPUT);

Timer1.initialize(1000000); // Значение для переполнения 1000000 мкс

// (1 секунда)

Timer1.attachInterrupt(blinky); // Выполнять blinky()при переполнении

}

void loop()

{

// Вставьте сюда любой код

}

// Обработка прерываний по таймеру

void blinky()

{

digitalWrite(LED, !digitalRead(LED)); // Переключить статус светодиода

}

В функции Timer1.initialize() задается временной интервал таймера в микросекундах. В этом примере установлено значение 1 с (1000000 мкс). Аргумент команды Timer1.attachInterrupt() - имя функции, которая будет выполняться по истечении заданного интервала времени. Очевидно, что функция обработки займет меньше времени, чем интервал между прерываниями.

- 266 -

<p>12.5. Музыкальный инструмент на прерываниях</p>

Чтобы закрепить знание аппаратных прерываний и прерываний по таймеру, создадим электронный музыкальный инструмент, который воспроизводит ноты последовательно в нескольких октавах. Ноту выбирают с помощью кнопки с аппаратной противодребезговой защитой. По прерываниям таймера одна и та же нота по порядку воспроизводится сначала в октаве 2, затем 3 и так до октавы 6, пока нажатием кнопки не будет выбрана следующая нота. В цикле loop() для отладки можно предусмотреть вывод текущей ноты и октавы через последовательный интерфейс на экран компьютера.

Если известна начальная частота, несложно вычислить частоты нот для каждой октавы. Например, рассмотрим ноту (До). Нота До большой октавы (С2) имеет частоту около 65 Гц. Чтобы получить частоту для До малой октавы СЗ (130 Гц) умножим частоту С2 на 2. Чтобы получить частоту для С4 (260 Гц), умножим частоту для СЗ на 2. Таким образом, частоту ноты для каждой октавы можно вычислить, умножая исходную частоту на степень числа 2. Зная это правило, будем увеличивать коэффициент в два раза при прерываниях по таймеру.

Переключать ноты будем так же, как в предьщущем примере с цветным светодиодом, - по нажатию кнопки. Задаем базовые частоты для каждой ноты и переключаем их каждый раз при нажатии кнопки.

12.5.1. Схема музыкального инструмента

Аппаратная часть проекта очень простая. К схеме предыдущего примера с RGB-светодиодом добавляем динамик, подключенный к контакту 12 Arduino через резистор 150 Ом. Я взял пьезоизлучатель, вы можете выбрать другой динамик. Монтажная схема показана на рис. 12.9.

12.5.2. Программа для музыкального инструмента

Программа для музыкального инструмента использует аппаратные прерывания и прерывания по таймеру, а также функцию tone() для управления динамиком и осуществляет передачу данных в последовательный порт. Загрузите код из листинга 12.3 на плату Arduino и нажимайте кнопку для перебора базовых частот. Посмотреть частоту, воспроизводимую в текущий момент, можно в мониторе последовательного порта.

Листинг 12.3. Код для музыкального инструмента - fun_with_sound.ino

// Использование аппаратных прерываний и прерываний по таймеру

// Подключение библиотеки TimerOne

#include

//

const int BUTTON INT =0; // Прерывание 0 (вывод 2 для Uno)

const int SPEAKER=12;

// Вывод 12 для подключения динамика

- 267 -

Рис. 12.9. Графическая схема музыкального аппарата

// Базовые частоты для нот

#define NOTE_C 65

#define NOTE_D 73

#define NOTE_E 82

#define NOTE_F 87

#define NOTE_G 98

#define NOTE_A 110

#define NOTE_B 123

// Переменные volatile для изменения при обработке прерываний

volatile int key = NOTE_C;

volatile int octave_multiplier = 1;

void setup()

{

// Запуск последовательного порта

Serial.begin(9600);

pinMode (SPEAKER, OUTPUT);

// Запуск для кнопки аппаратного прерывания по RISING

attachInterrupt(BUTTON_INT, changeKey, RISING);

//Set up timer interrupt

Timer1.initialize(500000);

// Период 0,5 секунды

- 268 -

Timer1.attachInterrupt(changePitch); // Выполнять changePitch()

// при прерываниях по таймеру

void changeKey()

{

octave_multiplier=1;

if (key == NOTE_C)

key = NOTE_D;

else if (key == NOTE_D)

Перейти на страницу:

Похожие книги