===== Эксперимент 23. Темп, длительность и паузы ===== Если в прошлом эксперименте ты попробовал выполнить дополнительное задание и записать мелодию, то, вероятно, понял, что это не просто, учитывая, что нужно описывать и ноты и их длительности и паузы между ними. А если после написания такой мелодии потребуется изменить ее темп, то придется пересчитывать все паузы. Должен быть другой, более удобный способ записывать мелодии. Для этого запишем мелодию, последовательность ее нот, в массив, а длительности этих нот в другой. С помощью оператора цикла будем получать эти данные и исполнять. Для записи темпа заведем отдельную переменную, которая будет учитываться в расчете длительностей. ==== Схема эксперимента ==== Схему эксперимента оставим прежней, займемся программой. {{ :products:esp-iot:exp7_sch.png?nolink |}} //Рисунок 1. Электрическая принципиальная схема эксперимента// {{ :wiki:exp7_mont.png?direct&600 |}} //Рисунок 2. Монтажная схема эксперимента// ==== Программный код эксперимента ==== from machine import Pin, PWM import time _init() tempo = 2 tones = { 'c': 262, 'd': 294, 'e': 330, 'f': 349, 'g': 392, 'a': 440, 'b': 494, 'C': 523 } speaker = PWM(Pin(15, Pin.OUT)) melody = 'abcdefgC' rhythm = [8, 2, 1, 8, 3, 4, 6, 8] for tone, length in zip(melody, rhythm): speaker.duty(512) speaker.freq(tones[tone]) time.sleep(tempo/length) speaker.duty(0) time.sleep(tempo/length/4) Мелодию мы записали строкой ''abcdefgC'', а ритм массивом ''[8, 2, 1, 8, 3, 4, 6, 8]''. С помощью цикла ''for'' и оператора ''in'' проходим по всем элементам мелодии. Для этого мы использовали оператор ''zip''. Он нужен для одновременного перебора сразу двух массивов и получения их элементов в переменные ''tone'' и ''length''. Так на первой итерации в переменной ''tone'' окажется ''a'', а в ''length'' — ''8''. На второй итерации ''b'' и ''2'' соответственно. Здесь внимательный читатель заметит, что ''melody'' не является массивом, а является строкой. Почему же мы говорим о ней как о массиве и работаем как с массивом. Оказывается в Python любую строку можно представить как массив символов и обращаться к ним по индексу, что мы и делаем. Получив ноту и ее длительность настраиваем частоту и скважность. Нота начинает звучать: speaker.duty(512) speaker.freq(tones[tone]) Нота звучит, пока мы ждем время, равное ее длительности. В расчете учитывается темп: time.sleep(tempo/length) Чтобы ноты не сливались, мы делаем между ними маленькие паузы. Паузы между нотами также зависят от темпа и длительности ноты, но в 4 раза короче. speaker.duty(0) time.sleep(tempo/length/4) ==== Дополнительное задание ==== * Измени темп мелодии и длительности отдельных нот.