Режим готовых аккордов настроен

В предыдущей заметке я высказывал опасение, что после настройки аккордов перестанет работать выборный режим для этих же нот. Так и получилось. 🙁

Я сегодня потратил часа 2, чтобы настроить датчики для режима аккордов. И когда я переключил на выборку, то для 9 нот из 12 была сбита настройка выборки: магниты пролетали мимо датчиков, и в крайнем положении рычагов ноты не звучали.

Это потому, что, как оказалось, в разных случаях при нажатии клавиш рычаги опускаются на разную глубину:

  • ниже всего рычаги опускаются в режиме выборки;
  • при нажатии мажорных аккордов рычаги останавливаются чуть выше;
  • при нажатии минорных аккордов рычаги останавливаются чуть выше, чем для мажорных;
  • а при нажатии септаккордов и уменьшенных септаккордов — они вообще опускаются чуть-чуть.

Получается, что датчик должен ловить магнит в довольно большом диапазоне расстояний. Одиночный магнит с такой задачей не справляется, и пришлось наклеить ещё по одному магниту на каждый «аккордовый» рычаг (см. рис. 1). И только после этого начали как надо работать и аккорды, и выборка.

Сегодня я с этим возился аж до полуночи. Завтра на свежую голову тщательно проверю ещё раз все датчики и буду прикручивать плату датчиков в рабочем положении. После этого просверлю отверстие в левой деке и, пожалуй, продену в него провод. (Операция эта условно-необратимая, потому что потом я припаяю к концу провода разъём, и вытащить провод обратно уже будет нельзя.

Если повезёт, то завтра я смогу сыграть на баяне обеими руками, но без меха (потому что внутренний объём пока будет негерметичен). Герметизировать всё буду уже потом, завтра не успею.

Рис. 1

Настроены датчики левой клавиатуры

Почти настроены. Выборный режим полностью работает (см. видео ниже).

Несмотря на то, что в выборном режиме все датчики работают нормально, нужно будет дополнительно настраивать 12 датчиков, которые работают в режиме готовых аккордов. Дело в том, что в выборном режиме рычаги нажимаются «глубже», т.е. опускаются ниже на плату. А в режиме готовых аккордов те же рычаги останавливаются раньше. И часть датчиков (бОльшая часть) не срабатывает. Их надо будет поднимать над платой, и ловить промежуточное положение, чтобы они звучали и в крайнем положении рычага для выборного режима, и в крайнем положении для готового. Очень надеюсь, что такое положение поймать удастся. Иначе придётся на эти 12 рычагов переклеивать магниты, чтобы они были двойные.

Внешний вид настроенных датчиков — на рис. 1. Видно, что никакой одинаковостью тут не пахнет и близко. Каждый датчик надо подгибать персонально, много раз вынимая плату для работы с датчиками и засовывая обратно для проверки.

Рис. 1

Занимаюсь настройкой положения датчиков левой клавиатуры

Процесс весьма трудоёмкий. Места между рычагами крайне мало, все подгибания ножек датчиков надо делать так, чтобы оставаться в одной плоскости.

Дело, можно сказать, вообще не двигалось, пока я не нашёл способ фиксировать плату в одном и том же положении, не прикручивая её шурупами. (Прикручивать буду в самом конце, когда буду уверен, что все датчики работают как надо и дальнейшая коррекция положения платы уже точно не нужна). Положение «ближе-дальше» определяется шириной картонной проставки, временно (а может и не временно) приклеенной перед платой, между бортиком и платой (см. рис. 1). А положение «вправо-влево» определяется «приметами на местности»; в данном случае — центр крепёжного отверстия платы должен точно совпадать с краем проставки.

Эта проставка на рис. 1 — уже третья, шириной 5 мм. Предыдущие 2 (7 мм и 6 мм) оказались слишком широкими, не позволяющими правильно выставить дальний ряд датчиков. В текущем положении далчики ближнего ряда слишком высовываются вперёд, но эту проблему можно решить подгибкой ножек.

Процесс очень небыстрый. Вчера за 2 часа я настроил только половину басов. Т.е. 12 датчиков дальнего ряда. 12 — потому что в этом баяне басы играют октавами, т.е., например, одновременно с самым левым рычагом на рис. 1 (Фа контр октавы) нажимается и 13-й рычаг (Фа большой октавы).

Эта особенность механизма, кстати, является проблемой для MIDI инструмента. Далеко не каждый вариант басового звука будет хорошо звучать октавами. Поэтому в прошивке буду делать отключаемый режим программного запрета на октавы в басах; т.е. если нижняя басовая нота уже звучит, то контроллер не будет отправлять в синтезатор команду включения верхней басовой ноты даже если соответствующий датчик сработал. (Придётся израсходовать 2 байта ОЗУ на запоминание текущего состояния 12-ти нижних басовых нот.)

Рис. 1

Полбаяна уже умеет играть

В прошедшие выходные я окончательно смонтировал и распаял платы правого полукорпуса.

Декоративную решетку пока прикрутить не получится, т.к. она будет упираться в плату датчиков 1-го и 2-го рядов (см. рис. 1). Как я ни старался опустить её как можно ниже, всё равно пришлось её поднять над рычагами так, что она в результате не помещается в штатные габариты этой части баяна. Положение платы выверено очень точно; если её опустить вниз хотя бы на 0.5 миллиметра, то некоторые рычаги клапанов среднего ряда по ней уже будут стучать, что недопустимо. Ну вот такой у меня баян, ничего с этим не поделать.

Придётся декоративную решётку тоже поднимать миллиметра на 2-3. Буду изобретать какие-нибудь прокладки между решеткой и корпусом баяна.

А пока решетки нет — плату панели управления пришлось прилепить на внешнюю поверхность корпуса. С этим можно будет прожить до тех пор, когда будет прикручена решетка. Потом прилеплю на саму решётку. (Клею на 2-сторонний скотч, естественно.)

Рис. 1

Вот так выглядит правый полукорпус изнутри:

Рис. 2

Герметизировать отверстие для проводов я пока не стал; на тот случай, если вдруг придётся зачем-нибудь всё разбирать.

Но разъёмы (MIDI-out и питание) я уже герметизировал. Обернул каптоновым скотчем — получилась как-бы опалубка, которую я залил термоклеем. В результате все щели в разъёмах перекрыты. При самой финальной сборке останется дополнительно герметизировать отверстие MIDI разъёма, и всё. Отверстие разъёма питания герметизировать е буду, т.к. мне кажется, что этот разъём и так уже достаточно плотно сидит в корпусе на резьбе.

Думал я, что вчера и сегодня буду работать над левым полукорпусом. Но не получилось. Оба вечера я играл на правой половинке: разучиваю «The Cat» Джимми Смита. Очень,очень затягивающее занятие. Но надо будет хотя бы завтра вечером начать работу над левой клавиатурой.

А что там вообще случилось-то?

Несколько раз до меня донеслось, что на этой неделе что-то там стряслось с windows, и что кошмар-кошмар и всё пропало.

Судя по выдаче Яндекса — реально что-то произошло. (См. рис. 1.)

Надо будет почитать про всё это. А то мне с Линукса плохо видно детали этого происшествия.

Рис. 1

(не)переполнение millis()

Как, наверное, любой начинающий ардуинщик, когда я узнал о том, как можно реализовать всякое с использованием функции millis(), возвращающей 32-разрядное беззнаковое целое число миллисекунд, прошедших с момента запуска микроконтроллера, я задался вопросом: «а что будет, когда счётчик миллисекунд переполнится?»

Функция millis() для ардуинщика — это альфа и омега всей «многозадачности» ардуино. Если что-то нужно регулярно выполнять через заданный интервал времени, то обычно пишут какой-то такой код:

uint32_t  my_timer;    // где-то объявляем переменную "таймер"
#define MY_PERIOD 1000 // "раз в секунду"

...

my_timer = millis();    // "запускаем" таймер, запоминая в
                        // переменной текущее значение millis()

...

// и где-то в основном рабочем цикле пишем примерно такое:
if ( millis() - my_timer > MY_PERIOD ){
    // Заданное время ожидания прошло
    // делаем здесь, что хотели

    my_timer = millis(); // снова взводим таймер для следующего
                         // срабатывания
}

Так вот, предположим, что в «таймере» мы сохранили число 0xFFFFFFFE. Естественно, 32-разрядный счётчик переполняется через 1 миллисекунду и millis() начинает возвращать 0, 1, 2, и т.д.

И куча новичков-ардуинщиков в интернете пугается, когда понимает, что при таком раскладе «всё пропало», потому что в этом случае при проверке срабатывания таймера из 1 будет вычитаться 0xFFFFFFFE и, вроде бы, так нельзя. Поиск по клчевым словам «переполнение millis()» выдаёт кучу ссылок на страницы, где «знатоки» со знанием делом говорят «не ссыте, всё будет нормально, потому что вычитание беззнаковое», не объясняя при этом ничего.

А я объясню, мне не жалко. 🙂

Для того, чтобы убедиться, что «так можно», нужно всего лишь понимать, как в процессорах общего назначения происходит вычитание целых чисел. А происходит оно через сложение.

В этом месте, может, стоило бы рассказать про комбинационную схему «сумматор» и объяснить, как она работает. Для того, чтобы на низком уровне показать, как же, собственно, компьютер складывает числа. И чтобы стало понятно, что вычитать (подобно тому, как это делает человек) процессор не умеет. Он умеет только складывать. Но про (полный) сумматор читайте в другом месте. А здесь и сейчас достаточно понять, что кто-то очень умный придумал, как можно вычитать одно число из другого, имея в качестве инструмента комбинационную схему, которая умеет только складывать (суммировать).

Он придумал представлять отрицательные числа в т.н. «дополнительных кодах«. То есть, если нам надо вычесть из положительного числа А положительное число Б, нужно преобразовать число Б в дополнительный код (получив тем самым число -Б), и после этого спокойно складывать числа «А» и «-Б». Здесь важно то, что беззнаковые числа тоже преобразуются в дополнительный код при вычитании.

Т.е. если наше А = 3 и Б = 1 (00000011 и 00000001 в двоичном представлении), то при вычитании Б из А будут складываться числа 00000011 и 11111111. В результате такого сложения мы получим 00000010, а точнее (1)00000010, где единица, образующаяся при сложении старших разрядов улетает в переполнение (за пределы нашего 8-разрядного целого). То есть, при сложении числа 3 и представленного в дополнительном коде числа -1 мы получили число 2.

В случае с millis(), нам надо было из беззнакового числа 1 вычесть беззнаковое число 0xFFFFFFFE (т.е. двоичное 1111111111111110). Ну, хорошо, преобразуем вычитаемое в дополнительный код и получаем двоичное 0000000000000010. В результате мы складываем 1 и двоичное 10, получая двоичное 11, т.е 3. Т.е. результатом операции «1 — 0xFFFFFFFE» будет 3. И это именно то, что мы рассчитывали получить, проверяя таймер:

1111111111111110 <-- здесь "засекли" таймер
1111111111111111
0000000000000000
0000000000000001 <-- а здесь "1 - 0xFFFFFFFE = 3"

Т.е. всё, что надо, успешно вычитается, и получается именно то, что надо. Вот такая магия.

P.S. Только что осознал, что двоичное представление 32-разрядных чисел у меня получилось 16-разрядным :). Но не буду исправлять, т.к. будет хуже читаться. А на суть явления размерность чисел не влияет. Можно было хоть на 3-разрядных числах это показывать.

