Статья отчасти является предупреждением допущений, не исключив которые разработчик может ощутить всю их неблагоприятность, отчасти — попыткой объяснить — что же от вас может хотеть заказчик, отчасти — работой над ошибками или признанием «сам дурак». Caution: DotA jargon ahead, «Я не гик!», а также искусное изложение без помощи матов. Продолжая читать, вы рискуете составить мнение о том, что автор — абсолютно отбитое животное, не знающее жалости, страха и пощады ©. Просто примите как данность, что каждый имеет право быть неидеальным, и всё у нас будет ладненько. Пожалуйста, и спасибо.
Работа велась над автоматикой escape room, детали которой, как принято, будут опущены. Длилась эта работа больше года, и первоначально там были действительно ощутимые огрехи в виду банального отсутствия опыта, но потом всё вылилось в неоптимальное управление. Заказчики (звали их, скажем, Гудвин и Урфин) занимались в основном косметической составляющей проекта, занимались от и до, после мы сосредоточились на собственно логике и реализации, т. к. собственно двери и объекты были готовы, и надо было сделать так, чтобы они шевелились. Время начинало давить, и мы на каком-то этапе спали часов по 5 в сутки. Разумеется, надо размывать детали для соблюдения секретности, но мне слишком конкретно что-то вспомнить и не удастся, т. к. мной была прекращена всякая работа над ним более 5 месяцев назад. Сдельной работы оказалось достаточно чтобы позволить себе каждый день тупым ножом открывать консервную банку с какой-нибудь сайрой, а чайные пакетики были настолько компактными, что помойка была счастлива меня увидеть раз в две недели. Комната моя превратилась в вентиляционную шахту, в которой жила Ребекка из фильма «Чужие». Или «Чужой 2», кому как привычнее. Если кто не помнит, то вот вам скрин с кучей мусора:
События, послужившего триггером; чего-то такого, что вынудило меня написать в чат «gg» и ливнуть, как такового не было. Меня просто посетила чёткая и ясная мысль: мне нужен длительный отдых. Передатчик на моём сотовом телефоне перешёл в авиарежим на 4 месяца. Эти же 4 месяца в статистике запросов на фейс, вконтакт, форумы, в которых как-либо могли фигурировать мои cookie-данные, ознаменованы такой длииииинной дырой. Никто, ни по какому каналу, не мог выйти со мной на связь. Мне просто было в кайф сидеть в комнате, жрать тушёнку и катать в дотан. Паскудное занятие, я знаю, но зато у меня было время хоть где-то достичь совершенства. Как и у всякого фаната VJLink, первыми кандидатами для того чтобы божить, должны были стать Пудж, ПотМа (Мирана) или Оракул, но как оказалось, мой любимый герой — Линочка. Всего на моём счету больше тысячи игр за неё, и любое нечто, заплутавшее на карте, ждёт изящная и лёгкая смерть от её слабых рук. Много народу говорит мне, что моя техника восхитительна, так что фраза из двух слов в заголовке теперь по праву красуется в качестве моего статуса вацапа.
Резюмируя весь проект, я могу сразу назвать его главную ошибку — отсутствие системного подхода. Я знаю, что в «Космической одисее» использовалась специальная интерфейсная плата, обеспечивающая взаимодействие периферии с TCP/IP. У меня же таких плат не было, лишь горсть Arduino, которые в итоге понадобились для неких совершенно простецких вещей. Мы постарались свести всё возможное к управлению простым 0 или 1, ногодрыгу, как говорят микроконтроллерщики. Это снизило нагрузку на центральный сервер, собранный на Mega2560, чтобы принимать и выдавать информацию по web с наименьшей задержкой. Логика квеста была переписана с Wiring на JavaScript, но это привело к тормозам, ибо JS выполняется в системе, не являющейся RTOS, в итоге логика потом ещё переписывалась на свойский формат (xml, которым руководствовалось приложение на Java), хотя в целом наивно полагать что это что-то дало, т. к. выполняется оно по-прежнему в среде Windows. Вообще в этой работе часто переделывалось нечто вроде бы уже отлаженное, где неожиданно вылезали какие-то косяки, и первоначально статья писалась именно об этом; но теперь она о том, что реализацию логики осуществляет приложение на Java, точнее — о причинах и предпосылках этого.
Почему Java а не JS? Понятия не имею, его писал другой человек, видимо этот инструмент ему привычнее. Получив сообщение из группы Whatsapp о моей неявке для прояснения деталей этот человек прислал в группу кадр Пикарда, прислонившего руку к голове, но знал бы он, что в тот момент мне уже было абсолютно плевать — думаю, смог бы понять. А мы попробуем разобраться, как так получилось. Сейчас уже не так напрягает возможное гавкание друг на друга «они неадекваты, не подчиняются предписаниям, не соблюдают стандарты и правила эксплуатации, выводят оборудование на недопустимые режимы, подвергают сомнению мою квалификацию каждой фразой», «он неадекват, некомпетентный, довести до конца проект не может, сроки срывает, постоянные переделки, какой-то самопал не как у всех», и т. д. и т. п. Побазлали и хватит. Гудвин и Урфин — те ещё упыри, однако последнее что пришло бы мне в голову — намеренно портить им дела. Выгоды я не получу, а вред назло, просто так — не на общее благо. Итак, зачем же тогда ухудшать мир? Думаю, и у них не особенно высок приоритет задачи обхаять меня и устроить антирекламу, чтобы никто никогда ко мне не обращался. Вряд-ли вообще такая задача поставлена. Опыт — суровый учитель, и нужно найти в себе силу идти дальше. И самое главное — пользоваться этим опытом. Часть этого опыта, по крайней мере ту, что смогу вспомнить — смею надеяться, я передам вам, уважаемый читатель.
Мы нечасто крыли друг друга матом, но всё же настроение было так себе. Дабы не свихнуться, мне пришлось использовать в работе самое тяжёлое из всего чем можно было упарываться — гайды VJLink и стримы Карины. Да-да, напоминаю: я не гик, я просто животное. Разумеется, я отдаю себе отчёт в том что эти двое — клинические имбецилы: не надо думать, что кто-то из них является для меня духовным учителем; на эту роль гораздо больше подходит itpedia. Но мы как-то отвлеклись от квеста, мысли по пути к которому сводились примерно к «да опять его пилить, ну сколько можно, когда это кончится». Вообще, отсутствие энтузиазма на любом проекте отражается самым скверным образом. Кому надо потеть, когда Сларк в вашей команде 0-7? Так и здесь: если каждая задача, каждое внедряемое решение встречает вас глюком на глюке, тает всякая надежда. Располагайтесь поудобнее и я поделюсь некоторыми мыслями о том, как не допустить этого. Также, мне бы хотелось побольше таких приёмов увидеть в комментариях. Любой опыт субъективен, но именно большой объём прецедентов позволяет их обобщать и анализировать. Учиться. Мной было допущено множество ошибок, но всё же не все из возможных. Вероятно, кто-то из читателей сталкивался с чем-то иным, но в общем-то подобным. Поделитесь своим опытом, all будет вам благодарен.
Мои правила
- Все датчики должны иметь индикацию.
- Все компараторы должны иметь гистерезис.
- Все скрутки должны быть пропаяны.
- Все силовые провода должны быть толстыми.
- Все сигнальные провода должны быть экранированными.
- Все провода, напряжение на которых выше 40 В, должны иметь изоляцию получше, чем просто тупая пара. 220 по витой паре или лапше — моветон.
- Все выходы должны иметь открытый коллектор/открытый сток.
- Все входы должны принимать сигналы через токовую петлю/оптопары.
- Все устройства, осуществляющие асинхронный приём-передачу, должны иметь формирователь импульса сброса и сторожевой таймер, чтобы быть готовыми к приёму в любой момент.
- Все коммутационные устройства должны иметь искрогасящие цепи. Реле особенно, слипшиеся контакты — это не весело.
- Всякая механика тяжелее килограмма любит редуктор. Люди, ставящие двигатель прямо на кирпич, без редуктора — знайте: длань Сатаны настигнет любого. Просто будьте прокляты :3
- Все индуктивные нагрузки должны иметь встречно-параллельный диод для подавления ЭДС самоиндукции. Если ток может идти в обе стороны (открывающиеся/закрывающиеся замки из автоактуатора, двигатель и т. п.) — вместо диода конденсатор 0.1 мкФ.
- Резисторы, транзисторы и оптопары лишними не бывают.
- Резисторы внатуре лишними не бывают, особенно там где ISP разъём.
- ISP разъём должен быть таким, чтобы его нельзя было вставить вверх тормашками.
- Аккумуляторы не любят глубокий разряд. Неважно какие, любые.
- Б/у аккумуляторы — особенно.
- Кварцевая стабилизация — добро и позитив, как у Сергея Симонова. Мутить 555 в критических ко времени приложениях — зло и негатив.
- Кабель всегда лучше чем радио.
Датчики движения, дальномеры, герконы и сенсоры — это не датчики присутствия
Хотя оное и написано в описании товара HC-SR501, но — нет. Он НЕ определяет присутствие. Он определяет возмущения в интерференционной картине, которую сенсор видит через линзу Френеля. Присутствие человека в некоторой зоне определяется прерыванием ИК-луча, причём узконаправленного, и то с оговорками. Первоначально предполагалось использовать УЗ-дальномер. К сожалению для дальномера, стены помещения были из пенопласта, окрашенного грунтовкой. Отражения были чудовищными, вдобавок в противоположном конце, за углом был второй дальномер (да-да, читатель, до нас допёрло использовать систему флагов и запрещать одновременную работу обоих датчиков, но всё равно). В общем, показания этих датчиков оказывались близкими к истине лишь по забавной случайности, ну или благодаря «тепличным» условиям, когда излучатели были направлены не на рабочее помещение а куда-нибудь в сторону, где на заднем плане был деревянный стол, мягкая тряпка или ещё что-нибудь такое, неглянцевое, эффективно поглощающее.
Инфракрасный дальномер, к сожалению, некогда было ни покупать, ни испытывать (хотя кому это рассказывали, при таком-то сроке). Поэтому по краям помещения были замурованы ИК-приёмники в одной стене и светодиоды в другой. Делать их видимыми не было никакого прикола, т. к. это бы разрушало атмосферу, и именно поэтому не были использованы датчики препятствия, такие жёлтенькие, с переменным резистором сзади — они отлично работали, но спереди был такой мааааало-мальский красноватый свет, от светодиода который вроде ИК, но не до конца — короче 808 нм. Может 780. В общем, видно их, как подсветку в камерах. К тому же, не хватало дальности, нормально они определяли людей только в пределах 45 см. Поэтому пришлось сделать своё.
В этом поучаствовали VS1838 (кстати универсальная вещь, они ещё понадобились) и TSAL6200, вставленные в трубки из пластмассовых дюбелей. Это не заработало. В робокрафте (пардон, не сочтите за рекламу) продаются ИК-фототранзисторы с двумя выводами, выглядят они как прозрачный светодиод, стоят рублей 15 что-ли, у них резко уменьшается сопротивление при освещении стабильным немодулированным светом 780-1000 нм, и нужно было использовать их. Но за год их так и не купили. Зато у меня была куча VS1838, выдранных из китайских бытовых светильников для подсобных помещений, кто не знает — это такой маленький, менее чувствительный, более дешёвый аналог TSOP1738. Как мы все знаем, 1738 содержит демодулятор, фильтр и АРУ. Поэтому в них нельзя светить немодулированным светом, для датчика он будет просто фоновой засветкой. В общем, передавать в светодиоды пачки импульсов требуемой частоты не составило труда, надо всего-лишь использовать прямой вывод в порт (ибо digitalWrite() слишком медленная для таких вещей), и delayMicroseconds(27). 27 мкс — это где-то примерно полупериод 38 кГц, несущей выделяемой датчиком. Однако, нельзя просто взять и светить на 38 кГц, такой сигнал АРУ считает шумом, поэтому пришлось поделить 38 кГц на пачки импульсов, чтобы сигнал не срезался. Как ни странно, паразитной засветки соседних датчиков (всего их было шесть, расстояние между ними около 35 см) не наблюдалось, особенных провалов по яркости, приводящих к заниженной чувствительности каких-то отдельных датчиков — тоже, но тем не менее. Не. Ра. Бо. Та. Ло.
Мы бы могли заморочиться этой темой, обсудить неоптимальность программы (ибо почему тогда диагностическая программа, в которой дефайном выбирался интерсующий отдельный датчик, работала от и до, идеально?), но это выходит за рамки темы. Скажу лишь, что я редко допускаю ошибки. Если я скручиваю шесть сигнальных проводов в один жгут — я знаю: выход у них — открытый коллектор, в жгуте они никак не будут влиять друг на друга. Я знаю что у каждого датчика есть свой конденсатор 0.1 мкФ параллельно питанию, что у каждого светодиода — свой, отдельный резистор, и что вешают несколько светодиодов параллельно на один резистор только конченные. Так что мы не будем останавливаться на этом, надо было использовать фототранзисторы и подавать на светодиоды постоянный ток. Всё. Так же, каждого в трубку чтобы избежать паразитной засветки. Оно могло работать, просто на определённом этапе не было принято нужное решение.
RFId не вечна, всмысле не бесконечна
RFId-приёмник имеет свою, весьма небольшую, зону чтения. У хороших приёмников она около 7 см. У тех что похуже — 4 см. Катушку можно перемотать (главное учесть, чтобы резонансная частота не слишком далеко ушла от 125 кГц), но опять же — не до любых размеров. Тем не менее, в 2-2.5 раза увеличить её диаметр можно. В действе участвовало три автономных, могущих оказаться где угодно предмета, которые нужно было идентифицировать. Величина двух из этих предметов была близка к габаритам блока питания ATX, соответственно, диаметр катушки исчислялся десятками сантиметров, поэтому от варианта со RFId пришлось отказаться.
Здесь опять же помог ИК-канал, только уже не с такими мощными светодиодами, а послабее (наоборот надо было, чтобы сигнал принимался только в непосредсвенной близости от приёмников). В одном из предметов замуровано 11 светодиодов, светящих под всевозможными углами, потому что предмет круглый. У другого есть деревянная ручка, поэтому там светодиодов только три, так как светить в направлении ручки не нужно, она всё равно торчит вверх, где приёмника нет. Третий предмет достаточно мал, и может быть в его случае даже можно было бы обратить вновь внимание на RFId, но габариты всё равно были несравнимы с зоной чтения.
Все предметы питаются от аккумуляторов 18650 емкостью от 2000 до 3400 мАч. Там где 2000, там б/у. Принцип с ИК прост — ждём долгий промежуток времени (секунды), выдаём чуть дольше миллисекунды квадратный сигнал 38 кГц, чтобы приёмник сработал и выдал чёткий ноль на выходе. Повторяем по вкусу. Первоначально этим занималось два 555х таймера, естественно время уползло непонятно куда, естественно забыли выключить, а таймер всегда хочет кушать, и надо ему не абы что а 20 мА, естественно двум б/у банкам это очень не понравилось.
Предметы пришлось вскрывать (да-да, силиконовые конечности зомби, граната Ф1 из чугуна без единого шва, додумайте сами), хотя не так уж много времени это и отняло. Ну, с неделю провозились в общей сложности. Таймеры были заменены на atmega8, код IRRemote туда не вмещался (хотя забавно, через время мне удалось собрать скетч для посылки, и никаких ошибок при выбранном atmega8 компилятор не показал — может быть, у меня тогда уже была новая версия библиотеки). Почему 8? Ну, дёшево, плюс 328 не было в наличии. Программа просто выдавала пачки импульсов с нужной паузой, и через 7000 секунд засыпала, переводя все выходы в высокоимпедансное состояние и отключая всё что можно, чтобы свести потребляемый ток к десяткам микроампер. Это работает и задача решена.
На приёмной стороне три датчика запускают три условия. По приходу импульса запускается счётчик и сохраняется метка времени (millis). Если следущий импульс пришёл в этот же датчик и счётчик достиг n1 — предмет первый, n2 — второй и так далее. Если n достаточно велико а сигнала всё нет, видимо сигнал был случайным и счётчик сбросится. Не думаю что это какой-то мега супер алгоритм, но он решает некоторые проблемы:
- Прицепить много (то есть больше одного) ИК-приёмника к одному контроллеру — задача не для нубов. Да, даже на mega2560. Да, существует многодатчиковый форк IRRemote. Одиночные датчики и самопальная система условий — проще.
- Были непонятки с записью кода IRRemote в atmega8. Да, можно было записать RAW пакет, сформировать из него массив а потом опять же выдавать низкоуровневыми функциями и микросекундными задержками, но чё-то было лень.
- У датчиков длинные провода, мало ли что. Длинные — это больше двух метров.
Сбросить время отсчёта позволяет разъём DC-05 (разъём питания ардуины) — если вставить в него разъём, два из трёх контактов размыкаются, отрезая питание. У третьего предмета разъёма нет (он слишком аутентичный для этого), но там тоже сброс не вызвал проблем — аккумулятор заряжается от TP4056, у неё есть вывод CH, ноль на котором обозначает процесс заряда — он соединён с Reset. Энергию TP4056 получает беспроводным способом через катушку — кладём на зарядную подставку — всё равно что вставили разъём, всё в сбросе. Сняли — сброс не притянут к земле, можно считать импульсы. Насчитали — заснём, глубоко и надолго; чтобы вывести из строя аккумулятор, надо забыть заряжать эту вещь на протяжении года. И то, она разборная. Эти предметы были самым удачным решением, которое получилось почти сразу, пусть с некоторыми плясками.
Yikes! Invalid device signature. Double check connections and try again or use -F to ignore...
Самая мерзкая ошибка из всей моей практики. Понятия не имеешь, в чём дело. Вот те ситуации, которые возникали у меня:
- Перепутан порядок проводов MOSI (D11), MISO (D12), SCK (D13).
- Вместо конденсаторов 22 пФ возле кварца припаяно что-то другое. Как-то раз вместо одного из них оказался резистор 1k. Припаянный надписью вниз.
- Все шесть проводов должны быть целы. Всегда таскайте тестер (разъём такой разъём), всегда прозванивайте от разъёма прямо до ног контроллера (дефекты дорог на плате никто не отменял). Или даже от ног ведущего контроллера (в программаторе) до ног ведомого.
- Допустим, плата питается от 12 через 7805. Минусы программатора и 7805 должны быть соединены. Да, все 6 проводов контачат, но ещё раз проверить нелишне.
- Выбран неверный контроллер.
- Выбран верный контроллер, но его сигнатура всё равно отличается. Вот что у меня написно для mega328 в hardwaretoolsavretcavrdude.conf:
# signature = 0x1e 0x95 0x0f; #tqfp32 # signature = 0x1e 0x95 0x14; #dip28
С чем работаем, то и раскомментируем.
- Fuses установлены на внешний кварц (больше 8 МГц), который по факту отсутствует. Тут всегда имейте платку с кварцем и двумя конденсаторами и три провода. А также, всегда предусматривайте на плате пады, идущие к XTAL1 и XTAL2. Даже если она точно будет на 8 МГц, от батареек же. Даже если «всего один раз прошить, там точно забыть нельзя». Ещё как можно.
- Pure f███ing magic? Другая, в точности такая же плата, собранная заново, работала.
Правдоподобность света
Не используйте для эффектов пламени трёхцветную ленту. Пламя содержит в тех или иных пропорциях жёлтый свет, красный свет. Всё. Попытаетесь использовать для достижения жёлтого сочетание R+G — пламя будет зелёное. Попытаетесь поднять яркость, добавив «белого» синим — будет пламя синее, голубое или фиолетово-персиковое, если жёлтого достаточно. Не надо холодные цвета применять как компоненты основных цветов, вообще, физически не должно быть зелёных и синих светодиодов в этой ленте. Никак от слова совсем. Это решение — самое неудачное принятых. Скорее всего, ленту в светильниках Гудвин и Урфин всё же решат поменять. Каналов там достаточно, этим тоже управляет самопал на atmega8, по сути плата Pro mini, у которой заодно предусмотрены три силовых транзистора на PWM-совместимые выходы. Две жёлтых ленты и одна красная, будет самое то. Все три случайно. Жаль что на глаза не попалась терпимая схема ГСЧ на шумовом диоде, хотя и псевдослучайные опусы atmega8 выглядят терпимо. Но не с зелёным цветом в ленте.
Стробоскоп
Молния — явление благородное, во всяком случае для нагнетания атмосферности, однако оно не так требовательно как кажется. Проще коммутировать квадрат 1х1 м обклеенный лентой (80 метров, 96 ампер при 12 вольтах, почти 1.2 кВт), чем поджечь одну импульсную лампу 10 кВ импульсом при токе в миллиамперы. Почему? Потому что помеха широкополосная. Стробоскоп в момент вспышки серет везде где можно, на всём спектре будет виднеться явная полоса. Вспышка. Как её убрать, непонятно. Строб, включенный через сетевой фильтр, благополучно вешает и W5100, и ардуину. Единственный удачный эксперимент на эту тему удалось сделать с аккумулятором. Способов отвязать стробоскоп от основной сети — два.
Способ первый:
- Включаем стробоскоп чтобы зарядить рабочий конденсатор. Двумя реле, надо будет отрезать от розетки оба провода питания.
- Отключаем.
- Подаём напряжение на поджигающую обмотку, по радио или через оптопару.
Способ второй:
- Переделываем питание стробоскопа на низковольтное, чтобы тот не подключался к розетке вообще.
- Подаём напряжение на поджигающую обмотку, по радио или через оптопару.
Сторобоскоп надо тщательно экранировать. Вокруг поджигающего трансформатора вообще полезно спаять коробочку из фольгированного материала, так, на всякий случай. И то не факт, что у вас опять что-нибудь не повиснет. А между тем, мощные полевики вполне нормально работают на частотах до 100 кГц, включить 80 метров ленты на 100 мкс — делать н… э-ээ, как два пальца обо..., ну в общем, не подберу я подходящего выражения, главное запастись конденсаторами, чтобы БП не ругался. И помеха будет низкочастотной, а это куда проще фильтровать. Дроссели, электролиты, ну в общем сами понимаете. Понимаю, что это не в пример дороже чем импульсная лампа, зато работать проще.
Диммеры 220
Может быть создатели не сталкивались с таким, а может быть делали только один канал, и в Сети как-то забыли упомянуть, что напряжение из одного фазового регулятора может утекать во второй, если они стоят рядом. Лечится сетевым фильтром. В микроволновках такой железный, на корпусе написано EMI Filter.
Датчик нагнетаемого воздуха
Датчик прост, это подвижная шторка из лужёного фольгированного стеклотекстолита, движение которой ограничено рыболовной резинкой. Почему не резинкой для денег? — рыболовная долговечнее. Воздух поступает через трубку диаметром около 2 см. Возможно, здесь бы зашла крыльчатка с энкодером/магнитами + датчики Холла, датчик давления и т. п., но этого не было в наличии (лол, год прошёл, до сих про я угараю с этой отмазы про наличие), ну и хотелось сделать датчик максимально дубовым, чтобы к нему могли идти длинные провода. Мало приятного, знаете ли, в занятии «тащить SPI или i2c за 7 метров от ардуины, 7 (семь) метров, Карл».
Датчик я, в общем, считаю удачным, но он имеет недостаток. Этот недостаток заключается в особом временном (темпоральном то есть) профиле сигнала, ADSR-огибающей, так скажем. Существует целый ряд вариантов, как именно воздух будет поступать в датчик, как дуть в него. Можно дуть длинно, можно кратко, часто/редко и так далее. Поэтому, нужны точные временные рамки, ограничивающие сработки датчика до тех и только тех случаев, когда с него приходит ноль, в течение некоторого времени, и спустя это время ноль должен стать единицей, опять же не меньше некоторого времени. Вроде пара условий, но на деле подобрать эти рамки оказалось сложно, и различие в каких-то 100 мс диаметрально изменяло логику срабатывания датчика. Осциллографа, чтобы снять нужные показания во время образцового дутья, а потом под них подогнать систему условий, разумеется не было. Так или иначе, настройка свелась к двум-трём неделям работы и особых фокусов там не было. Даже провода не рвали.
Кстати о проводах
Это, в основной своей массе, — омеднённая алюминиевая витая пара STP, с экраном из фольги. Раньше там была медная UTP пара, но почти вся она была заменена на экранированную. Во-первых, прекратились натекания непонятно чего на датчики, приводящие раньше к ложным срабатываниям, во-вторых — так спокойнее. Правда биметалл, ну да ладно. Дурость номер раз допустил техник, работающий с проектом до меня — он провёл своей UTP парой вообще всё. В том числе и провода светильников, которые первоначально были 220. Потом туда поставили лампы с длинной нитью, жрущие ничтожный ток, и это в принципе, в общем-то, если наплевать на безопасность, было допустимо. Но свет ламп Гудвина с Урфином не устроил и мы их заменили на ленту, подав 12 вместо 220. Так как светильники уже были установлены, там был патрон Е27, и мы просто сделали пару платок на mega8, к которым были подпаяны такие цоколи, которые оторвали с энергосберегающих ламп. Вроде всё путём, но в одной стене в патроне оказалась одна полярность, а в другой стене — другая полярность, и было весело менять вышедшую из строя 7805 когда лампы перепутали. С тех пор на них паяльником выжжены надписи, какая откуда. Потом Урфину и Гудвину захотелось управлять этими лампами, и было увлекательно и занимательно им объяснять, каким именно образом и какие возможности управления сколькими каналами у них есть, по двум проводам, два из которых являются проводами питания. Они как-то сникли, но спорить не стали, это им плюс в карму. Мы ещё вернёмся к этому аспекту, но пока продолжим о проводах.
С ними вообще связано множество интересных решений, ибо всё строилось и подключалось одновременно, я понимаю что всё ради маляра Пети, который не должен курить и тупить, ожидая каменщика Васю, но чисто гипотетически можно было предусмотреть чуточку больше вопросов. Техзадание как таковое рождалось по ходу работы, но мы спишем это на нубство и отсутствие опыта. Последствия этого таковы: 8 метров ленты, это на минутку, почти 10 ампер, питаются от одной жилы UTP пары. К чести этой жилы, такой ток она выдерживает (спойлер: не весь) и даже не тёплая, но только благодаря модуляции, а также настоящей, монолитной меди, без всякого биметалла. Тем не менее, если модуляция остановится а на затворе полевика будет единица — полевику всё равно. Спустя час такого режима изоляция расплавится, и парням из Волшебной страны Оз будет весело выковыривать провод, ибо он вбетонирован в пол. Ну не знали они, что в будущем решат приклеить туда столько ленты, ну с кем не бывает. Конечно, всего надо будет вытащить от силы сантиметров 70, но тем не менее…
Часть проводов оказалась потом не нужной вовсе. Часть проводов — коаксиальный ТВ кабель для камер (естественно, не IP) и микрофонов. Когда решили немного перетащить DVR, выяснилось что кабели камер и микрофонов надо наращивать. Потом выяснилось, что кабели, которые пробуют силой затолкать в гофру, обычно рвутся в месте пайки. Часть из витых пар была разведена до меня, и тогдашний доктор Эммет Браун решил, что будет здорово в одном кабеле сделать минусы синей и коричневой парой, в другом — синей и зелёной. Мне было привычнее расплетать пары и делать минусом все белые провода, а плюсом — все цветные. Ну согласитесь, так тяжелее полярность перепутать. Выяснять потом эту полярность у оборванных, откушенных кабелей — это была просто песня! Особенно когда на том конце подключен двигатель сопротивлением в пару Ом, и отличить КЗ от не КЗ по сопротивлению невозможно… В общем, спустя месяц можно было сдавать устный зачёт по сопротивлениям всех имеющихся в системе кабелей, а также схемам, провода каких цветов соединены внутри скруток вместе. Это даже не писалось в таблицах, оно вбито в подкорку, как вбивают солдатикам а потом среди ночи спрашивают серийный номер автомата.
Звуковая подсистема
WTV-020SD16P не зашла. Не любую TF карту читает, нет чётких признаков того, что вообще работает, примеры внятных результатов не дают. Альтернативным вариантом стал самопал на atmega328 с библиотекой TMRpcm. Не устроила амплитуда сигнала, пытались уменьшать резистор на PWM-выходе, уменьшали-уменьшали, 328 возьми да и гавкнись. Поменяли, подключили к такому усилителю, к сякому усилителю, в общем — тихо, говорят. Не устраивает. Даже кто-то из этих челиков озвучил мега светлую мысль последовательно подключить один усилитель (китайскую колонку), а на его выход, там где два провода на динамик — второй усилитель, и это была титаническая задача: довести до его светлого разума простой посыл, гласящий «чувак, ты так просто спалишь вход». Тёмными ночами меня мучают кошмары и я просыпаюсь в холодном липком поту с одной лишь мыслью: а вдруг он мне не поверил? Щютка йумора, мне плевать.
Всего источников звука 6, из них один вуфер и в одной из комнат стереозвук, так что можно условно назвать это 4 зонами, из которых доносится звук. Три первых просто представляют собой различные каналы 5.1 и озвучиваются с компьютера, на последнюю каналов вуфера не хватило. Там стоит компьютер, одна маленькая колонка и одна большая колонка, разнесённые на разные каналы 2.0 (стерео).
При запуске компьютера на нём запускается Firefox, в нём — страница, в странице — бесконечный цикл с AJAX запросом к PHP сценарию, обслуживаемому сервером на том же компьютере. По запросу к PHP извне тот пишет цифру в файл, по запросу AJAX со страницы — говорит цифру, если цифра отличается от прошлой — AJAX, точнее howler.js, проигрывает звук. Куда — зависит от звука, в одних звуках в правом канале полная тишина, они для одной колонки, в других звуках тишина в левом, они для другой колонки.
Компьютер стар и забывает что-то, что позволяло разбудить его по WOL, за несколько часов. То есть, если выключить его, и хоть с телефона, хоть с другого компьютера в течение обозримого времени послать WOL-пакет, компьютер запустится. Проходят сутки и он этого уже не делает Поэтому к его кнопке питания пришлось тащить два провода.
Остальной звук для меня остался тайной, раньше он тоже проигрывался из HTML посредством howler.js, затем новый человек приспособил к своему приложению на Java библиотеку VLC-проигрывателя, сейчас не знаю. Я пойму комментарии в духе «сервер с howler — костыльное решение, где mp3 shield?», объясняю сразу — к тому времени ещё не посетила идея купить, к тому же «вот у нас 5 проигрывателей на WTV020, вот флешки». Это оказалось рабочим решением, и я не считаю его худшим, нежели mp3 shield.
Командная подсистема
Сейчас она представляет собой два центральных процессора, к которым по длинным проводам подключены датчики/исполнители. Длинные — это значит больше двух метров. Если исполнитель — через IRFZ48N либо релейную плату, либо более мощное реле (60А) если двигатель, либо фазовый регулятор на симисторе+moc3021/3051. Если датчик — через оптопару, чтобы земля датчиков была отвязана от земли Arduino. Длина проводов — до 20 м, так или иначе это либо токовые петли, либо многожильные провода для мощных нагрузок. Почему не развести для них DMX/RS-485 сразу, для меня — загадка. Но, есть то что есть. Раньше они управлялись дистанционно сетью трансиверов nRF24L01+. В протоколе трансиверов был предусмотрен код устройства, код операции и ещё чёртова бабушка, и даже не было коллизий, но он так себе работал совместно с циклом, обслуживающим Ethernet. Запросы приходят часто, т. к. Урфин и Гудвин хотят видеть на компьютере оператора состояние, желательно в реальном времени, поэтому сперва в HTML-интерфейсе, а потом и в Java-службе, был помещён бесконечный цикл, непрерывно опрашивающий состояние, с обоих контроллеров. Естественно, в те 150 миллисекунд, которые контроллер занимался сетью, ему было не до трансиверов.
Способов сделать эту подсистему лучше, два.
Во-первых, можно остановить poll-цикл, и присылать состояние только по изменению показаний датчиков. Для этого потребуется передатчик, способный дать сигнал компьютеру (например, последовательный вайфай ESP8266, посылающий для PHP запрос).
Во-вторых, можно разделить систему на отдельные устройства, каждое из которых будет способно напрямую связаться с компьютером, но это потребует наличия сететвого интерфейса на всех устройствах, от датчиков до двигателей. Допустим, для нескольких устройств, территориально сосредоточенных возле какой-нибудь двери, и всё же, их потребуется больше чем 2. В общем, сделать TCP/IP периферийнуюю плату из квеста про Космическую одиссею. Такая плата — наилучшее решение, из всех возможных.
Ориентированность на процесс
Эта теория принадлежит не мне, я ни на чём не настаиваю. И в мыслях нет подвергать сомнению деловые качества Гудвина с Урфином, но ряд принятых ими решений как специально указывал на намерение как можно дальше оттянуть сдачу проекта. Касается это в основном реализации. Самое эпичное, это пожалуй прямое указание сделать все подключения к ардуине механическими, это те стальные штыри 40х2.54 в пластмасске. Зачем это было сделано, когда пайка к плате надёжнее, непонятно. Напоминаю, паялась витая пара. Которая вообще-то жёсткая и из разъёма может выскочить. Которую не припаяешь ко штырю на тяп-ляп, иначе отвалится, обязательна паяльная кислота. Которую затем в месте пайки надо закрыть термоусадкой, мало ли что.
Ранее все, ну или почти все устройства располагались вместе с разъёмами и оптопарами на кросс-плате. Это была самая большая плата из когда-либо изготовленных мной, её размер 305х405 мм. К сожалению, фольгировка была китайская, а потому слой фольги — всего лишь 18 мкм, и лудить её было просто адским занятием. Из-за огромных размеров любые переделки требовали поднимать её полностью, потому что всего там было больше 40 разъёмов, в каждом из которых минимум три провода, и отключать их все чтобы снять — лучше откусить себе голову сразу. Паять что-либо там было дико неудобно, т. к. плата при этом находилась над паяльником. К тому же, несмотря на все выверенные разводки, в разъёмах всё равно были допущены ошибки. Минус месяц, и от этой кросс-платы в конечном итоге отказались, хотя подключать к ней исполнители с датчиками было удобнее. Это второе по неудачности решение, первым были и остаются зелёные светодиоды в ленте, имитирующей свет пламени.
Знай мы сразу, что логичнее было расположить всю логику в непосредственной близости от роутера/компьютера, и тащить только провода к конечным устройствам, что не стоило пытаться предусмотреть контроллеры на местах — можно было бы закончить работу гораздо раньше. Однако опыта у нас не было и скорее всего ориентированность на процесс — нечто логично вытекающее из этого. Я этот взгляд не разделяю и считаю что все перепробованные варианты так или иначе были в плюс, т. к. выявили много неудачных решений. Если мне впредь влом будет заниматься escape room — наш опыт будет полезен ещё кому-то из тех, кто читает эту статью.
С одной стороны, какого-либо права вообще рассуждать на эту тему у меня нет: вражеский трон наши доламывают уже без меня. Но меня конкретно напрягали некоторые их решения, идущие вразрез со здравым смыслом и минимизацией затрат. Если наняли меня для принятия каких-то решений — не надо спорить и сомневаться. Если я говорю, что сигнал с динамика одного усилителя подавать на вход другого нельзя, значит у меня есть основания. Если я говорю, что зона чтения RFId недостаточна, значит у меня было время проверить, я ничего не говорю с потолка.
Человек, на которого была свалена моя работа
На месяце так восьмом к нашему проекту присоединился ещё один персонаж, которого мы назовём Железный Дровосек. У него в распоряжении были некоторые промышленные датчики, и часть устройств претерпело изменения как в конструкции, так и в логике. К тому времени мне уже начинало основательно давать, и его вмешательство, в общем-то, было мною потребовано. Не работало что-то явно рабочее, те же 6 инфракрасных периметров, выполняющих функцию датчика присутствия. С ним, в отличие от Урфина и Гудвина, по крайней мере можно было вести разговоры, ибо он отличал затвор от сопротивления, те же двое меня иногда побуждали вырвать им все зубы, один за другим, без анестезии. Железный Дровосек с ходу предложил несколько исправлений, которые могли повлиять на надёжность, но мало что из этого дало результаты. Тем не менее, совсем недавно, именно им поднимался вопрос о том, чтобы использовать в предметах код IRRemote. То есть эта вещь уже была полностью отлаженной, и всё равно у них что-то там случилось. Урфин полез разбирать один из них и устроил КЗ, пришлось менять транзистор. Хотя, это как раз тот момент, в который не следовало бы лишний раз лезть.
Уникальная разработка Железного Дровосека — датчик угла, он был нужен для, скажем, руля с педалями. Чтобы определить, куда его крутят, первоначально там стоял энкодер KY040 с контроллером, альфа-версия даже имела триггеры шмитта и счётчик из схемы PighiXXX, подавляющей дребезг и преобразующей непонятно что фазово сдвинутое в сигналы step/dir. Но вменяемой работы добиться от него не удалось, потом он начал ошибаться, потом вовсе рассыпался, и так было принято решение заменить его диском с дыркой, и двумя фотопрерывателями, состоящими из древнего советского фотодиода ФД265 с компаратором, и белых светодиодов. При повороте диска дырка оказывалась под светодиодами, на компараторах получался ноль, порядок, в котором нули приходили с двух компараторов, позволял оценить направление и примерно положение. Не то что энкодер, но и прерываний не требует, а значит можно подключать по длинным проводам. Длинным — это значит более двух метров. Да ладно, будем честны — к KY040 запросто ставятся оптопары, встречно-параллельный диод, керамика 0.1 мкФ, и получается нормальный энкодер, который можно хоть за сто метров подключать. Тем более что они россыпью валялись в пакетике. Но осадочек остался, связываться уже не хотелось, да и код был уже переписан и работал точнее. Возникшие впоследствии глюки, скорее всего, были связаны с неисправностью в линии, с какими-то призрачными сигналами которые наводились, но в конечном итоге он работал. Единственным его недостатком было то, что работал он медленно, и при больших оборотах мог что-то пропустить (напоминаю, цикл опроса находился всё там же, в центральном контроллере, который заодно обслуживал и HTTP-запросы от панели управления). Цикл опроса, с ещё кое-какими датчиками, был переселён в pro mini, которая отдавала информацию основному контроллеру через Serial0. Как же было увлекательно гадать, почему оно не работало на Serial1! Но тем не менее, речь здесь не об этом. Датчик угла имел какие-то механические дефекты, и Железный Дровосек заменил его комплексом из чего-то, что определяет движение вообще (двигатель? энкодер? но какая нам разница?), и двух датчиков Холла, выясняющих куда именно происходит движение. Так на свет появилась новая, уже третья версия кода, определяющего число оборотов.
Кроме переделки некоторых датчиков, он занимается оставшейся аппаратной адаптацией проекта. Я не приписываю ему каких-то особых заслуг, но золото за крипа достанется тому, чей удар — последний. Проект завершит этот человек, мне же достанутся лавры сволочи, которая забила на людей, нуждающихся в моей помощи, толстенную сваю. С одной стороны мой поступок — свинство, и я это признаю. С другой стороны, мне были предоставлены определённые условия — когда меня эти условия перестали устраивать, моя богоподобная персона перестала в этих условиях находиться. Всё. А свинство, не свинство — мне как-то индифферентно. Железному Дровосеку же я выражаю свою благодарность — он взялся за то, на что у меня сил уже не осталось.
Работа над ошибками
Первый и главный шаг к прозрачному и безглючному управлению — плата из Космической одиссеи. Эта вещь необходима, она позволяет решить разом кучу проблем:
- Если у исполнителя нет мощных потребителей, устройство целиком (саму плату и скажем, пару метров ленты, подключенной к плате) можно питать посредством PoE.
- У вас не будет коллизий в трафике. У вас вообще не будет систематически повторяющихся запросов, а значит в десятки раз меньшая вероятность положить сеть, проворонить ответ или что-нибудь ещё. Всё управление можно будет сделать полностью асинхронным — что-то понадобилось от исполнителя — послали запрос — выполнилось. Всё, повторять запрос уже не нужно.
- У вас будет доступ к информации об исполнителе вообще. Датчики? Да хоть десяток, цепляем через мультиплексор/сдвиговый регистр и видим каждый, на каком и сколько. Двигатель? Можно не только включать, но и убедиться что он реально включился, датчиком тока.
Типичный пример «как не надо» — делаем имитацию пламени на восьмой меге, дёшево, элементарно — чего там предусматривать? random() да и только. Как бы не так.
Уверяю, рассуждая таким макаром, вы окажетесь в точно такой же ситуации. Потом вам понадобится поменять цвет пламени, потом плавно гасить/зажигать, потом чёрта с рогами, а проводов управления нет, от слова совсем. И радио не повесишь, потому что SPI занята. Или ещё что-то. И как хочешь — так и крутись, но роди решение.
Поэтому самое главное — обеспечить прямой доступ исполнителей к компьютеру и наоборот. Может быть через Modbus. Может быть DMX. Но чем роднее интерфейс, тем меньше геморроя будет в дальнейшем. Самый родной — TCP/IP. Советую не злоупотреблять ESP8266, даже если очень хочется. Есть возможность проложить кабель — используйте кабель.
Далее, возвращаемся к правилам. Датчики прорабатываем от и до, чтобы текущее состояние оценивалось одним взглядом, чтобы всё работало чётко и однозначно. Если датчик дискретный (ноль или единица), на нём не должен появляться уровень посередине. Скрутки пропаиваем или вообще не делаем, разводя всё на шилдах/платах. На проводах не экономим. Полярность не путаем. Точно знаем: если что-то забыть, включить неправильно, сломать способен только дурак — да, именно так, такой дурак найдётся. Включит, забудет, поломает. Поэтому защита, защита и ещё тонны защиты.
Даже себя следует считать дураком. Раньше меня устраивал обычный ардуинный ISP-разъём, но однажды наступил день, когда в моём программаторе умер порт MOSI/D12. Программатор, ясное дело, у меня другой, но и разъём другой — однорядный. И в нём семь проводов, а не шесть. Сначала плюс, потом пустой, потом минус и все остальные. Чтобы наоборот его воткнуть вообще было невозможно. Вы скажете — а где резисторы 100-300 Ом на каждый из этих проводов? И работало бы со стандартным, и вверх тормашками ничего бы не сгорело. Совершенно верно, и резисторы у меня теперь тоже есть. Но разъём симметричным я не стану делать уже никогда.
Ещё один момент — датчики тока. Они дёшевы, это один мощный низкоомный резистор, один подстроечный резистор и половина LM393. Зато будет видно, что дверь уже открылась, но тянущий её двигатель по-прежнему включен, и его обмоткам это не нравится. Рекомендую их ставить на всё, что вообще можно дистанционно включать. На светодиоды/ленту не обязательно, но если светодиодов реально много — то желательно. Куча ленты нагружает источник питания так же хорошо, как и двигатели.
Если из watchdog не требуется сделать дополнительный таймер, используем его по назначению. Чтобы любое повисшее устройство максимум через 4 секунды уже было не повисшим. Кстати, ничто, абсолютно никакая информация, определяющая режим работы квеста (недоступность открывания дверей, закрытость/открытость замков и т. п., невосприимчивость датчиков) не должна храниться в оперативной памяти. Исходить нужно из предположения, что повиснуть может абсолютно всё, в абсолютно любой момент. Это никак не должно искажать/нарушать логику задач и решений, возлагать ответственность за состояние системы возможно только на одно устройство — компьютер оператора, чтобы у него всегда была полная картина состояний перед глазами.
Если собираете самопал, то вот основное:
Керамический конденсатор 0.1 мкФ должен быть у каждого корпуса. У каждого сдвигового регистра, у каждого компаратора. Тем более у микроконтроллера. Также, такой конденсатор, плюс электролит мкФ так 100 следует напаивать на nRF24L01+, ESP8266, ENC28J60. Прямо на штыри платы, или на проводах в непосредственной близости от платы. Земля по свободной площади платы — это не лишннее. Тонер дешёвый, а травится быстрее. Плюс, гипотетически что-нибудь экранирует на плате. Кварц надо везде. Без кварца можно сделать ардуину на atmega8, при условии что она не считает интервалы точнее сотен микросекунд. Atmega8 дешевле Attiny85/2313.
Если есть выбор между аккумуляторами LiIon и NiMH — литий проще заряжать: платами на TP4056 можно брать и обмазываться, как говаривал Банан, специальных же контроллеров для никеля всё никак не видно.
Если в системе есть исполнители, которые не выносят длительного включения (замки, соленоиды, нагреватели, возможно некоторые мощные двигатели, двигатели с конечным ходом тяги, которые могут что-нибудь случайно поломать/порвать), слпедует для них дополнительно делать защиту от длительного включения. Например, если надолго включить актуатор автомобильного замка, обмотка двигателя будет выделять тепло, двигатель раскалится и расплавит редуктор, так как он пластмассовый. Все мы знаем, что секунды ему для открытия/закрытия вполне достаточно. Просто делаем формирователь секундного импульса, всё что нам надо — это 555 и кучка обвязки. Или RC-цепочка с КМОП-триггером.
Загрузчик — по общему правилу — зло. Пишите через ISP, или хотя-бы поменяйте стандартный на optiboot.
Arduino ВНЕЗАПНО способна быть MIDI-устройством. Если вам нужен звук в компьютере, то лучше бы ему возникать в VST-проигрывателе или инструменте, а не в обозревателе из под Javascript. Это так, если локальный звук невозможен/не устраивает. VST плугов и хостов сейчас до чёрта, в т. ч. бесплатных.
Психологический аспект
Умнейшие подрядчики в нашем мире — шлюхи. С них можно и нужно брать пример: они чётко и ясно говорят клиенту — чего он может делать, а чего они будут избегать любым путём. Моей промашкой было участие в проекте не на конкретной должности, а на нескольких — это привело к ненужной ответственности и неоптимальному расходу времени. Например, две недели было посвящено одной вещи, которая в сути своей, являлась просто кнопкой/выключателем/парой контактов. Хотя можно было просто открыть рот и сказать: «Как хотите сделайте, мне нужно чтобы при воздействии на эту вещь один провод замкнулся с другим». А я отвечаю за программу и за то, какой из этих проводов будет землёй, а какой цифровым входом.
Четыре недели было посвящено настройкам в цвете свечения ленты, и то результат далёк от идеала. И этим невозможно управлять. Можно было просто сделать радиоприёмник/провод, и вывести полностью цвет в компьютер, ну или хотя-бы некоторые коэффициенты. Или брутально, предусмотреть область в EEPROM, которую можно править внешней приблудой с экраном 1602 и кнопкой, ибо изготовить такую приблуду не составило бы никакого труда.
Три недели вылавливали косяк в механике дверей, хотя это мои челики прощёлкали, у них отлимолась пара-тройка роликов. Ну это так, ничего особенного. Назовём эту претензию обычным нытьём.
И тэ дэ и тэ пэ. Эти люди пытались сдвинуть с места 100-килограммовый груз 40-ваттным двигателем. Сорокаваттным, Карл. Эти люди систематически задавали мне вопрос, почему не сделать так, абсолютно не вникая в тонкости варианта сяк. Да, некоторые их решения были толковыми. Но некоторые заставляли меня люто гореть и гадать — зачем гавкать самому, после того как куплена собака?
В общем, в этом аспекте выделить можно только два принципа:
- Знайте свою квалификацию и настаивайте на ней. Считаете что воздух можно качать компрессором? Пусть не лезут со своей аквариумной помпой.
- Обозначьте правила. Только с резинкой, только в классической позе, ну вы понимаете, надеюсь. Извините уж за пошлость, но здесь других метафор не подобрать.
На сём, я думаю, мною было изложено достаточно информации. Думайте, запоминайте, делитесь опытом. Мой был не лучшим, но он ценен, и тем остальным будет проще, чем больше опыта мы передадим в комментариях. Так что вперёд.
FYI: статья лишена иллюстраций, т. к. я не вижу смысла рисовать два ISP разъёма, один — стандартный, другой — мой, и подписывать правильно/неправильно. Все решения, описанные выше, легко гуглятся, однако если таковое нужно, отпишите в комментариях. Опции правки доступны, и все интересующие иллюстрации могут быть добавлены.
Автор: stdamit