Привет, Хабр. С праздниками всех читателей! Меня зовут Павел, и одним из моих хобби является создание различных устройств на базе микроконтроллеров. Это моя первая статья здесь, и я буду рад конструктивной критике со стороны завсегдатаев Хабра.

Как и у многих инженеров, рабочее место на моем столе имеет склонность быстро заканчиваться, а последующее привидение всего этого безобразия в потребный вид порой требует больше времени и сил, чем собственно решение рабочей задачи. И в бесконечной череде оптимизаций пространства мой взгляд пал на следующую замечательную парочку: китайская паяльная станция для жал типа Т12 и самопальный паяльный фен, сделанный на Atmega328 еще в те далекие времена, когда Arduino стало для меня откровением. Они занимают много места, задачи у них смежные и зачастую используются оба, к тому же хотелось уже обновиться до жал JBC, а именно C245 c их мощностью (один из китайских клонов сейчас у меня потребляет 10А при 24В питания, 240 ватт мощности в маленьком формате, большинство же жал этого формата потребляют 180-190 ватт, против 70 ватт на жалах Т12) и огромным выбором форм. Решение очевидно: совместить их в одном устройстве. Беглый поиск дал понять, что готового устройства за адекватные деньги (паяльник C245 + фен) не найти. Добавим сюда еще несколько факторов: большой зоопарк жал T12 в наличии, которые бы тоже хотелось использоваться далее, небольшой дымоуловитель, подключающийся сюда же, возможность полной кастомизации готового устройства, от размера и до всевозможных настроек и, конечно, огромное желание творить.

Формирование ТЗ

Был проведен анализ и согласование потребностей и возможностей и выделены основные моменты:

  • 2 канала, один – паяльник, второй фен.

  • Удобные органы управления – никакого множества действий на единственную кнопку, по итогу пришел к 4 кнопкам + 2 энкодера (так же с кнопками внутри).

  • Полное отключение, при этом включение с отдельной кнопки на передней панели. Если станция выключена – она должна быть полностью гальванически отключена от сети. Сюда же добавим гальваническое отключение нагревателя фена, если рукоятка фена не подключена, а также отключение станции при возникновении нештатных ситуаций (КЗ в нагревателе жала паяльника, превышение допустимых температур, просто по времени простоя).

  • Подключение дымоуловителя.

  • Настраиваемые пресеты: для пары температура / воздушный поток фена, для пары температура / воздушный поток дымоуловителя.

  • Цветной экран, чтобы было и красиво, и удобно. Разумеется, с учетом моих скромных возможностей в графическом дизайне интерфейсов.

  • Возможность измерения рабочего тока жала.

  • Возможность настройки PID.

  • Возможность калибровки температур по нескольким точкам. Пресеты для откалиброванных жал.

  • Программная компенсация температуры холодного спая для термопар с применением NTC термисторов. Где расположен термистор, должно настраиваться (в рукоятке, или использовать размещенный на плате контроллера).

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

Схемотехника

Указанные выше пункты и наличие определенных запчастей вырисовывало следующую картину:

  • В качестве контроллера будет использоваться бюджетный STM32F401RCT6. Всевозможные F407, F446 побережем для задач, требующих большей производительности.

  • Экран будет использоваться TFT 1.77 ‘’ на базе ST7735S с разрешением 160x128 пикселей. Все должно уместиться, фильмы смотреть на нем не предполагается, а после монохромного экрана от Nokia даже такой экран - техническое чудо.

  • Так как будут использоваться и жала с последовательным соединением термопары и нагревателя (T12), и с параллельным с общей землей (С245), то температуру придется измерять в паузах ШИМ. Понадобится нормальный ОУ, способный это сделать достаточно точно, хотелось бы rail-to-rail. В наличии были китайские AD823ARZ, они подойдут. Вход ОУ нужно будет защитить диодом от перенапряжения при включенном ШИМ и переходных процессах, ставим параллельно входу диод, а лучше пару, включенных встречно.

  • Для измерения тока применен ACS712-20A. Конечно, можно обойтись шунтом + LM358, но у нас штучный товар, и хотелось хоть где-то попробовать эти микросхемы.

  • Так как ACS712-20A требует 5В питания, необходимо 2 преобразователя. В качестве преобразователя 24В – 5В, конечно, просится импульсный DC-DC, например TPS5430, но я поставил простой линейный 78M05 с включенным перед ним последовательно резистором на 22 Ома для уменьшения входного напряжения на нем. Места и денег на этом выиграно не много, поэтому если сейчас вы меня спросите почему – я ответить вам не смогу. В общем, решение спорное, и выбор был не очевиден. Если буду делать обновленный вариант платы, то применю импульсный стабилизатор. В качестве преобразователя 5В – 3.3В поставил LM1117-3.3.

  • Настройки будут храниться в I2C EEPROM AT24C32. Писать будем равномерно, так что износиться в этом столетии не должна.

  • В коммутацию нагревателя паяльника на первый взгляд просится N-канальный мосфет. Однако, разумных вариантов использования такого варианта коммутации с картриджами жалами, в которых есть термопара, нет. В общем, проще использовать что-то P-канальное. В наличии были AOD403, я перестраховался (эти транзисторы с TAO-BAO) и поставил 2 в параллель для нагревателя, однако и с одним работает нормально, транзистор холодный. Для турбинки фена и дымоуловителя поставил их же, унификация, как никак. В управление их затворами поставил BC817-40.

  • В каналы измерения температуры NTC поставил супрессоры PESD3V3L1UA.

  • Добавил канал измерения напряжения питания станции. Тут простой делитель.

  • Управлять ШИМ нагревателя термофена будет симистор BTA12-600 с драйвером MOC3063.

  • Управление первичным питанием всей станц��и и отдельно нагревателя фена вынесено на отдельную печатную плату. Коммутация с основной платой через 4-ех проводной шлейф: земля, сигнал включения станции, сигнал подключения нагревателя термофена, сигнал управления симистором. Габариты и крепежные отверстия у плат одинаковы в целях установки единым пакетом через стойки.