Смонтировал немножко электроники в правый полукорпус

Сегодня я подготовил места крепления платы микроконтроллера и дифференциального датчика давления (см. рис. 1).

Заодно просверлил в деке 2 отверстия ∅4 мм. Одно отверстие для силиконовой трубки, которая будет соединять один из входов датчика давления с внешней средой (т.е. с зоной условно-нулевого давления). А второе отверстие — для жгута проводов, которые пойдут к плате панели управления и к платам датчиков правой клавиатуры.

Уже на этом этапе я вокруг отверстий наклеил каптоновый скотч. Это для того, чтобы потом герметизировать отверстия термоклеем. Умными людьми замечено, что термоклей плохо держится на алюминии, но отлично держится на каптоновом скотче. А скотч, в свою очередь, отлично клеится к алюминию и не теряет своих свойств при нагреве.

Следующий шаг — подготовка соединительных проводов (отмерить, нарезать, зачистить, облудить, связать в жгуты, промаркировать).

Рис. 1

Установил гнёзда

Гнездо MIDI-out (которое DIN-5) в данный момент держится на трении. Отверстия под крепёжные винты я делать не буду, чтобы не дырявить лишний раз герметичный корпус. Думаю, что при финальной сборке это гнездо отлично будет держаться на термоклее, которого придётся наляпать в изобилии, т.к. этот разъём сам по себе не герметичен.

