Интеграция 3CX с amoCRM

image

Введение

3CX предлагает интеграцию с популярной CRM системой amoCRM непосредственно “из коробки” и совершенно бесплатно! Вам не нужно использовать платные решения от сторонних разработчиков. Официальная CRM интеграция всегда соответствует последней версии API 3CX и периодически тестируется для корректной работы с amoCRM.

Интеграция позволяет открыть карточку контакта или компании при входящем вызове, либо создать новый контакт в интерфейсе amoCRM. Также ведется учет вызовов в amoCRM, позволяя добавить заметки к каждому разговору с клиентом.

Для успешной интеграции вам потребуются:

  • 3CX v15 PRO (Standart не поддерживается) с последними обновлениями
  • Установленный на ПК пользователя клиент 3CX Client for Windows
  • Учетная запись amoCRM в домене amocrm.com (не .ru)

    Настройка интеграции на стороне сервера 3CX

    Для установки плагина в консоли управления amoCRM перейдите в раздел Обновления > Модули CRM интеграции и скачайте плагин.

    image

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

    image

    Настройка интеграции на стороне клиента 3CX

    В правом нижнем углу интерфейса нажмите на иконку image, чтобы перейти в параметры софтфона, а затем в Дополнительные параметры > Интеграция

    image

    Раздел General

    В разделе General указываются общие параметры интеграции.

    image

    • Open contact — укажите, когда открывать карточку контакта: во время вызова, после ответа или не открывать вообще.
    • Only show CRM contact details… — укажите, при какой длине номера открывать карточку контакта. Например, вы можете указать длину номера большую 3, чтобы карточка не открывалась при вызове от внутренних пользователей.
    • Enable Journaling – если включить эту опцию, после завершения разговора с amoCRM будет создана заметка, привязанная к этому вызову и соответствующему контакту.
    • Create new contact… – если невозможно найти контакт или компанию, плагин создаст новый потенциальный контакт (лид).
    • Maximum digit lenght… – Caller ID может передаваться от оператора как с различными префиксами (междугородный, международный), так и без них. Кроме того, в amoCRM номера клиентов могут храниться в различных форматах (например, только городской номер, либо полный номер в формате E.164). Чтобы распознать клиента, рекомендуется проверять соответствие Caller ID с номером клиента по последним 7 цифрам номера, т.к. в большинстве случаев локальные (городские) номера имею длину 7 цифр. Если установить соответствие по меньшему количеству цифр, возможны “ложные срабатывания” при определении клиентов с одинаковыми последними цифрами номера. Если установить соответствие по большему количеству цифр, система может не определять уже имеющихся клиентов (их номер будет слишком короткий).

    Раздел amoCRM

    В разделе amoCRM указываются параметры подключения пользователя к порталу amoCRM и справочники, по которым плагин будет искать соответствие CallerID.

    image

    • E-mail пользователя в amoCRM
    • API Key amoCRM. Этот ключ можно скопировать в интерфейсе amoCRM в разделе Настройки > API > Ваш ключ API.
    • Domain – ваш поддомен (адрес) amoCRM. По умолчанию, система присваивает поддомен isamo (полный путь https://isamo.amocrm.com), но его можно поменять в разделе Общие настройки > Адрес.
    • Lookup Order – укажите приоритет поиска контакта в справочниках. Как видно на скриншоте, плагин сперва ищет соответствие Caller ID в справочнике Contacts, а потом в Companies.
    • Default Browser и Select Browser – открывать карточку контакта в браузере, установленном в системе по умолчанию, либо в определенном браузере.

    image

    После сохранения настроек подключения, перезапустите клиент 3CX Client for Windows.

    На этом настройка интеграции завершена. Напоминаем, что в данный момент интеграция работает только для домена amocrm.com!

ссылка на оригинал статьи https://habrahabr.ru/post/319104/

Как дают названия сиквелам

image

Хватит! Довольно! Горшочек, не вари!

Позвольте мне представить мою вступительную речь в виде сценария.

Сценарий

[Студия новостной передачи. Молодой ведущий сидит за столом, заваленным Nintendo Amiibo и игрушками-штурмовиками из (новых) Star Wars, улыбается и воодушевлённо говорит, глядя в камеру]

Ведущий: «… и другие новости: на этой неделе выпущена Battlefield 1, первая игра новой франшизы Battlefield. Непривычно видеть цифру 1 в названии первого продукта. Она демонстрирует уверенность Dice и EA в том, что игра даст начало новой серии…»

[Ведущий прерывается и прикладывает палец к уху]

Ведущий: «… секундочку. Простите, мой продюсер уточняет информацию».

[Неразборчивое бормотание]

Ведущий: «…ПЯТНАДЦАТАЯ игра Battlefield?!?! И это БЕЗ дополнений?!»

[Ведущий бросает нервный взгляд в камеру, отворачивается, прижимает руку к уху и начинает тихо переговариваться с продюсером, находящимся за кадром]

Ведущий: «Это что, шутка? Серьёзно, хватит. Вы просто решили посмеяться над новичком, или… вы точно шутите… значит, Battlefield Hardline была из той же сер… а Battlefield 4 на самом деле была Battlefield 13? Боже ты… Сейчас вы наверно скажете, что Assassin’s Creed 4 была… шестой?..»

«Так, подождите, что мне говорить о Battlefield 1?..»

Ведущий (теперь громким шёпотом): «… ПРОСТО ПОТОМУ ЧТО ДЕЛО ПРОИСХОДИТ ВО ВРЕМЯ ПЕРВОЙ МИРОВОЙ ВОЙНЫ?! ТУПЕЕ ЭТОГО НИЧЕГО НЕ СЛЫШАЛ!»

«Ладно, хорошо. Да, ладно. Я понял».

[Ведущий опускает руку, медленно поворачивается к камере и натягивает на лицо «телевизионную улыбку»]

Ведущий: «Кхм… простите меня. Battlefield 1 вышла на этой неделе и была тепло принята критиками. Обозреватели назвали её «лучшей Battlefield» со времён…»

[На долю секунды ведущий теряется и с трудом продолжает]

Anchor: «…Bad Company 2».

«И, наконец, только что вышел новый DLC для Doom, нового шутера id Software и Bethesda, который захватил мир в первой половине года…»

[Ведущий останавливается, он снова слушает продюсера и улыбка спадает с его лица. Он опять отворачивается от камеры.]

Ведущий: «… не нового?.. 1993 год?.. Но наверно за 20 лет все уже забыли одну-единственную игру с фиговой графикой… ЧЕТВЁРТЫЙ DOOM?!.. Почему они тогда просто не назвали его…?.. кто такие «два Джона»?.. «Quake»? Нет, Quake выходит в следующем году, я точно знаю!.. нет… нет… ладно, забудьте…»

[Ведущий встаёт, стремясь выйти из кадра и снимая микрофон. Микрофон трётся об одежду, издавая резкие звуки]

Ведущий (его слышно хуже): «… Нет, я ухожу! Забудьте! Это какое-то посмешище! Пока эта индустрия не повзрослеет, как можно воспринимать её серьёзно?»

[Освободившись от микрофона, ведущий окончательно выходит из кадра и двигается к выходу. Его слышно всё хуже]

Ведущий: Попробую вернуться на интернатуру в Fox. По крайней мере, в названии Fant4stic есть правильная цифра.

[Слышно, как кто-то ему отвечает]

Ведущий: «Только третья часть?!»

[Постепенно затихающие громкие ругательства, обрывающееся хлопком двери]

[Конец сцены]

Статья

Потрясающе смешно, правда?

Есть юмор в том, во что превратились со временем названия игр. Но в этом есть и опасность для сохранности игр и для исторических исследований тех, кто придёт после нас, или даже всего через двадцать лет. Большинство людей не задумывается о завтрашних проблемах (так мы пришли к тому миру, в котором находимся сейчас), поэтому я сосредоточусь на юморе. Но всё-таки постарайтесь представить, как всё это будет выглядеть для людей из будущего. Будут ли они считать наше время золотой эрой создания игр, или его будут воспринимать как время ненасытных потребителей, которые, похоже, даже не понимают, во что они играют, и не хотят в этом разбираться? И на самом ли деле все настолько глупы и неразборчивы, как это, наверно, кажется большим участникам рынка?

Пояснение

Я хочу уточнить, что ничего не имею против упомянутых здесь игр. Многие из них просто отличные! Мне не нравится только то, как дают названия этим играм, а больше проблем создают именно успешные серии, потому что в них много игр.

Надеюсь, из моего «сценария» вы поняли проблему, которую я хочу подчеркнуть. Я мог сказать «принципы придумывания названий никто не контролирует», но на самом деле, похоже на то, что никаких принципов не существует. Никто в игровой индустрии не заходит дальше рассуждений «отдел маркетинга считает, что на этой неделе целевой аудитории нравится такая-то цифра».

А как дела у кино?

Игровую и киноиндустрию постоянно сравнивают, и мне это совсем не нравится. Но сегодня я сравню их, потому что в них есть множество параллелей и уроков, которые нужно усвоить.

В киноиндустрии совершенно точно используется более зрелый подход к названиям в случаях «долгоиграющих» франшиз и «перезагрузок» старых фильмов. Конечно, проблема (если вы действительно считаете это проблемой) постоянно возникающих «перезагрузок» в обеих индустриях развлечений первой появилась именно в кинематографе. Но, к его чести, он обращается с этой проблемой гораздо более аккуратно. За исключением «Робокопа» (2014), в большинстве «перезагрузок» используется для уточнения изменённое название или подзаголовок (Batman Begins, The Amazing Spiderman, The Incredible Hulk — да, похоже, «перезагрузки» происходят в основном у супергеройских фильмов и боевиков).

При нумеровании сиквелов фильмов создатели избегают этой проблемы и теперь уже редко добавляют цифры в конце. Вместо них они предпочитают подзаголовки. В качестве хорошего примера можно взять Marvel: взаимно переплетённые сюжеты фильмов могут быть достаточно сложными, и иногда даже сложно сказать, кто в них главный герой. Например, «Первый Мститель: Противостояние» был «Мстителями 3» или «Капитаном Америка 3»? Или «Противостоянием 1»? Так что игнорируйте цифры и давайте названия. Это работает.

Поясню: я не хочу сказать, что такие принципы имеют больше смысла или более целостны (в «Челюстях» сначала использовались цифры, потом цифры или названия, потом подзаголовки: Jaws, Jaws 2, Jaws 3-D, Jaws: The Revenge). Но я утверждаю, что, за заметным исключением «Робокопа» (и, возможно, некоторых других фильмов, которые я не могу вспомнить), франшизы редко настолько перепутаны, что невозможно понять, о каком именно фильме идёт речь. И я не могу вспомнить примеров того, когда «Название-фильма 3» на самом деле не третья часть, или хотя бы не третья в текущей «перезагрузке».

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

Примечание: РЕМЕЙКИ фильмов часто носят то же название, что и оригиналы, но обычно они являются переделками классических 40-50-летних картин («Поезд на Юму», «101 далматинец», «Алиса в Стране чудес»). ПЕРЕЗАГРУЗКИ обычно следуют за несколькими сиквелами, но начинают новую серию сиквелов, связанных только друг с другом, а не со старыми сериями. Например, «Star Trek» (2009). Оригинальный фильм 1979 года назывался «Star Trek: The Motion Picture». Создатели не использовали то же название, хотя, по-моему, не помешало бы добавить подзаголовок к фильму 2009 года.

А как дела у игр?

Мне видится, что существует два подхода, каждый из которых всё равно в разной степени «мутит воду». (В кино есть ещё и третий: связанные серией фильмы имеют разное название, например «Молчание ягнят» и «Ганнибал»). Они создают проблемы при поиске в Интернете или просто при общении и попытках объяснить, какую же игру вы на самом деле имеете в виду.

Разбрасывание цифрами

Я никогда не видел, чтобы такое делали в фильмах, но игровые серии, похоже, настолько стыдятся своего возраста, что постоянно жонглируют цифрами. Тому могут быть причины: например, создатели хотят скрыть количество игр (чтобы игроки не «пресытились» ими), разделить разные сюжетные линии (серия Command & Conquer: «Tiberium» и Command & Conquer: Red Alert 1-3), или отметить выпуски на разных устройствах. Но всё равно, такая практика очень запутывает.

Фильмы, отбросившие цифровые окончания, обычно сохраняют эту тенденцию. После шести «цифровых» «Полицейских академий» седьмой просто дали подзаголовок «Миссия в Москве». У «Супермена» не было не было продолжений с цифрами после четвёртой части, несмотря на вышедший позже сиквел и ещё более позднюю «перезагрузку»

Grand Theft Auto: Vice City стала четвёртой GTA, и ещё до GTA IV (которая была на ДВЕ игры позже) я для краткости называл Vice City «GTA 4». GTA 5 на самом деле седьмая, и так далее.

Assassin’s Creed III была пятой игрой в серии.

Недавняя Gears of War 4 тоже стала пятой GoW.

Если вы читали мои последние статьи, то знаете, как я настроен против названия Battlefield 1. Сегодня я не включу его в систему.

Мой сатирический «сценарий» уже затрагивал Battlefield, возможно, самого грубого нарушителя правил. Уже через три игры после начала серии можно начинать путаться: Battlefield 1942, затем Battlefield Vietnam, и, наконец, начался бардак с третьей игрой Battlefield 2. С того момента цифры не имели смысла, и это было заметно (для меня, во всяком случае) по тому, что никто и ухом не повёл, когда новую игру назвали Battlefield 1. Очень нелепо называть новую игру «1» (насколько я знаю, такое случилось впервые в мире). Хуже всего осознавать, что в этой игре разработчики вернулись к корням, отойдя от современного или фантастического антуражей, и поэтому имели возможность вернуть оригинальную систему названий (Battlefield 1942) и назвать эту игру, например, "Battlefield 1916" (или выбрать любой год из интервала 1914-1918; я выбрал 1916, потому что в последнем трейлере сделан упор на этот год, к тому же год выпуска 2016 — хорошая круглая дата). Мне не важно, что говорят остальные, маркетологи определённо здесь промахнулись. У меня есть степень по маркетингу, поэтому я могу сказать это, имея хоть какой-то авторитет:

Если они по каким-то причинам были настроены сильно против года в названии, то Battlefield: The Great War всё равно меньше бы походило на шутку, чем Battlefield 1. Ну ладно, я высказался. Отличная игра, отвратное название, поехали дальше…

Проблема этой тенденции в том, что единственный способ исправить ситуацию для всех вышеупомянутых игр — дать следующей игре правильный номер. Например, «Battlefield 16», на что они никогда не пойдут, особенно сразу после 1 (в их случае).

Более предпочтительный выход — если уж начали, продолжать всегда использовать подзаголовки, но в этом случае продажи обвалятся, потому что менее упорные фанаты могут пропустить игру с названием, даже не поняв этого

Как бы всё это ни было смехотворно, основная проблема для поиска заключается в другом. На самом деле, поиск по Википедии быстро покажет вам, что вы забыли о существовании Assassin’s Creed: Brotherhood, если вы действительно хотите разобраться. Я упомянул преимущества нечестности, поэтому эта часть оказалась в самом начале раздела.

Но есть проблема и покрупнее.

Названия «перезагрузок» совпадают с оригинальными

Виновными здесь можно назвать Doom, Star Wars: Battlefront, Battlezone и игру, ставшую причиной этой статьи — Prey.

На E3 2016 года мы видели тизер новой игры под названием Prey. Тогда я подумал: «люди в каком-то странном восторге от неё. Что они знают такого, чего не знаю я? Вроде название мне знакомо. Не было ли игры с похожим названием всего несколько лет назад?»

Десять лет назад. Прошло всего десять лет без сиквелов, и они выпускают игру с точно таким же названием. Как её должны обсуждать фанаты? "Prey ужасна, мне гораздо больше нравится Prey". Это какое-то посмешище! Даже если есть важная сюжетная причина (например, параллельные вселенные или что-то подобное), дающая хорошее обоснование выбора того же имени (чтобы была хоть какая-то аргументация, допустим, преимущества были значительными), то всё равно разработчикам нужно заботиться о маркетинге и возможности поиска в Интернете. Новички не будут так благосклонны к вашему подходу «мы сохранили название из-за персонажа».

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

И мы плавно переходим к Star Wars: Battlefront, которая на самом деле является Battlefront 3. Тот факт, что она разрабатывалась другой студией, не отменяет факта покупки и прохождения мной двух предыдущих игр Battlefront, одна из которых называлась Star Wars: Battlefront. Когда была объявлена «перезагрузка», я попытался загуглить название оригинальной игры, чтобы узнать год её выпуска, и она показалась мне достаточно свежей, чтобы пытаться скрыть её, как это можно сделать с 50-летним фильмом.

2004 год! *вопль* «Ей было всего 12 лет, у неё впереди была вся жизнь». Звучит, конечно, смешно, но тут нужно сделать замечание. Предполагается, что любую игру с внятным названием можно будет найти в Интернете в течение нескольких десятилетий. В то время, когда сохранение цифрового искусства становится всё более важной темой, намеренное сокрытие существования любой выпущенной игры выглядит безответственно и жестоко.

Кстати, чтобы найти дату выпуска, мне пришлось искать Battlefront 2 и начинать уже с неё. Если бы я не знал о существовании сиквела, скажем, мне было бы 10 лет, а не 29, эти две более старые игры для меня бы не существовали, если бы кто-нибудь не сказал мне о них.

А теперь рассмотрим ещё один случай: игра Battlezone для Playstation VR — это «перезагрузка» оригинальной Battlezone 1980 года для Atari, а не Battlezone 1998 года или её повторного выпуска в 2016 году «Battlezone 1998 Redux», и не продолжение Battlezone II: Combat Commander 1999 года. Видите, как всё усложняется? И с исторической точки зрения эти игры были очень интересными! Часто недооцененными, но вносившими новизну во время своего выпуска. Это примеры игр, которые стоит сохранить и исследовать в будущем. Почему новая версия не может просто называться Battlezone VR? Это выше моего разумения.

Вы, наверно, уже поняли мою точку зрения. Doom (2016 год) должна называться Doom 4 или даже «Doom 2016», но её так не назвали. Простите, но Doom — это название уже существующей игры, у которой всё ещё есть тысячи игроков. Уверен, что через пять лет в классический Doom будут играть больше людей, чем в новый Doom, как бы он ни был хорош. Нельзя подминать под себя старые игры и притворяться, что их не было. И это довольно иронично, ведь версия 2016 года выглядит признанием в любви к оригиналу. Я очень сожалею, что авторы просто «скопипастили» название. Имитация — лучшая форма лести, но нельзя доходить до того, чтобы влазить в кожу своего кумира.

В заключение: что я пропустил?

Тенденция присваивания старых названий новым играм определённо увеличивается, даже если между играми прошло всего 10 лет, и я вижу только этом только негативные последствия. Неужели отбрасывание цифр — это просто мода?

Мне кажется это отвратительным. Выглядит так, как будто мы настолько непостоянны, что забудем об оригиналах, или больше будем ценить новые версии просто потому, что в их названии нет цифры 4 или 5. Вы можете возразить, что новые игроки охотнее купят игру, если не будут жалеть о пропущенных пяти частях, но скрывать прошлое игры только по этой причине очень цинично! Похоже, что эту теорию просто выдумали получающие слишком большую зарплату маркетологи, а потом сами убедили себя в её правильности, и она не взята из данных о продажах. В конце концов, я купил Assassin’s Creed IV, Civilization V, Skyrim, The Witcher 3 и Fallout 4, не поиграв в предыдущие части. И я знаю многих, сделавших то же самое.

Жонглированием цифрами занимаются крупнейшие компании с огромными отделами маркетинга. В этом должна быть какая-то логика. Не похоже, что кто-то спонтанно убедил их в этом. Я уверен, что всему этому есть логичное объяснение, но не могу найти его.

Какой бы ни была логика или её отсутствие, она мешает сохранению и возможности поиска игр. Мне могут ответить: «ну и ладно, старые игры не продаются хорошо. Мне нужно получать ежемесячную премию. Меня не волнует история». Что я могу сказать в ответ?

Новый игрок покупает Gears of War 4. Игра ему нравится. Он хочет поиграть в во все предыдущие игры серии Gears. Логично, что это 1, 2 и 3. Вы получили ещё три дополнительные продажи (хотя и по более низкой цене). Отлично. А как насчёт Judgment? Её не купят, правда? Почему? Потому что не было понятно, что она существует, а ведь это самая последняя и самая дорогая из предыдущих игр. И вам не удалось её продать.

Так какой будет вывод? Боюсь, я могу только посоветовать быть честными с цифрами или вообще не использовать их. И никогда не использовать старые названия. Смотрите, если вы используете название, похожее на чьё-то ещё, на вас подадут в суд. Несколько лет назад Bethesda инициировала иск против Mojang, когда та объявила о выпуске Scrolls, потому что название слишком походило на The Elder Scrolls. Но вы позволяете себе такое, просто потому что это ваша собственность? С точки зрения закона это нормально, но как насчёт покупателей?

Я процитирую абзац о товарных знаках с веб-сайта Ведомства по патентам и товарным знакам США.

Что такое «нарушение прав на товарный знак»?
Нарушение прав на товарный знак — это несанкционированное использование товарного знака или знака обслуживания на товары и (или) услуги, или в связи с ними, таким образом, что это может вызвать путаницу, обман или заблуждение об источнике товаров и (или) услуг.

«Несанкционированное» к нашему случаю не относится, но об остальном стоит задуматься.
ссылка на оригинал статьи https://geektimes.ru/post/284266/

Проектирование импульсного источника питания с активным ККМ. Эпизод I

Предисловие

В своей предыдущей статье я говорил, что продолжу рассказ о работе с датчиками тока на эффекте Холла. С того момента прошло не мало времени, выход продолжения затянулся, да и писать «скучную теорию» я не любитель, поэтому ждал практической задачи.
Еще одной причиной отсутствия статей была моя работа в одной «современной успешной IT-hardware-компании», сейчас наконец-то я ее покинул и окончательно пересел на фриланс, так что время для статьи появилось))
Недавно ко мне обратился мой старый наставник и просто очень хороший человек. Естественно я не мог отказать в помощи, а оказалось все достаточно просто — меня попросили сделать блок питания для КВ трансивера FT-450, который будет более стабильный в работе, особенно при пониженном входном напряжении, чем уже имеющийся Mean Well. Прошу заметить, я не говорю о том, что Mean Well плохая фирма, просто в данном случае нагрузка достаточно специфическая, а так продукция у них вполне себе хорошая.