PCB

После проектирования платы приняли свой конечный вид. Единственным нюансом в трассировке стало то, что микроконтроллер, его обвязка в виде кварца, EEPROM и еще немного пассивной рассыпухи расположились под TFT экраном. В любом случае экран монтируется последним уже после отмывки платы.

Плата №1 вид сверху
Плата №1 вид сверху
Плата №1 вид снизу
Плата №1 вид снизу
Плата №2
Плата №2

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

Прошивка

Прошивка писалась в STM32CubeIDE с использованием HAL. До чего-то более низкоуровневого я пока не дорос, а HAL позволяет мне в условиях жестко ограниченного на хобби времени создавать рабочие устройства. После Arduino даже HAL, который многие профессионалы, мягко говоря, недолюбливают, дает огромные возможности в плане контроля.

Небольшие пояснения для тех, кто захочет разобраться в творящемся внутри микроконтроллера хаосе.

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

Таймер TIM2 обслуживает ШИМ нагревателя термофена. Коллбек окончания периода таймера вызывает функцию получения результатов от PID регулятора.

Синхронизация работы таймера TIM5 и ADC
Синхронизация работы таймера TIM5 и ADC

Таймер ШИМ нагревателя жала паяльника TIM5 работает на протяжении всего времени работы прошивки, заполнение считается PID регулятором. В коллбеке завершения периода таймера вызывается однократно отрабатывающий таймер TIM10, отсчитывающий задержку на переходные процессы перед вызовом ADC, а также подсчитывается выход PID регулятора для работы паяльника. По завершению работы ADC вновь запускается TIM5, а так же TIM10 (с соответствующим флагом, для последующего запуска ADC и получения тока жала). Таким образом связка TIM10 + ADC отрабатывает дважды за один период таймера ШИМ, на старте периода (для измерения тока) и по его завершению (для измерения все остальных каналов ADC). Коллбек завершения импульса таймера устанавливает флаг слишком короткого импульса для измерения тока в случае, если он вызывается во время работы связки TIM10 + ADC.

Коллбек завершения периода таймера TIM2 (таймер ШИМ для нагревателя термофена)  вызывает подсчет выхода PID регулятора для работы термофена.

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

Коллбеки обработки событий таймеров
void HAL_TIM_PWM_PulseFinishedCallback (TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM5)
  {
    if (flag_ADC_Start)
    {
      flag_ADC_need_restart = true; 
    }
  }
}

void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM2)
  {
    PID_REG_HOTAIR ();
  }

  if (htim->Instance == TIM5)
  {
    HAL_TIM_PWM_Stop_IT (&htim5, TIM_CHANNEL_4);
    HAL_TIM_Base_Start_IT (&htim10);
    flag_TIM5_Pulse_Start = false;
    flag_ADC_Start = true;
    PID_REG_IRON ();
  }

  if (htim->Instance == TIM10)
  {
    HAL_TIM_Base_Stop_IT (&htim10);
    HAL_ADC_Start_DMA (&hadc1, (uint32_t*) &adc, ADC_CHANNELS);
  }

  if (htim->Instance == TIM11)
  {
    flag_update_UI = true;
    IRON_ext_sensor = HAL_GPIO_ReadPin (EXT_SENSOR_GPIO_Port, EXT_SENSOR_Pin);
    IT_SLEEP_count_IRON++;
    IT_SLEEP_count_HOTAIR++;
  }
}

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

Графический интерфейс

Так выглядит основное меню и некоторые из страниц настроек
Так выглядит основное меню и некоторые из страниц настроек

