Изучаем Arduino: инструметы и методы технического волшебства - [68]

Шрифт
Интервал

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)

key = NOTE_E;

else if (key == NOTE_E)

key = NOTE_F;

else if (key == NOTE_F)

key = NOTE G;

else if (key == NOTE_G)

key = NOTE_A;

else if (key == NOTE_A)

key = NOTE_B;

else if (key == NOTE_B)

key = NOTE_C;

}

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

void changePitch()

{

octave_multiplier = octave_multiplier * 2;

if (octave_multiplier > 16) octave_multiplier

tone(SPEAKER,key*octave_multiplier);

}

void loop()

{

Serial.print ("Кеу: ");

Serial.print(key);

Serial.print(" Multiplier: ");

Serial.print(octave_multiplier);

Serial.print(" Frequency: ");

Serial.println(key*octave_multiplier);

delay(100);

}

Значения частот для нот можно найти в Интернете. Базовые частоты определены для нот второй октавы. Обратите внимание, что переменные key и octave_multiplier должны быть объявлены как volatile, потому что их значения меняются во время обработки прерываний. Функция changeKey() вызывается каждый раз при срабатывании прерывания по нажатию кнопки и изменяет базовое значение пере

- 269 -

менной key. Функция changePitch() вызывает tone() для установки частоты сигнала для динамика. Она запускается каждые полсекунды по прерыванию таймера.

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

В цикле loop() в последовательный монитор каждые 0, 1 с выводятся значения переменных key, octave_multiplier и частоты.

ПРИМЕЧАНИЕ

Посмотреть видеоклип, демонстрирующий работу музыкального инструмента, можно на странице www.exploringarduino.com/content/ch12. Этот видеофайл доступен и на странице издательства Wiley.

Резюме

В этой главе вы узнали следующее:

• Как выбрать альтернативу: опрос входов в цикле или использование прерываний.

• Что реализация прерываний на различных платах Arduino неодинакова. На плате Due прерывания можно задать для любого контакта, на других платах для прерываний доступны только определенные контакты.

• Как создать противодребезговую защиту кнопок на аппаратном уровне с помощью RC-цепочки и триггера Шмитта.

• Что с помощью функций обработки прерываний можно асинхронно опрашивать входы Arduino.

• Как с помощью сторонней библиотеки TimerOne организовать прерывания по таймеру.

• Как комбинировать прерывания таймера, аппаратные прерывания и опрос в одной программе, чтобы параллельно выполнять несколько задач.

Глава 13. Обмен данными с картами памяти SD

Список деталей

Для повторения примеров главы вам понадобятся следующие детали:

• плата Arduino (рекомендуется Uno );

• USB-кабель для программирования платы Arduino;

• источник питания для платы Arduino (блок питания или аккумулятор);

• инфракрасный датчик расстояния;

• плата часов реального времени;

• плата расширения SD card shield;

• карта памяти SD;

• набор перемычек;

• макетная плата;

• компьютер с картридером.

Электронные ресурсы к главе

На странице http://www.exploringarduino.com/content/ch13 можно загрузить программный код, видеоуроки и другие материалы для данной главы. Кроме того, листинги примеров можно скачать со страницы www.wiley.com/go/exploringarduino в разделе Downloads.

Что вы узнаете в этой главе

Есть множество примеров устройств на основе плат Arduino для сбора данных о состоянии атмосферы с метеодатчиков, зондов, датчиков систем жизнеобеспечения зданий и т. п. Учитывая небольшой размер, минимальное энергопотребление и простоту взаимодействия с датчиками, платы Arduino удобны для построения регистраторов данных (устройств для записи и хранения информации в течение определенного периода времени). Такие регистраторы часто присутствуют в сетях сбора данных и для хранения накопленной информации требуется энергонезависимая память, например SD-карта. В этой главе вы узнаете, как связать Arduino с SD-картой.