Диагноз примерно такой:


— Заявлен выходной ток в 40А, на деле при потреблением в 30-35А (на передаче) блок уходит в защиту;
— Наблюдается сильный нагрев при длительной нагрузке;
— Совсем становится плохо, когда использует его на даче, где напряжение в сети 160-180В;
— Напряжение максимальное 13,2-13,4В, а хотелось бы 13,8-14В с возможностью подкрутить +-20%.

Особенностью данной статьи будет то, что проект продвигается вместе с ней. Я за него только засел и поэтому смогу рассказать обо всех этапах разработки: от ТЗ до готового прототипа. В таком формате статей с наскоку на гике я не нашел, обычно люди пишут уже проделав всю работу и забыв половину мелочей, которые часто несут в себе главный интерес. Так же эту статью я хочу написать доступным для новичков языком, поэтому местным гуру стоит чуточку проще относиться к «неакадемичности» моего слога.

Технические требования

Любой проект всегда начинается с технического задания и обсуждений. Обсуждения мы прошли, остается ТЗ. У меня проект не коммерческий, а так сказать open source, поэтому я не буду тратить большое количество времени и ограничусь перечнем технических требований.
Для чего это нужно? Те, кто работает в компаниях связанных с разработкой чего либо меня поймут — «без ТЗ проект не взлетает», но для людей не связанных с промышленной разработкой этот момент может быть не очевиден. Поэтому немного объясню…
В процессе разработки если вы не опираетесь на ТЗ, то с вероятностью около 100% уйдете от изначально желаемого результата. Например, вначале вы хотели получить 1000 Вт мощности блока питания, но не нашли трансформатор подходящий и поставили тот, что попался под руку. В результате железка стала на 700 Вт, а вы то планировали на 1000! Для любителя это не смертельно, он просто убьет кучу денег и времени, не получив результата. Для работодателя инженера же это финансовая катастрофа, просроченный проект, а для инженера часто просто пинок под зад на улицу. И таких нюансов будет море, по мимо трансформатора еще что-то не найдется, вам яблоко на голову упадет и вы решите добавить каких нибудь «светюлек» и так далее.
Как этого избежать? Именно для этого сумрачный советский гений придумал «ГОСТ 34. Разработка автоматизированной системы управления (АСУ)». Достаточно просто сделать как надо ТЗ по данному ГОСТу, которое займет 30-50 страниц и ваш проект на стадии идеи будет соответствовать конечному результату в виде железки, надо лишь идти по пунктам. Если написано «трансформатор на 1000 Вт», то вы ищите/добываете его именно на 1000Вт, а не на авось берет «чуть чуть поменьше». Я работал и в ВПК и в частных компаниях: первые молятся на адекватные ТЗ и тех. проекты, которые обычно выглядят как томик «Война и Мир», поэтому наши танки лучше всех. Вторые же забивают «на бестолковую порчу леса», поэтому гражданская электронная продукция на выходе в России в большинстве случаев — «гуано на ардуине».