Основное окно интерфейса логически поделено на несколько зон. В верхней зоне отображается установленная температура, установленный поток воздуха, текущая температура. Левая часть относится к паяльнику и дымоуловителю, правая к термофену. Цвет температуры меняется в зависимости от того, включен ли инструмент, находится ли он в подставке, или же вообще отсутствует. В средней части расположены прогресс-бары текущей мощности, номера пресетов температуры для паяльника и термофена соответственно, номер пресета инструмента для паяльника, рабочий ток жала, напряжение питания, режим работы для паяльника и фена (собственно работа, удержание пониженной температуры в подставке, отключение инструмента). В нижней зоне расположены подсказки для навигации по различным меню для четырех кнопок управления.

Все остальные страницы меню выполнены примерно в одном стиле с типовой навигацией с помощью кнопок и изменением значений при помощи энкодеров.

Практически все, что может быть настроено, можно изменить и сохранить в EEPROM, не прибегая к редактированию исходников и перепрошивке.

Текущие настройки:

Настройки для паяльника/термофена:

MIN TEMP – минимальная температура, которую можно установить

MAX TEMP – максимальная температура, которую можно установить

STEP TEMP – шаг изменения температуры

MIN FLOW – минимальный поток воздуха, который можно установить

MAX FLOW - максимальный поток воздуха, который можно установить

STEP FLOW – шаг изменения потока воздуха

TOOL NTC – выбор NTC, установленного в рукоятке

TOOL SENSOR – установлен ли в ручке сенсор

SLEEP TIMER – время, через которое инструмент перейдет в режим HOLD, будучи установленным в подставку

Дополнительные настройки:

INT NTC – выбор встроенного в плату станции NTC

0 CURRENT – показания АЦП для нулевого тока ACS712-20A

K CURRENT – коэффициент коррекции для измерения тока жала

K VOLTAGE – коэффициент коррекции для измерения напряжения блока питания

K INT NTC – коэффициент коррекции для измерения температуры встроенным NTC

K IRON NTC – коэффициент коррекции для измерения температуры NTC, встроенным в рукоятку паяльника

K HOTAIR NTC – коэффициент коррекции для измерения температуры NTC, встроенным в рукоятку фена

TIME OFF – время перехода инструмента из режима HOLD в режим OFF

OVERCURRENT – максимальное значение тока жала паяльника. При превышении нагрев прекращается

Настойки для конкретных инструментов:

P – коэффициент P для PID регулятора выбранного инструмента

 I - коэффициент I для PID регулятора выбранного инструмента

 D - коэффициент D для PID регулятора выбранного инструмента

 ADC (Δ 0°C) - ADC (Δ360°C) – показания АЦП при заданной дельте температуры термопары и холодного спая.

Корпус

Вид изнутри
Вид изнутри

Контроллер из двух плат, соответствующий блок питания (24V, 12.5A), колодка для подключения внешнего кабеля питания и вентилятор для обдува внутреннего содержимого были установлены в напечатанный на FDM принтере из серого PLA корпус. Рукоятки для энкодеров и щиток, закрывающий щели у экрана, напечатаны на SLA принтере из серой ABS-like смолы. Размеры готового блока 19x11x18 см, которые можно значительно сократить, применив более плотную компоновку блока питания и разъемов, а также версию вентилятора с толщиной 10 мм.

Итоги

Что же в итоге? На выходе получился вполне рабочий вариант инструмента с возможностью его полной адаптации под себя и свои нужды.

Лицевая панель
Лицевая панель

Плюсы:

  • Опыт. Программирование STM32 в CubeIDE для меня - значительный шаг вперед после Arduino.

  • Полная кастомизация устройства и адаптирование под себя по мере необходимости.

  • Станция паяет. Жала C245 себя полностью оправдали, они действительно оказались намного производительнее T12. Там, где раньше приходилось ставить более крупное жало, теперь вполне справляется наиболее ходовой у меня размер BC1.6. А если воткнуть BC5, то размер полигона становится совершенно не важен. В плане термофена никаких неожиданностей – то, что раньше работало на Atmega328 с обычным пропорциональным регулятором, так же отлично работает и с PID регулятором.

Минусы:

  • Потраченное время. От идеи до готового устройства прошел год, разумеется, с учетом лишь периодической работы над ним. Лично для меня минусом не является (не считаю, что время, потраченное на хобби, стоит расценивать как упущенное), однако многие выберут вариант получить готовое устройство здесь и сейчас.

  • Наверняка, не самые оптимальные алгоритмы работы. Я уверен, что инженеры из того же AiXun намного сообразительнее меня, и их устройство позволяет полнее раскрыть потенциал жал C245.

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

  • Разъем для заливки прошивки стоило разместить со стороны лицевой панели. Еще более интересным вариантом было бы вывести USB и применить небольшой bootloader для заливки прошивок по USB без программатора.

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

Репозиторий на Github для тех, кто захочет посмотреть проект подробнее.