А вот разъём питания вкручен в стенку корпуса на резьбу. Длина резьбовой части разьёма оказалась практически равна толщине стенки. Поэтому я просверлил в стенке отверстие 7.5 мм и нарезал резьбу М8×0.75. Благо нужный метчик у меня нашёлся. При финальной сборке перед закручиванием я намажу резьбу разъёма клеем (не суперклеем, а каким-нибудь ПВА или «Моментом». Сам разъём выглядит герметичным. Надеюсь, не придётся его заливать термоклеем.

Рис. 1

Снаружи это выглядит так:

Рис. 2

Магниты 3 ряда приклеены

На плоские рычаги магниты вообще без проблем клеятся, даже активатором не пришлось брызгать. Датчики на соответствующей плате я тоже подогнул как надо.

Следующий шаг — сверление монтажных отверстий в корпусе для разъёмов MIDI-out и питания. И сверление отверстия в правой деке, через которое будет проходить жгут из 12 проводов МГТФ 0.12 к плате 1-го и 2-го рядов и к плате панели управления.

Про панель управления я ещё не решил, как её крепить на время наладки датчиков. В итоговом варианте она будет крепиться на декоративную решётку, примерно в то место, где у многотембровых инструментов находятся переключатели регистров. Но на время наладки, думаю, прилеплю её просто на корпус на 2-сторонний скотч. Главное предусмотреть, чтобы соответствующие жгуты проводов были достаточной длины, чтобы дотянуться до места. Но с этой стороны проблем не ожидаю: 40 метров провода МГТФ должно хватить. 🙂

Рис. 1

Вообще, я уже устал от этой работы. Начинаю понимать, почему Бутусов за установку одной MIDI-системы в один инструмент берёт 200 тыр.

P.S. На рис. 1 — магниты, приклеенные неправильно. 🙂 Надо было клеить с другой стороны рычагов и с противоположным направлением полюсов. Вот что значит «устал». В результате в тот же вечер я эти 18 магнитов отодрал и переклеил по-правильному.