И так, чтобы избежать «хлама» на выходе мы составим список технических требований, которыми должен обладать наш прототип. Пока он их не достиг — проект считается незавершенным. Вроде все просто.

Требования к импульсному блоку питания:

— Выходное напряжение с возможностью регулировки в пределах 10-15В DC;
— Входное напряжение сети: 160-255В AC;
— Ток вторичных цепей: 40А
— Наличие синфазного фильтра;
— Наличие корректора коэффициента мощности (ККМ);
— Косинус фи: не менее 0,9;
— Гальваническая развязка входа с выходом;
— Защита от КЗ во вторичной цепи;
— Время срабатывания защиты по току: не более 1 мс;
— Стабильность выходного напряжения: не хуже 0.1%;
— Температура силовых элементов устройства: не более 55 градусов при 100% нагрузке;
— Общий КПД устройства: не менее 90%;
— Наличие индикатора напряжения и тока.

Еще хотел бы отметить одну особенность проектируемого ИИП — он полностью аналоговый. Это было достаточно важным требованием, т.к. я последние годы в основном проектировал с использованием DSP процессоров в качестве управляющего «мозга», но это пугает «заказчика». Ибо на данный момент он проживает в 2500 км от меня и в случае поломки ремонт затянется на долго, поэтому необходимо сделать устройство с максимальной ремонтопригодностью. Заказчик человек опытный в аналоговой схемотехники и отремонтирует в случае проблем без каких либо пересылок, максимум придется позвонить да обсудить проблему.

Подытожим: когда я разработаю, изготовлю, а затем протестирую ИИП и получу в результате тестов ТТХ, которые как минимум не хуже описанных выше — можно будет считать, что проект успешен, блок можно отдавать владельцу, а самому радоваться еще одно успешной железке. Но это все далеко впереди…

Функциональная схема

Обычно я с начальством воевал на тему, что функциональные схемы для чайников и отказывался рисовать, но т.к. статья все таки предназначена для новичков в электронике и чтобы всем было интересно читать я все таки ее нарисую и распишу, что делает каждый блок. Да и при условии отсутствия полноценного ТЗ данная схема позволит мне не отклоняться в процессе работы от изначальной идеи.

image
Рисунок 1 — Функциональная схема ИИП

Теперь кратко пробегусь по каждому блоку, а более подробно данные решения разберем уже на этапе разработки схемотехники. И так сами модули:
1) Синфазный фильтр — он призван спасти сеть и бытовые приборы подключенные к ней от помех, которые генерирует наш блок питания. Не пугайтесь — любой импульсный блок питания их выдает, поэтому в 90% ИИП имеется фильтр синфазных помех. Так же он оберегает и наш блок от помех приходящих из сети. На эту тему недавно наткнулся на чью-то бакалаврскую работу, там достаточно понятно все расписано — статья. Автор диплома Куринков А.В., за что его сердечно поблагодарим, хоть один диплом бакалавра в этом мире станет полезен))

2) Дежурное питание «классическое» на микросхеме TOP227, схема скорее всего будет взята прямо из даташита с добавление гальванической развязки от сети через оптрон. Выход будет реализован в виде 2-х развязанных друг от друга обмоток с напряжением 15В и 1А каждая. Одна будет питать ШИМ контроллер корректора, вторая ШИМ контроллер полумоста.

3) Выпрямитель выполнен на диодном мосте. Изначально хотел применить синхронный на N-канальных Mosfet, но на таких напряжениях и при токе 3-4А это будет бесполезная трата ресурсов.

4) Активный корректор мощности — без него никуда как только речь идет о хорошем КПД, да и по требованиям законодательства применение ККМ обязательно. ККМ это по факту обычный бустерный преобразователь, который закроет 2 проблемы: низкое входное напряжение, т.к. на своем выходе он стабильно будет выдавать 380В и позволит равномерно отбирать мощность из сети. Микросхему применил весьма популярную, китайцы (и не только) любят ставить ее в сварочные инвертора в тех же целях — ICE2PCS01. Таить не буду — взял ее как проверенное временем решение, на ней собирал ККМ на 6 кВА для полуавтомата и проблем нет уже не первый год, надежность меня подкупает.

5) Непосредственно преобразователь напряжения реализован по топологии — «полумост», советую для знакомство с ней прочитать главу в книге Семенова «Силовая электроника: от простого к сложному». Контроллер полумоста реализован на «классической» как Чайковский микросхеме TL494: дешево, функционально, надежно, проверено временем — что еще требуется? Кто считает ее старой может обратить свой взор на что-то от Texas из серии UCC38xxx. В данном модуле реализована обратная связь по напряжению на TL431 + PC817, а так же защита по току на датчике на эффекте Холла — ACS758.

6) Силовой трансформатор я планирую реализовать на сердечнике компании Epcos типа ETD44/22/15 из материала N95. Возможно мой выбор изменится дальше, когда буду рассчитывать моточные данные и габаритную мощность.

7) Долго колебался между выбором типа выпрямителя на вторичной обмотке между сдвоенным диодом Шоттки и синхронным выпрямителем. Можно поставить сдвоенный диод Шоттки, но это P = 0,6В * 40А = 24 Вт в тепло, при мощности ИИП примерно в 650 Вт получается потеря в 4%! При использование в синхронном выпрямителе самых обычных IRF3205 с сопротивление канала тепла выделится P = 0,008 Ом * 40А * 40А = 12,8 Вт. Получается выигрываем в 2 раза или 2% кпд! Все было красиво, пока я не собрал на макете решение на IR11688S. К статическим потерям на канале добавились динамические потери на коммутацию, в итоге то на то и вышло. Емкость у полевиков на большие токи все таки большая. лечется это драйверами по типу HCPL3120, но это увеличение цены изделия и чрезмерное усложнение схемотехники. Собственно из этих соображений решено было поставить сдвоенный Шоттки и спать спокойно.

8) LC-контур на выходе, во-первых, уменьшит пульсации тока, во-вторых, позволит «срезать» все гармоники. Последняя проблема крайне актуальна при питании устройств работающих в радиочастотном диапазоне и имеющие в своем составе высокочастотные аналоговые цепи. У нас же речь идет от КВ трансивере, поэтому тут фильтр просто жизненно необходим, иначе помехи «пролезут» в эфир. В иделе тут еще можно поставить на выход линейный стабилизатор и получить минимальные пульсации в единицы мВ, но на деле скорость ОС позволит и без «кипятильника» получить пульсации напряжения в пределах 20-30 мВ, внутри трансивера критичные узлы запитываются через свои LDO, так что его избыточность очевидна.

Ну вот мы и пробежались по функционалу и это только начало)) Но ничего, дальше пойдет бодрее ибо начинается самая интересная часть — расчеты всего и вся!

Расчет силового трансформатора для полумостового преобразователя напряжения

Сейчас немного стоит подумать о конструктиве и топологии. Я планирую применять полевые транзисторы, а не IGBT, поэтому рабочую частоту можно выбрать побольше, пока задумываюсь о 100 или 125 кГц, такая же частота кстати будет и на ККМ. Повышение частоты позволит несколько уменьшить габариты трансформатора. С другой стороны задирать сильно частоту не хочу, т.к. применяю TL494 в качестве контроллера, после 150 кГц она себя уже не так хорошо показывает, да и динамические потери вырастут.
Исходя из таких вводных, посчитаем наш трансформатор. У меня есть в наличии несколько комплектов ETD44/22/15 и поэтому пока ориентируюсь на него, список исходных данных таков:
1) Материал N95;
2) Тип сердечника ETD44/22/15;
3) Рабочая частота — 100 кГц;
4) Выходное напряжение — 15В;
5) Выходной ток — 40А.

Для расчетов трансформаторов до 5 кВт использую программу «Старичка», она удобна и достаточно точно считает. После 5 кВт начинается магия, частоты растут для уменьшения габаритов, а плотности поля и тока достигают таких значений, что даже скин-эффект способен менять параметры чуть ли не в 2 раза, поэтому для больших мощностей применяю дедовский метод «с формулами и выводом карандашом на бумаге». Вписав в программку свои вводные данные был получен следующий результат:

image
Рисунок 2 — Результат расчета трансформатора для полумоста

На рисунке с левой стороны отмечены вводные данные, их я описал выше. По центру фиолетовым цветом выделены результаты, которые нас больше всего интересуют, пробегусь кратко по ним:

1) Входное напряжение составляет 380В DC, оно стабилизированное, т.к. полумост питается с ККМ. Такое питание упрощает конструкцию многих узлов, т.к. пульсации токов минимальны и трансформатору не придется вытягивать напряжение при входном сетевом напряжение 140В.
2) Потребляемая (прокачиваемая через сердечник) мощность получилась 600 Вт, что в 2 раза меньше габаритной (той, которую сердечник может прокачать не уйдя в насыщение) мощности, а значит все хорошо. В программке не нашел материал N95, но на сайте Epcos в даташите подсмотрел, что N87 и N95 дадут очень похожие результаты, проверив на листочке выяснил, что разница в 50 Вт габаритной мощности — не страшная погрешность.
3) Данные по первичной обмотке: 21 виток мотаем в 2 провода диаметром 0.8 мм, думаю тут все понятно? Плотность тока около 8А/мм2, а это значит, что обмотки не будут перегреваться — все хорошо.
4) Данные по вторичной обмотке: мотаем 2 обмотки по 2 витка в каждой проводом так же 0.8 мм, но уже в 14 — все таки ток 40А! Далее соединяем начало одной обмотки и конец другой, как это сделать я объясню дальше, почему-то часто люди при сборке на этом моменте в ступор впадают. Тут тоже вроде магии никакой нету.
5) Индуктивность выходного дросселя — 4.9 мкГн, ток соответственно 40А. Нужен он, чтобы на выходе нашего блока не было огромных пульсаций ток, в процессе отладки я пока на осциллографе работу с ним и без него, все станет ясно.

Расчет занял 5 минут, если у кого-то вопросы, то в комментариях или ЛС спрашивайте — подскажу. Чтобы не искали саму программу, предлагаю скачать ее с облака по ссылке. И моя огромная благодарность Старичку за его труд!
Следующим логичным этапом будет расчет выходного дросселя для полумоста, это как раз тот, что на 4.9 мкГн.

Расчет моточных параметров для выходного дросселя

Вводные данные мы получили в предыдущем пункте при расчет трансформатора, это:
1) Индуктивность — 4.9 мкГн;
2) Номинальный ток — 40А;
3) Амплитуда перед дросселем — 18В;
4) Напряжение после дросселя — 15В.

Используем так же программу от Старичка (все они есть в ссылке выше) и получаем следующие данные:

image
Рисунок 3 — Расчетные данные для намотки выходного дросселя

Теперь пробежимся по результатам:


1) По вводным данным есть 2 нюанса: частота выбирается та же самая, на которой работает преобразователь, это думаю логично. Второй момент связан с плотностью тока, сразу отмечу — дроссель должен греться! Вот только насколько сильно уже определяем мы, я выбрал плотность тока 8А/мм2, чтобы получить температуру в 35 градусов, это видно в выходных данных (отмечено зеленым). Ведь как мы помним по требованиям на выходе нужен «холодный ИИП». Так же хочется отметить для новичков возможно не совсем очевидный момент — дроссель будет греться меньше, если через него протекает большой ток, то есть при номинальной нагрузке 40А дроссель будет иметь минимальный нагрев. Когда ток меньше номинального, то для части энергии он начинает работать как активная нагрузка (резистор) и превращает все избытки энергии в тепло;
2) Максимальная индукция, это значение которое нельзя превышать, иначе магнитное поле насытит сердечник и будет все очень плохо. Данный параметр зависит от материала и его габаритных размеров. Для современных сердечников из распыленного железа типовым значение является 0,5-0,55 Тл;
3) Намоточные данные: 9 витков мотаются косой из 10 жил провода диаметром 0.8 мм. Программка даже примерно указывает сколько слоев для этого понадобится. Я буду мотать в 9 жил, т.к. потом удобно будет разделить большую косу на 3 «косички» по 3 жилы и без проблем их распаять на плате;
4) Собственно само кольцо на котором буду мотать имеет размеры — 40/24/14.5 мм, его хватает с запасом. Материал №52, думаю многие видели в АТХ блоках кольца желто-голубого цвета, часто они используются в дросселях групповой стабилизации (ДГС).

Расчет трансформатора дежурного источника питания

На функциональной схеме видно, что я хочу использовать в качестве дежурного блока питания «классический» flayback на TOP227, от него будут запитываться все ШИМ контроллеры, индикацию и вентиляторы системы охлаждения. То, что вентиляторы будут запитываться от дежурки я понял только спустя какое-то время, поэтому данный момент на схеме не отображен, но ничего это же реалтайм разработка))

Скорректируем немного наши вводные данные, что же нам нужно:


1) Выходные обмотки для ШИМ: 15В 1А + 15В 1А;
2) Выходная обмотка самопитания: 15В 0.1А;
3) Выходная обмотка для охлаждения: 15В 1А.

Получаем необходимость в блоке питания с суммарной мощностью — 2*15Вт + 1.5Вт + 15Вт = 46.5 Вт. Это нормальная мощность для TOP227, я ее использую в мелких ИИП до 75 Вт для всяких зарядок АКБ, шуруповертов и прочего хлама, за много лет что странно еще ни один пока не сгорел.
Идем в другую программку Старичка и считаем трансформатор для flayback:

image
Рисунок 4 — Расчетные данные для трансформатора дежурного питания

1) Выбор сердечника обоснован просто — он у меня есть в количестве ящика и те самый 75 Вт он вытягивает)) Данные на сердечника тут. Он из материала N87 и имеет зазор 0.2 мм на каждой половинке или 0.4 мм так называемый полный зазор. Данный сердечник прямо предназначен для дросселей, а у обратноходовых преобразователей эта индуктивность именно дроссель, но не буду пока в дебри влезать. Если в трансформаторе полумоста зазора не было, то для обратноходового преобразователя он обязателен иначе как и любой дроссель он просто уйдет в насыщение без зазора.
2) Данные о ключе 700В «сток-исток» и 2.7 Ом сопротивления канала, взяты из даташита на TOP227, у данного контроллера силовой ключ встроен в саму микросхему.
3) Входного напряжение минимальное взял чуть с запасом — 160В, это сделано для того, чтобы в случае выключения самого блока питания в работе осталась дежурка и индикация, они сообщат о аварийно низком напряжении питания.
4) Первичная обмотка у нас представляет из себя 45 витков проводом 0.335 мм в одну жилу. Вторичные обмотки силовые по 4 витка и 4 жилы проводом 0.335 мм (диаметр), обмотка самопитания обладает такими же параметрами, поэтому все тоже самое, только 1 жила, ибо ток на порядок ниже.

Расчет силового дросселя активного корректора мощности

Думаю самый интересный участок данного проекта именно корректор коэффициента мощности, т.к. по ним достаточно мало информации в интернете, а рабочих и описанных схем еще меньше. Выбираем программку для расчета — PFC_ring (PFC это по-басурмански ККМ), вводные используем следующие:
1) Входное напряжение питания — 140 — 265В;
2) Номинальная мощность — 600 Вт;
3) Выходное напряжение — 380В DC;
4) Рабочая частота — 100 кГц, обусловлена выбором ШИМ контроллера.

image
Рисунок 5 — Расчет силового дросселя активного ККМ

1) Слева как обычно вводим исходные данные, установив 140В минимальным порогом мы получаем блок, который сможет работать при напряжение сети 140В, так мы получаем «встроенный стабилизатор напряжения»;
2) Сердечник выбрал — К46/24/18. По расчетам впритык влезало и на кольцо диаметром 39 мм, но там получалось 110 витков — мотать сложно будет в кучу слоев, да и запас по индукции в ККМ весьма кстати, в итоге получает 0.35 Тл при допустимых 0.5 Тл;
3) Многих пугает такая надпись: «Емкость выходного конденсатора» 4000 мкФ! Те, кто в теме ужаснутся такой цифре, это 15 огромных и дорогих кондеров (300-350р/шт), но не пугайтесь — это цифра бесполезна для нас и ориентироваться на нее нельзя, Старичок наверное в расчетах или лишний ноль где-то дописал, или речь идет о конденсаторах к огромным ESR и надо 15 штук параллелить. Для нас есть параметр более грамотный — «Действующий ток в выходной емкости» 3.845А. 1 хороший электролит от Epcos со своим низким внутренним ESR способен отдавать 3-4А. Я перестрахуюсь и поставлю 2 штуки параллельно, чтобы уменьшить ESR и получить минимум 6А с ног кондеров.

Какие на самом деле конденсаторы надо применять

Существуют специальные пленочные конденсаторы, они способны отдавать огромные токи, а их ESR измеряется в единицах мили Ом! Да, у них меньшие емкости 10-50 мкФ, но 1 такой конденсатор заменяет батарею из нескольких огромных электролитов алюминиевых, а самое главное работает на больших частотах, тогда как «классически» электролит после 200 кГц превращается в резистор и просто греет планету.
Выглядят они вот так. Как видите ценник очень даже преятный на фоне тех же электролитов, так что советую использовать именно их. У меня их просто нету в наличии, а digikey только после праздников отправит.

Схемотехника активного корректора коэффициента мощности и входных цепей

Вот и подошли на верное к самому интересному пункту — схемотехника. Начну разумеется по порядку: от входа к выходу. Думаю те, кто разбирал любой импульсный блок питания видел скопление конденсаторов (чаще синего цвета) и дроссель сразу около разъема подключения вводного кабеля, этот модуль называется как раз — фильтр синфазных помех.
Что такое синфазные помехи и зачем с ними бороться можно нагуглить без проблем, я же лишь вкратце объясню. Синфазные помехи — это все помехи, блуждающие между проводниками тока и землей. Они приходят к нам из сети питания, да и наш блок питания так же излучает их в определенном виде, чтобы избавиться от них — мы и ставим фильтр.
Методика расчета есть во многих источниках, так же советую посмотреть книги Семенова: первую (3.3) и вторую (3.2). Я же предпочитаю задачи связанные с ЭМИ моделировать в CST Suite Studio и «методом подбора» получать наиболее оптимальные параметры. К тому же данный фильтр в отличии от LC фильтра низкой частоты не требует высокой точности, поэтому для 90% ИИП вы можете использовать данные приведенные в моем схематике.

Для управления ККМом я решил применить микросхему — ICE2PCS01GXUMA1. Она позволяет построить достаточно простой и надежный преобразователь, как уже было написано АККМ — это ни что иное как booster.

image
Рисунок 6 — Схема входных цепей и активного ККМ

