===== Эксперимент 23. Темп, длительность и паузы ===== Если в прошлом эксперименте ты попробовал выполнить дополнительное задание и записать мелодию, то, вероятно, понял, что это не просто, учитывая, что нужно описывать и ноты и их длительности и паузы между ними. А если после написания такой мелодии потребуется изменить ее темп, то придется пересчитывать все паузы. Должен быть другой, более удобный способ записывать мелодии. Для этого запишем мелодию, последовательность ее нот, в массив, а длительности этих нот в другой. С помощью оператора цикла будем получать эти данные и исполнять. Для записи темпа заведем отдельную переменную, которая будет учитываться в расчете длительностей. ==== Схема эксперимента ==== Схему эксперимента оставим прежней, займемся программой. {{ :products:esp-iot:exp7_sch.png?nolink |}} //Рисунок 1. Электрическая принципиальная схема эксперимента// {{ :wiki:exp7_mont.png?direct&600 |}} //Рисунок 2. Монтажная схема эксперимента// ==== Программный код эксперимента ==== #define SPEAKER_PIN 15 int tones[8] = {262, 294, 330, 349, 392, 440, 494, 523}; enum Note {c, d, e, f, g, a, b, C}; struct Sound { int note; int length; }; const int tempo = 2000; Sound melody[8] = {{a, 8}, {b, 2}, {c, 1}, {d, 8}, {e, 3}, {f, 4}, {g, 6}, {C, 8}}; void setup() { pinMode(SPEAKER_PIN, OUTPUT); analogWriteRange(1024);; } void loop() { for (int i = 0; i < 8; i++){ analogWrite(SPEAKER_PIN, 512); analogWriteFreq(tones[melody[i].note]); delay(tempo / melody[i].length); analogWrite(SPEAKER_PIN, 0); delay(tempo / melody[i].length / 4); } } Для того, чтобы записать ноту и ее длительность в одну переменную воспользуемся типом ""struct"", который представляет набор переменных разного типа, объединённых одним именем, в нашем случае — ""Sound"" Количество переменных внутри ""struct"" в принципе не ограничено нам будет достаточно двух "note" и "length": struct Sound { int note; int length; }; Мелодию мы запишем в массив ''melody[8]'' содержащий элементы типа ''Sound'', каждый из которых в свою очередь состоит из двух переменных типа ''int''. Sound melody[8] = {{a, 8}, {b, 2}, {c, 1}, {d, 8}, {e, 3}, {f, 4}, {g, 6}, {C, 8}}; С помощью цикла ''for'' проходим по всем элементам мелодии. Обращение к внутренней переменной типа ''struct'' производится с помощью ''.'' и ее имени. Получив ноту и ее длительность настраиваем частоту и скважность. Нота начинает звучать: analogWrite(SPEAKER_PIN, 512); analogWriteFreq(tones[melody[i].note]); Нота звучит, пока мы ждем время, равное ее длительности. В расчете учитывается темп: delay(tempo / melody[i].length); Чтобы ноты не сливались, мы делаем между ними маленькие паузы. Паузы между нотами также зависят от темпа и длительности ноты, но в 4 раза короче. analogWrite(SPEAKER_PIN, 0); delay(tempo / melody[i].length / 4); ==== Дополнительное задание ==== * Измени темп мелодии и длительности отдельных нот.