Немного о схемотехнике… В современном мире трудно что-то изобрести — это факт. Можно сделать классную железку, но с вероятностью 99,99% ее уже кто-то делал, но возможно просто в более плохом исполнение. Все это касается и электроники, можно месяцами сидеть и изобретать схемы и в итоге окажется, что ее придумали лет так 10 назад. Это ни в коем случае не повод перестать изобретать! Это лишь повод получше поискать информацию. Я использую микросхему, которую производит гигант индустрии — Infineon Technologies. Поэтому с большой вероятностью они предусмотрели для своего контроллера некую отладочную плату, поэтому я сразу пошел на digikey.com, где обычно закупаюсь, и вбил название своего камня — по мимо возможности купить микросхему поисковик на сайте мне выдал одну отладку (Evaluation Board) — EVALPFC2-ICE2PCS01. Купить ее уже нельзя, только у производителя под заказ, но мне и не надо. Зато тут есть документация на готовое рабочее решение с открытой схемой, трассировкой платы и списком компонентов! Вот оно готовое решение, ничего не надо придумывать, производитель сделал все, чтобы его продукцию покупали, а для разработчиков практически всегда на первом месте в требованиях к элементам стоит доступность документации и только потом цена. Есть только одно «НО» — отладочная плата на 300Вт, а мне надо 700, но не страшно — сама архитектура это уже 90% работы, пересчитать номиналы это дело 15 минут, и так поехали:

1) Силовой дроссель L5 я пересчитал и данные для его намотки отображены на рисунке 5. Мы получили, что вместо индуктивности в 1240 мкГн понадобится значение в 480 мкГн, правда и значение тока выросло в 2,5 раза;
2) Диоды VD11,12 должны быть на напряжение не менее выходного, то есть 400В и выше, а так же должны выдерживать импульсное значение тока в устройстве. Еще одним важнейшим параметром является время обратного восстановления, т.к. мой корректор работает на частоте в 100 кГц и обычный диод просто не будет успевать. Для данной задачи подойдут импульсные или ultrafast диоды. Я применил диоды VS-HFA16TB120-N3 на 1200В и 16А с временем восстановления всего 30 мкс, т.к. они соответствую всем параметрам, выпускаются в удобном для охлаждения корпусе TO-220-2 и стоят не дорого около 2-2,5$;
3) Транзистор VT1 должен быть не менее чем с 1,5 запасом по напряжению «сток-исток» и выдерживать импульсное значение тока (х2 от номинального). Учитывая частоту лучше применить N-канальный Mosfet, тем более в последние пару лет они стали очень доступны по цене. Я применил ключ на 800В, т.к. выбросы могут достигать 1,5й амплитуды (около 550В) и запас дополнительный лишним не бывает. Ток у данного ключа 11А и что важно он изготавливается в корпусе TO-247, а значит его очень легко охлаждать и изолировать от радиатора;
4) Выходные конденсаторы C18,19 являются важным узлом, т.к. у нас преобразователь однотактный и именно они сглаживают пульсации тока. Конденсатор должен быть желательно на 450В чтобы иметь запас по напряжению и способен отдавать до 8А тока на пиковых нагрузках. В спойлере выше я писал про конденсаторы, хороший электролит способен отдавать 3-4А мгновенного тока и он ограничивается исключительно ESR конденсатора. Чтобы получить необходимые 8А я решил уменьшить ESR за счет параллельного включения 2-х конденсаторов, каждый на 470 мкФ и 450В. Такая «батарея» способна отдать 11А, т.к. применил кондесаторы весьма хорошие от Epcos из линейки Low ESR;
5) Еще стоит пересчитать датчик тока в виде шунта, в даташите эта тема полностью раскрыта в виде целого раздела.

Узел дежурного питания ИИП

Немного по гальванической развязке, решение у меня тут немного своеобразное, объясню почему так и не иначе:
1) «Первичка и вторичка развязаны» — сделал для того, чтобы в случае пробоя TOP227 «мозги» не сгорели и ремонт ограничится лишь в замене самой микросхемы;
2) «Вторичные обмотки между собой не развязаны» — а зачем? У меня все модули управления объединены общей землей. Конечно можно озадачиться и развязать «мозги» ККМа, полумоста и индикации, но это актуально, когда цена управляющих цепей очень высока и составляют 20-30% от стоимости самого устройства. Такое бывает если для управления применяю DSP или какой-то МК motor control, в моем же случае TL-ка за 15 рублей и IR2110 не стоят таких затрат как оптическая развязка или развязка на трансформаторах — сложность такого решения сильно возрастет вместе с ценником;
3) «Если вторички гальванически связаны, то зачем делать их аж 3 штуки, когда можно сделать 1 штуку на 3А?» — я художник и я так вижу сделано это ради просто удобства: удорожание копеечное, а разводить ПП и искать дефекты при ремонте будет намного проще. Ведь каждая цепь питания целый, логически завершенный блок на схеме.

Теперь сама схемотехника, как я и предполагал — особо не удалялся от даташита на TOP227, из «изысков» добавил дроссели на вторичных обмотках ради уменьшения пульсаций тока, добавлена индикация светодиодная на каждый канал. Снаббер применил RC-шный, т.к. супрессор почему-то не успевал за выбросами, хотя должен. Да и я не сторонник использования супрессоров, ну не нравятся они мне просто после того, как пару раз намучился с ними. Еще «камень в их огород» — не работают на большой частоте, современная база позволяет проектировать обратноходовые преобразователи на частотах 1-1,5 МГц и там они нужны как козе баян.
Еще один момент — питание для дежурки я взял после синфазного фильтра, но до диодного моста. Да, мне пришлось поставить еще один диодный мост за 0.2$, но зато я сэкономил около 3$ на еще одном синфазнике — профит!

image
Рисунок 7 — Схема дежурного блока питания для цепей управления ИИП

Я упоминал, что данную статью в первую очередь пишу для новичков и тех, кто хочет познать джедайскую мощь схемотехники, поэтому покажу откуда взялись номиналы всех компонентов в данном модуле, ведь часто открыв даташит мы обнаруживаем, что далеко не все компоненты можно посчитать по имеющимся формулам, т.к. производители делают документацию для подготовленных инженеров, а не новичков и любители — о этот жестокий мир!

1) VD4 – напряжение его должно быть не менее, чем: UМ = 265В * 1.41 = 374В. Откуда взялись эти цифры: «265В» – максимальное напряжение работы ИИП равно 255В и 10В в запас, «1.41» — это множитель, что пересчитать переменное напряжение до диодного моста в постоянное напряжение после него.
Номинальный ток не менее: I = P/(µ * UВХ) = (15В * 1А * 3 + 15В * 0,1А) / (140В * 0,85) = 0,39А. Тут лучше взять хотя бы с двойным запасом, т.к. в момент включения будет заряжаться конденсатор и будет пик тока достаточно большой. Теперь по цифрам: «15В и 1А» – это наши обмотки, «140В» – это минимальное напряжение на входе нашего БП. Почему минимальное? А потому, что в данном случае будет максимальный ток – рассматривать всегда надо худшие условия, чтобы ничего не взрывалось. «0,85» — это КПД нашего преобразователя, как показывает практика — это среднее значение для данной микросхемы, и оно даже оговорено в даташите.
2) R1 и C13 – считаются в программе Старичка там же где и трансформатор, в левом верхнем углу «RCD-снаббер».
3) VD8 – берется исходя из соображений, что максимальное напряжение не меньше, чем у встроенного в микросхему силового ключа, в моем случае это не менее 700В. Ток не менее тока потребления схемой, то есть требования к диоду: >700В и >0.4А, у FR207 значения 1000В и 2А – все подходит.
4) VD2,3,5,6 – это должны быть диоды Шоттки или импульсные диоды. Шоттки предпочтительнее из-за меньшего падения напряжения, хотя при таких токах не критично. Так же в таблице расчета трансформатора (рисунок 4) есть показатель «обратное напряжение», у меня оно 46В – значит напряжение диодов должно быть, не менее 46В. Ближайшие Шоттки 60В отлично подойдут под эту задачу. Ток диода же не менее, чем номинальный, правда есть одна тонкость – нагрузка будет импульсная: ток номинальный 1А, но потребление теоретически может быть и выше до 2А просто кратковременно при заряде затвора ключа. Поэтому взял Шоттки на 60В и 2А – запас жопу не жмет как говорят в нашей доблестной армии.
5) С6-С11 – минимальная емкость выходного конденсатора указана на рисунке 4, в однотактных преобразователях именно он уменьшает пульсации тока, отдавая энергию. У меня получилось 99 мкФ – на деле работать будет, но пульсации будут около 1-2В. Это опять же опыт, либо считать руками. Чтобы не портить бумагу можно смоделировать выходную цепь в MicroCap. Я поставил суммарную емкость в 660 мкФ, этого более чем достаточно для получения пульсаций в пределах 100 мВ.
6) L2-L4 – индуктивности моделируются так же в MicroCap, самый простой способ и точный. А так можно ставить с индуктивностью от 2.2 до 10 мкГн без каких-либо опасений, будет работать достойно. Ток дросселя должен быть не менее, чем номинальный, то есть 1А. Я применил дроссели с индуктивностью 10 мкГн и током 1.1А от Epcos.
7) R3 – тут все по закону Ома: R = (UП — UД) / IС = (15,3В – 2,6В) / 0,008А = 1570 Ом – ближайший номинал 1,5 кОм. «15,3В» — это напряжение на выходе от которого питается светодиод оптрона. «2,6В» — падение на светодиоде (в даташите берется). «0.008А или 8 мА» — ток, который мы направим в оптрон, вообще можно до 20 мА, но смысла нет и 1-10 мА вполне достаточно – дольше проживет.
8) R6 и R8 – образуют делитель напряжения, который собственно задает напряжение на выходе. Оно считается так: UВЫХ = UREF * (1+R2/R8) = 2,56В * (1+100/20) = 2,56В * 6 = 15,36В – отлично же! «UREF = 2,56В» — это напряжение при котором пробивает «программируемый стабилитрон» TL431, то есть при достижении напряжения 2,56В на управляющей ноге 2 стабилитрон открывается и подает «землю» с ноги 3 на ногу 1 и соответственно на анод светодиода оптрон. Так TOP227 узнает, что хватит качать энергию. Сами номиналы резисторов подбираются так, чтобы при деление выходного напряжения (которое мы хотим) получалось ровно 2,56В.
9) R2, R4, R7 – токоограничивающие резисторы на светодиодах, я не хочу светить ими в полный накал, поэтому подавать буду не 12-15 мА, которые они хотят по даташиту, а всего 5 мА иначе они слепят не плохо так. Опять прибегаем к закону Ому: R = (UП — UД) / IС = (15,3В – 2,6В) / 0,005А = 2540 Ом – ближайший номинал 2,4 кОм.

Схемотехника преобразователя напряжения по топологии «полумост»

Задача данного модуля преобразовать напряжение с ККМ с номиналом 380В в необходимое выходное 15В. Полумост я выбрал исходя из уменьшенного количества компонентов на фоне полного моста, а так же достаточно высокого значения КПД. С резонансником я заморачиваться не стал, габариты мне не критичны, а выигрыш в 1-2% не стоит таких усилий.
Устройство построено по распространенной схеме: «ШИМ контроллер (TL494) + драйвер полумоста (IR2110S) + 2 х N-канальных Mosfet-ах + диод Шоттки в выходном выпрямителе», поэтому ничего сверхнового тут не будет, единственное я добавил защиту по току на Холловском датчике тока ACS758, т.к. ток достаточно большой и измерять его хочется по возможности точнее — оборудование целее будет.

image
Рисунок 8 — Схема полумостового преобразователя напряжения

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

1) Один из основных параметров для ШИМ контроллера — это частота встроенного генератора. Рабочая частота для двухтактного блока питания будет составлять 1/2 от частоты генератора. Задается данный параметр с помощью RC-цепочки, на схеме это R37-C43. Формула для расчета частоты генератора приведена в даташите и выглядит следующим образом: fosc = 1,1 / (RT * CT). Рабочая частота у меня 100 кГц, значит расчетная частота для генератора должна быть вдвое больше — 200 кГц. Считаем: пусть С43 имеет емкость 2.2 нФ, тогда RT = 1,1 / (200 000 Гц * 0,0000022 Ф) = 2500 Ом — беру ближайший номинал 2.4 кОм;

2) Обратная связь по току реализована на встроенном, в ШИМ-контроллер, компараторе. При токе 40А согласно даташиту на ACS758-50B будет напряжение: UВЫХ = UVCC + Iизм*0,04В/А = (5В / 2) + (40А * 0,04В/А) = 2,5В + 1,6В = 4,1В. Чтобы компаратор выдал ошибку в видел лог.1 и ШИМ-контроллер понял, что пора уменьшить скважность ШИМа, неоходимо сигнал с датчика подавать на положительный вход ОУ, а на инверсный надо подать опорное напряжение значение 4.1В. У TL494 есть встроенный источник опорного напряжения (ИОН) на 5В, необходимо сделать делитель напряжения с коэф. деления равному: 5В / 4.1В = 1.22. Данный делитель реализован на R27-R26, я подобрал номиналы 2 и 10 кОм, коэф. деления будет равен 1,2В и на инверсном входе компаратора будет опорное напряжение, равное: UОП = UREF / (1+R27 / R26) = 5В / (1 + 2/10) = 4,16В — это значение соответствует току в 41.3А. Так и оставляем;

3) Обратная связь по напряжению «классическая», сильно рассказывать о ней не будут. Выходное напряжение через делитель поступает на TL431 с напряжением открытия 2,56В. Как только напряжение достигает нужного значения TL431 подключает светодиод оптрона к земле и он загорается, подавая +5В на положительный вход встроенного ОУ (их аж 2 штуки у TL494). Когда оптрон закрыт вход через резистор R30 подтянут к земле и компаратор выдает лог.0. На инверсный вход через делитель подается 1/2 UREF равное 2.5В, поэтому при закрытом оптроне на прямом входе 0В и выход ОУ равен 0, когда оптрон открыт, то на прямом входе 5В, что больше 2.5В и на выходе ОУ устанавливается 1, сообщая об ошибке;

4) C25, 26 — конденсаторы создают «среднюю точку», конденсаторы применяются с рабочим напряжением 200-250В. Я поставил конденсаторы от Epcos на 220 мкФ и 250В;

5) VT2, 3 — полевые транзисторы, такие же как в ККМ. Напряжение «сток-исток» с большим запасом, реально там не будет более 200В + выбросы 50-100В. Такой запас позволяет отказаться от снабберных цепей. Ток в ключах будет: IVT = PВЫХ / UДЕЛ = 600 Вт / (380В / 2) = 600 Вт / 190В = 3,15А. Наши ключи на 11А, так что даже пиковые кратковременные перегрузки не навредят преобразователю;

6) Выходной дроссель L6 мы уже рассчитывали и результаты приведены на рисунке 3.

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

Дизайн печатной платы импульсного блока питания

Вот я и добрался до этапа, который остается для многих чем-то сакральным — дизайн/разработка/трассировка печатной платы. Почему предпочитаю именно термин «дизайн»? Он ближе к сущности данной операции, для меня «разводка» платы всегда процесс творческий как у художника написание картины, да и людям из других стран будет проще понять чем вы занимаетесь.
Сам процесс проектирования платы не содержит в себе каких либо подводных камней, они содержатся в том устройстве для которого она предназначена. На деле силовая электроника не выдвигает какое-то дикое количество правил и требований на фоне того же СВЧ аналога или скоростных цифровых шин данных.
Я перечислю основные требования и правила касающиеся именно силовой схемотехники, это позволит реализовать 99% любительских конструкций. О нюансах и «хитростях» рассказывать не буду — каждый должен сам набить себе шишек, получить опыт и уже оперировать им. И так поехали:

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

Немного о плотности тока в печатных проводниках

Часто люди не задумываются о данном параметре и мне приходилось встречать, где силовая часть выполнена проводниками 0.6 мм при 80% площади платы просто пустующей. Зачем так делать для меня лично загадка.
Так какую же плотность тока можно брать в расчеты? Для обычного провода стандартной цифрой является 10А/мм2, это ограничение привязано к охлаждению провода. Можно пропускать и больший ток, но перед этим опустите его в жидкий азот. У плоских проводников, как на печатной плате к примеру, площадь поверхности большая, охлаждать их проще, а значит можно позволить себе большие плотности тока. Для нормальных условий с пассивных или воздушным охлаждением принято брать в расчет 35-50 А/мм2, где 35 — для пассивного охлаждения, 50 — при наличии искусственной циркуляции воздуха (мой случай). Есть еще одна цифра — 125 А/мм2, это по настоящему большая цифра, не все сверхпроводники могут ее себе позволить, но она достижима лишь при погружном жидкостном охлаждение.
С последним я столкнулся при работе с одной компанией, занимавшейся инженерными коммуникациями и проектированием серверов, на мою доля выпал как раз дизайн материнской платы, а именно часть с многофазным питанием и коммутацией. Сильно удивился, когда увидел плотность тока в 125 А/мм2, но мне объяснили и показали на стенде такую возможность — тут я понял зачем же целые стеллажи с серверами погружают в огромные бассейны с маслом)))
В моей железке все по проще, 50 А/мм2 цифра вполне себе адекватная, при толщине меди в 35 мкм полигоны без проблем обеспечат нужное сечение. Остальное же было для общего развития и понимания вопроса.

2) Длина проводников — в данном пункте нету необходимости равнять линии с точностью до 0,1 мм как это делают, например, при «разводке» шины данных DDR3. Хотя все равно крайне желательно делать длину сигнальных линий примерно равно длины. Достаточно будет и +-30% длины, главное не делать HIN в 10 раз длиннее, чем LIN. Это необходимо, чтобы фронты сигналов не смещались относительно друг друга, ведь даже на частоте всего в сотню килогерц разница в 5-10 раз может вызвать сквозной ток в ключах. Особенно это актуально при малом значение «мертвого времени», даже при 3% у TL494 это актуально;

3) Зазор между проводниками — он необходим для уменьшения токов утечки, особенно это касается проводников, где протекает ВЧ сигнал (ШИМ), ведь поле в проводниках возникает сильно и ВЧ сигнал за счет скин-эффекта стремится вырваться как на поверхность проводника, так и за его пределы. Обычно достаточно зазора в 2-3 мм;

4) Зазор гальванической развязки — это зазор между гальванически развязанными участками платы, обычно требование на пробой около 5 кВ. Чтобы пробить 1 мм воздуха надо около 1-1,2 кВ, но у нас пробой возможен не только по воздуху, но и по текстолиту и маске. В заводских условиях используются материалы проходящие электротестирование и можно спать спокойно. Поэтому основная проблема воздух и из вышеописанных условий можно сделать вывод, что достаточно будет около 5-6 мм зазора. В основном разделение полигонов под трансформатором, т.к. он является основным средством гальванической развязки.

Теперь перейдем непосредственно к дизайну платы, я не буду в данной статье рассказывать ну супер подробно, да и вообще писать целую книгу текста желания не много. Если наберется большая группа желающих (в конце опрос сделаю), то просто сниму видеоролики по «разводке» данного устройства, это будет и быстрее и информативнее.

Этапы создания печатной платы:

1) Первым делом необходимо определиться с примерными габаритами устройства. Если у вас есть уже готовый корпус, то вы должны измерить посадочное место в нем и отталкиваться в размерах платы именно от него. Я же планирую корпус сделать на заказ из алюминия или латуни, поэтому буду стараться сделать максимально компактное устройство без потери качества и ТТХ.

image
Рисунок 9 — Создаем заготовку будущей платы

Запомните — габариты платы должны быть кратны 1 мм! Или хотя бы 0.5 мм, иначе вы еще вспомните мое завещание Ленина, когда будете собирать все в панели и делать заготовку на производство, а конструкторы, которые будут создавать по вашей плате корпус засыпят вас проклятиями. Не надо создавать плату с размерами аля «208,625 мм» без крайней необходимости!
P.S. спасибо тов. Лунькову за то, что он все таки донес мне эту светлую мысль))

Тут я сделал 4 операции:
а) Сделал саму плату с габаритными размерами 250х150 мм. Пока это примерный размер, дальше думаю ужмется ощутимо;
б) Закруглил углы, т.к. в процессе доставки и сборку острые убьются и сомнутся + плата приятнее выглядит;
в) Разместил крепежные отверстия, не металлизированные, с диаметром отверстия 3 мм под стандартный крепеж и стойки;
г) Создал класс «NPTH», в который определил все не металлизированные отверстия и создал для него правило, создающие зазор 0.4 мм между всеми другими компонентами и компонентами класса. Это технологическое требование «Резонита» для стандартного класса точности (4-й).

image
Рисунок 10 — Создание правила для не металлизированных отверстий

2) Следующим этапом необходимо сделать расстановку компонентов с учетом всех требований, она должна быть уже сильно приближена к конечному варианту, т.к. побольше части сейчас определятся финальные габариты платы и ее форм-фактор.
image
Рисунок 11 — Выполнена первичная расстановка компонентов

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

image
Рисунок 13 — 3D вид платы после расстановки компонентов

3) Теперь, определив расположение и общую структуру расставляем оставшиеся компоненты и «разводим» плату. Дизайн платы можно выполнить двумя способами: в ручную и с помощью автотрассировщика, предварительно описав его действия парой десятков правил. Оба способа хороши, но данную плату сделаю все таки руками, т.к. компонентов мало и особых требований по выравниваю линий и целостности сигналов тут нет и не должно быть. Так будет определенно быстрее, автотрассировка хороша, когда много компонентов (от 500 и далее) и основная часть схемы цифровая. Хотя если кому-то будет интересно, то могу показать как «разводить» платы автоматически за 2 минуты. Правда перед этим надо будет весь день писать правила, хех.

После 3-4х часов «колдунства» (половину времени отрисовывал модели недостающие) с температурой и чашечкой чая я наконец-то развел плату. Я даже не задумывался от экономии места, многие скажу, что габариты можно было ужать на 20-30% и будут правы. У меня штучный экземпляр и тратить свое время, которое явно дороже 1 дм2 за двухслойную плату, было просто жалко. Кстати о цене платы — при заказе в «Резонит»-е, 1 дм2 двухслойной платы стандартного класса, обходится примерно в 180-200 рублей, так что много тут не сэкономить если у вас конечно не партия в 500+ штук. Исходя из этого, могу посоветовать — не извращайтесь с уменьшением площади, если 4 класс и не требований к габаритам. И вот что получилось на выходе:

image
Рисунок 14 — Дизайн платы для импульсного блока питания

В дальнейшем я буду проектировать корпус для данного устройства и мне необходимо знать его полные габариты, а так же иметь возможность «примерить» его внутрь корпуса, чтобы на финальной стадии не выяснилось, например, что основная плата мешает разъемам на корпусе или индикации. Для этого я всегда страюсь отрисовывать все компоненты в 3D виде, на выходе вот такой результат и файлик в формате .step для моего Autodesk Inventor:

image
Рисунок 15 — Трехмерный вид на получившиеся устройство

image
Рисунок 16 — Трехмерный вид на устройство (вид сверху)

Теперь документация готова. Сейчас необходимо сформировать необходимый пакет файлов для заказа компонентов, у меня все настройки уже прописаны в Altium-е, поэтому выгружается все одной кнопкой. Нам необходимы Gerber-файлы и файл NC Drill, в первом хранится информация о слоях, во втором координаты сверловки. Посмотреть файлик для выгрузки документации можно будет в конце статьи в проекте, выглядит это все примерно так:

image
Рисунок 17 — Формирования пакета документации для заказа печатных плат

После того, как файлы готовы можно заказывать платы. Конкретных производителей рекомендовать не буду, наверняка есть лучше и дешевле именно для прототипов. Все платы стандартного класса 2,4,6 слоев я заказываю в Резоните, там же 2 и 4-х слойный платы 5-го класса. Платы 5 класса, где 6-24 слоя в Китае (например, pcbway), а вот платы HDI и 5-го класса с 24 и более слоями уже только на Тайване, все таки качество к Китае еще хромает, а где не хромает ценник уже не такой приятный. Это все касается прототипов!
Следуя своим убеждениям я иду в Резонит, ох сколько они нервов потрепали и крови выпили… но в последнее время вроде исправились и начали более адекватно работать, хоть и с пинками. Заказы я формирую через личный кабинет, вводите данные о плате, подгружаете файлы и отправляете. Личный кабинет у них мне нравится, цену кстати тут же считает и можно меняя параметры добиться лучше цены без потери качества.
Например, сейчас я хотел плату на текстолите 2 мм с медью 35 мкм, но оказалось, что такой вариант в 2,5 раза дороже чем вариант с 1,5 мм текстолитом и 35 мкм — поэтому выбрал последний. Для увеличения жесткости платы я добавил дополнительные отверстия под стойки — проблема решена, цена оптимизирована. Кстати, если бы плата шла в серию, то где-то на 100 штуках эта разница в 2,5 раза пропала и цены сравнялись, ибо тогда нестандартный лист закупали под нас и потратили без остатков.

image
Рисунок 18 — Финальный вид расчета стоимости плат

Финальная стоимость определена: 3618 рублей. Из них 2100 — это подготовка, она платится только один раз на проект, все последующие повторения заказа идут уже без нее и выплатите лишь за площадь. В данном случае 759 рублей за плату площадью 3.3 дм2, чем больше серия, тем меньше будет стоимость, хотя и сейчас она 230 руб/дм2, что вполне приемлемо. Можно было конечно сделать срочное изготовление, но я заказываю часто, работаю с одним менеджером и девушка всегда старается пропихнуть заказ быстрее если производство не загружено — в итоге и с вариантом «мелкая серия» по сроком выходит 5-6 дней, достаточно просто вежливо общаться и не хамить людям. Да и спешить мне сильно некуда, поэтому решено сэкономить около 40%, что как минимум приятно.

Эпилог

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

Как и обещал делюсь исходниками проекта и прочими продуктами деятельности:

1) Исходник проекта в Altium Designer 16 — тут;
2) Файлы для заказа печатных плат — тут. Вдруг вы захотите повторить и заказать, например, в Китае, этого архива более чем достаточно;
3) Схема устройства в pdf — тут. Для тех, кто с телефона или для ознакомления не хочет тратить время на установку Altium (качество высокое);
4) Опять же для тех, кто не хочет ставить тяжеловесный софт, но интересно покрутить железку выкладываю 3D модель в pdf — тут. Для просмотра надо обязательно скачать файл, когда откроете в правом верхнем углу жмем «доверять документу только один раз», дальше тыкаем в центр файла и белый экран превращается в модельку.

Так же хочется поинтересоваться мнение читателей… Сейчас платы заказаны, компоненты тоже — по факту есть 2 недели, о чем написать статью? По мимо таких «мутантов» как эта иногда хочется наваять что-то миниатюрное, но полезное, несколько вариантов я представил в опросах, либо предлагайте свой вариант наверное в личку, чтобы не засорять комментарии.
ссылка на оригинал статьи https://geektimes.ru/post/284140/

Еще один велосипед для борьбы с callback hell в JavaScript


Считается, что мир JavaScript бурно развивается: регулярно выходят новые стандарты языка, появляются новые синтаксические фишки, а разработчики моментально все это адаптируют и переписывают свои фреймворки, библиотеки и прочие проекты с тем, чтобы все это использовалось. Сейчас, например, если вы всё ещё пишете в коде var, а не const или let, то это уже вроде как моветон. А уж если функция описана не через стрелочный синтаксис, то вообще позор…

Однако, все эти const-ы, let-ы, class-ы и большинство других нововведений не более чем косметика, которая хоть и делает код красивее, но действительно острых проблем не решает.

Я думаю, что основная проблема JavaScript, которая уже давным давно созрела и перезрела, и которая должна была быть решена в первую очередь, это невозможность приостановить выполнение, и как следствие, необходимость все делать через callbacks.

Чем хороши callbacks?

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

Чем плохи callbacks?

Первое, с чем обычно сталкивается новичок, это тот факт, что с ростом сложности код быстро превращается в малопонятные многократно вложенные блоки — «callback hell»:

	fetch(“list_of_urls”, function(array_of_urls){ 		for(var i=0;  array_of_urls.length; i++) { 			fetch(array_of_urls[i], function(profile){ 				fetch(profile.imageUrl, function(image){ 					... 				}); 			}); 		} 	});

Во-вторых, если функции с колбеками соединены друг с другом логикой, то эту логику приходится дробить и выносить в отдельные именованные функции или модули. Например, код выше выполнит цикл «for» и запустит множество fetch(array_of_urls[i]… мгновенно, и если array_of_urls слишком большой, то движок JavaScript зависнет и/или упадет с ошибкой.

С этим можно бороться путем переписывания цикла «for» в рекурсивную функцию с колбеком, но рекурсия может переполнить стек и также уронить движок. Кроме того, рекурсивные программы труднее для понимания.

Другие пути решения требуют использования дополнительных инструментов или библиотек:

  • Promises – позволяет писать код колбеков внутри неких объектов. В результате это те же колбеки, но меньшей вложенности и соединенные друг с другом в цепочки:

    firstMethod().then(secondMethod).then(thirdMethod);

    На мой взгляд Promises это костыль, потому что

    1. цепочки вызывают функции только в одном заданном порядке,
    2. если порядок может менятся в соответсвии с какой-то логикой, по-прежнему приходится дробить логику в колбеках на отдельные функции,
    3. для кодирования логики между функциями по-прежнему приходится что-то изобретать, вместо того, чтобы просто пользоваться стандартными операторами if, for, while и т.п.
    4. логика с Promises выглядит малопонятно.

  • async (библиотека) — позволяет объявить массив функций с колбеками, и исполнять их одну за другой, или одновременно. Недостатки те же, что и у Promises.
  • async/await – новая возможность в JavaScript, основанная на generators, позволяет останавливать и возобновлять исполнение функции.

Будущее, судя по всему, за async/await, но пока это будущее не наступило, и многие движки эту возможность не поддерживают.

Чтобы иметь возможность исполнять код с async/await на актуальных на данный момент движках JavaScript 2015, были созданы транспиляторы — преобразователи кода из нового JavaScript в старый. Самый известный из них, Babel, позволяет конвертировать код Javascript 2017 с async/await в JavaScript 2015 и запускать его на практически всех используемых в данный момент движках.

Выглядит это примерно так:

Исходный код на JavaScript 2017:

async function notifyUserFriends(user_id) {   var friends = await getUserFriends(user_id);    for(var i=0; i<friends.length; i++) {     friend = await getUser(friends[i].id);     var sent = await sendEmail(freind.email,"subject","body");   } } 

Конвертированный код на JavaScript 2015:

спрятано в спойлер

"use strict";  var notifyUserFriends = function () {   var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(user_id) {     var friends, i, sent;     return regeneratorRuntime.wrap(function _callee$(_context) {       while (1) {         switch (_context.prev = _context.next) {           case 0:             _context.next = 2;             return getUserFriends(user_id);            case 2:             friends = _context.sent;             i = 0;            case 4:             if (!(i < friends.length)) {               _context.next = 14;               break;             }              _context.next = 7;             return getUser(friends[i].id);            case 7:             friend = _context.sent;             _context.next = 10;             return sendEmail(freind.email, "subject", "body");            case 10:             sent = _context.sent;            case 11:             i++;             _context.next = 4;             break;            case 14:           case "end":             return _context.stop();         }       }     }, _callee, this);   }));    return function notifyUserFriends(_x) {     return _ref.apply(this, arguments);   }; }();  function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } 

Чтобы иметь возможность отлаживать такой код, необходимо настроить и задействовать многое из того, что перечислено в этой статье.

Всё это само по себе требует нетривиальных усилий. Кроме того, Babel тянет за собой около 100 кб минифицированного кода «babel-polyfill», а сконвертированный код работает медленно (на что косвенно намекают многочисленные конструкции case номер_строки в сгенерированном коде).

Посмотрев на все это, я решил написать свой велосипед — SynJS. Он позволяет писать и синхронно исполнять код с колбеками:

function myTestFunction1(paramA,paramB) {     var res, i = 0;     while (i < 5) {         setTimeout(function () {             res = 'i=' + i;             SynJS.resume(_synjsContext); // < –- функция для сигнализации, что колбек закончен         }, 1000);         SynJS.wait(); // < – оператор, останавливающий исполнение         console.log(res, new Date());         i++;     }     return "myTestFunction1 finished"; }

Исполнить функцию можно следующим образом:

SynJS.run(myTestFunction1,null, function (ret) {     console.log('done all:', ret); }); 

Результат будет такой:

i=0 Wed Dec 21 2016 11:45:33 GMT-0700 (Mountain Standard Time) i=1 Wed Dec 21 2016 11:45:34 GMT-0700 (Mountain Standard Time) i=2 Wed Dec 21 2016 11:45:35 GMT-0700 (Mountain Standard Time) i=3 Wed Dec 21 2016 11:45:36 GMT-0700 (Mountain Standard Time) i=4 Wed Dec 21 2016 11:45:37 GMT-0700 (Mountain Standard Time)

По-сравнению с Babel он

  • легче (35кб без минимизации),
  • не имеет зависимостей,
  • не требует компиляции,
  • исполняется примерно в 40 раз быстрее (хотя это может быть не так критично при работе с медленными функциями).

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

Функция может быть выполнена через SynJS следующим образом:

SynJS.run(funcPtr,obj, param1, param2 [, more params],callback)

Параметры:
— funcPtr: указатель на функцию, которую надо выполнит синхронно
— obj: объект, который будет доступен в функции через this
— param1, param2: параметры
— callback: функция, которая будет выполнена по завершении

Чтобы можно было дожидаться завершения колбека в SynJS существует оператор SynJS.wait(), который позволяет остановить исполнение функции, запущенной через SynJS.run(). Оператор может принимать 3 формы:
— SynJS.wait() — останавливает исполнение пока не будет вызван SynJS.resume()
— SynJS.wait(number_of_milliseconds) – приостанавливает исполнение на время number_of_milliseconds
— SynJS.wait(some_non_numeric_expr) – проверяет (!!some_non_numeric_expr), и останавливает исполнение в случае false.

С помощью SynJS.wait можно ожидать завершения одного или нескольких колбеков:

        var cb1, cb2;         setTimeout(function () {             cb1 = true;             SynJS.resume(_synjsContext);         }, 1000);         setTimeout(function () {             cb2 = true;             SynJS.resume(_synjsContext);         }, 2000);         SynJS.wait(cb1 && cb2);

Чтобы дать сигнал о завершении колбека в основной поток используется функция

SynJS.resume(context)

Обязательный параметр context содержит ссылку на контекст исполнения, который необходимо уведомить (так как каждый вызов SynJS.run создает и запускает отдельный контекст, в системе может существовать одновременно несколько запущенных контекстов).
При парсинге SynJS оборачивает каждый оператор оборачивается в функцию следующим образом:

function(_synjsContext) { 	... код оператора ... }

Таким образом можно использовать параметр _synjsContext в коде колбека для сигнализации о завершении:

SynJS.resume(_synjsContext);

Обработка локальных переменных.

При парсинге тела функции SynJS определяет декларации локальных переменных по ключевому слову var, и создаёт для них хеш в контексте исполнения. При обёртывании в функцию код оператора модифицируется, и все ссылки на локальные переменные заменяются ссылками на хеш в контексте исполнения.
Например, если исходный оператор в теле функции выглядел так:

	var i, res; 	...     setTimeout(function() {         res = 'i='+i;         SynJS.resume(_synjsContext);     },1000); 

то оператор, обернутый в функцию будет выглядеть так:

function(_synjsContext) {     setTimeout(function() {          _synjsContext.localVars.res = 'i='+_synjsContext.localVars.i;          SynJS.resume(_synjsContext);     },1000); }

Несколько примеров использования SynJS
1. Выбрать из БД массив родительских записей, для каждой из них получить список детей

2. По списку URL-ов, получать их один за другим, пока содержимое URL-а не будет удовлетворять условию

код

	var SynJS = require('synjs'); 	var fetchUrl = require('fetch').fetchUrl; 	 	function fetch(context,url) { 		console.log('fetching started:', url); 		var result = {}; 		fetchUrl(url, function(error, meta, body){ 			result.done = true; 			result.body = body; 			result.finalUrl = meta.finalUrl;  			console.log('fetching finished:', url); 		    SynJS.resume(context); 		} ); 		 		return result; 	}  	function myFetches(modules, urls) { 		for(var i=0; i<urls.length; i++) { 			var res = modules.fetch(_synjsContext, urls[i]); 			SynJS.wait(res.done); 			if(res.finalUrl.indexOf('github')>=0) { 				console.log('found correct one!', urls[i]); 				break; 			} 		} 	}; 	 	var modules = { 			SynJS: 	SynJS, 			fetch:	fetch, 	}; 	 	const urls = [ 	              'http://www.google.com',  	              'http://www.yahoo.com',  	              'http://www.github.com', // This is the valid one 	              'http://www.wikipedia.com' 	          ]; 	 	SynJS.run(myFetches,null,modules,urls,function () { 	    console.log('done'); 	}); 

3. В базе данных, обойти всех детей, внуков и т.д. некоторого родителя

код

	global.SynJS = global.SynJS || require('synjs'); 	var mysql      = require('mysql'); 	var connection = mysql.createConnection({ 	  host     : 'localhost', 	  user     : 'tracker', 	  password : 'tracker123', 	  database : 'tracker' 	});  	function mysqlQueryWrapper(modules,context,query, params){ 		var res={}; 		modules.connection.query(query,params,function(err, rows, fields){ 			if(err) throw err; 			res.rows = rows; 			res.done = true; 			SynJS.resume(context); 		}) 		return res; 	} 	 	function getChildsWrapper(modules, context, doc_id, children) { 		var res={}; 		SynJS.run(modules.getChilds,null,modules,doc_id, children, function (ret) { 			res.result = ret; 			res.done = true; 		    SynJS.resume(context); 		}); 		return res; 	} 	 	function getChilds(modules, doc_id, children) { 		var ret={}; 		console.log('processing getChilds:',doc_id,SynJS.states); 		var docRec = modules.mysqlQueryWrapper(modules,_synjsContext,"select * from docs where id=?",[doc_id]); 		SynJS.wait(docRec.done); 		ret.curr = docRec.rows[0]; 		 		ret.childs = []; 		var docLinks = modules.mysqlQueryWrapper(modules,_synjsContext,"select * from doc_links where doc_id=?",[doc_id]); 		SynJS.wait(docLinks.done);  		for(var i=0; docLinks.rows && i < docLinks.rows.length; i++) { 			var currDocId = docLinks.rows[i].child_id; 			if(currDocId) { 				console.log('synjs run getChilds start'); 				var child = modules.getChildsWrapper(modules,_synjsContext,currDocId,children); 				SynJS.wait(child.done); 				children[child.result.curr.name] = child.result.curr.name; 			} 		} 		return ret; 	}; 	 	 	var modules = { 			SynJS: 	SynJS, 			mysqlQueryWrapper: mysqlQueryWrapper, 			connection: connection, 			getChilds: getChilds, 			getChildsWrapper: getChildsWrapper, 	}; 	 	var children={}; 	SynJS.run(getChilds,null,modules,12,children,function (ret) { 	    connection.end(); 	    console.log('done',children); 	}); 

На данный момент я использую SynJS для написания браузерных тестов, в которых требуется имитировать сложные пользовательские сценарии (кликнуть ”New”, заполнить форму, кликнуть ”Save”, подождать, проверить через API что записалось, и т. п.) — SynJS позволяет сократить код, и самое главное, повысить его понятность.

Надеюсь, кому-то он тоже окажется полезен до тех пор, пока не наступило светлое будущее с async/await.

Проект на гитхабе: github.com/amaksr/SynJS
NPM: www.npmjs.com/package/synjs

P.S. Чуть не забыл, в SynJS имеется оператор SynJS.goto(). А почему бы и нет?
ссылка на оригинал статьи https://habrahabr.ru/post/319094/

Умельцы взломали NES Classic, теперь игры можно заливать по USB

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

Причем с новейшими консолями у японской компании дела идут не слишком хорошо. Может быть, именно поэтому в июле прошлого года Nintendo выпустила NES Classic, решив попробовать пойти по уже проторенному некогда пути. NES Classic — современная инкарнация NES, которая оснащена современными электронными компонентами и модулями. В частности, здесь есть HDMI-выход. В комплекте с приставкой компания решила поставлять и 30 старых игр.

«Нам захотелось дать поклонникам всех возрастов возможность снова открыть оригинальную систему Nintendo, дать им вспомнить, почему им так нравилась эта консоль… Nintendo Entertainment System: NES Classic Edition идеально подходит всем, кто помнит, как играть в NES, или кто хотел бы дать возможность прочувствовать вкус такой игры новому поколению геймеров», — заявил в свое время Реджинальд Фис-Эме (Reginald «Reggie» Fils-Aimé), президент и главный операционный директор Nintendo of America.

Все это хорошо, но кроме 30 игр, о которых было объявлено в самом начале, компания решила ничего больше не давать геймерам. Было четко объявлено, что официально Nintendo не станет выкладывать больше игр, что, впрочем, не остановило умельцев от поиска самостоятельного решения этой проблемы.

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

Ребята из сообщества NESClassicMods нашли собственное решение. Для того, чтобы оно заработало, необходимо создать файл сохранения в первом слоте Super Mario Bros. В общем-то, это сделать очень легко. После этого необходимо подключить NES Classic Edition к компьютеру через micro-USB кабель, а затем загрузить NES в режиме «FEL». Это можно сделать, удерживая кнопку перезагрузки, одновременно зажимая кнопку включения питания (финт с кнопками необходимо выполнить, когда приставка выключена). Начнется загрузка, и на ПК в это время необходимо начать загрузку «sunxi-FEL». Открытая версия этого ПО находится здесь.

Конечно, все это, включая остальные шаги, необходимо проделывать на свой страх и риск. Дело в том, что требуется копировать файлы с NES Classic на свой ПК, там их редактировать и снова загружать на приставку. Если что-то пойдет не так, консоль может перестать работать, хотя шансы на это и малы. Работать необходимо при помощи приложения, созданного умельцами. В числе прочих возможностей — на приставку можно заливать ROM-файлы игр.

После того, как все сделано, стоит добавить и файл изображения к игре. Затем все нужно запаковать и отправить на приставку. Если все пойдет так, как нужно, на приставке появятся новые игры. Стандартный список тоже неплох, здесь мы видим следующие наименования:
С приставкой поставляются такие игры, как:

  • Balloon Fight
  • Bubble Bobble
  • Castlevania
  • Castlevania II: Simon’s Quest
  • Donkey Kong
  • Donkey Kong Jr.
  • Double Dragon II: The Revenge
  • Dr. Mario
  • Excitebike
  • Final Fantasy
  • Galaga
  • Ghosts N’ Goblins
  • Gradius
  • Ice Climber
  • Kid Icarus
  • Kirby’s Adventure
  • Mario Bros.
  • Mega Man 2
  • Metroid
  • Ninja Gaiden
  • Pac-Man
  • Punch-Out!!! Featuring Mr. Dream
  • StarTropics
  • Super C
  • Super Mario Bros.
  • Super Mario Bros. 2
  • Super Mario Bros. 3
  • Tecmo Bowl
  • The Legend of Zelda
  • Zelda II: The Adventure of Link

Но все же геймерам хочется и дополнительных игр, благо, их очень много — всегда есть, во что поиграть.

Стоит отметить, что этому «хаку» немногим более пары дней, так что не слишком большое количество пользователей смогли проверить работоспособность игр, залитых таким необычным образом. Но в Сети уже появились видеоролики с Mega Man, где видно, что никаких проблем нет.


На этом скриншоте хорошо видно, что среди официально предоставленных Nintendo игр на приставке появились и Battletoads

Ограничения аппаратной платформы пока что не вполне ясны. Ясно, что добавлять можно и больше 30 игр, никаких проблем нет. Видео, которое размещено выше, демонстрирует нам систему с 55 играми, где в числе прочих залиты Contra и Battletoads.

Вполне может быть, что усилия сторонних разработчиков будут замечены компанией Nintendo. Хотелось бы надеяться, что она после всего этого начнет официально поставлять официальные версии старых игр, чтобы не заставлять геймеров придумывать различные обходные пути. Ясно, что аппаратная платформа позволяет загружать и дополнительные игры, так что вопрос «почему Nintendo не хочет давать дополнительные игры» остается открытым.
ссылка на оригинал статьи https://geektimes.ru/post/284370/