Авторизация
Регистрация

Напомнить пароль

Прибор для измерения мгновенного тока потребления электродвигателя

В данной статье пойдет речь о простом самодельном амперметре, способном производить непрерывные измерения силы тока 150 раз в секунду, высчитывать минимальное, максимальное и среднеквадратическое значение, а также строить небольшой график изменения силы тока во времени. Дополнительно прибор позволяет контролировать температуру устройства и выдавать предупреждающие звуковые сигналы при его перегреве. Прибор построен на основе микроконтроллера Microchip ATtiny85, монохромного OLED-дисплея разрешением 128х64 точек, а также самодельного импульсного источника питания. Если описание вас заинтересовало, то садитесь поудобнее и будем начинать, но сразу предупреждаю, текста в этот раз получилось много.


Предыстория или зачем это вообще нужно?

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

На самом деле, я бы купил её и значительно раньше, так как давно задавался таким вопросом, но очень смущала необходимая ей площадь в квартире, ведь это практически 2 квадратных метра, а дорожка — не третий по счету 3D-принтер по акции, место для которого найдется всегда. И тут вдруг в начале этого года внезапно была разобрана лоджия, образовалось достаточное свободное пространство, которое можно было занять без ущерба бытовой повседневной жизни, и звезды, наконец, сошлись.

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

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

Когда с моделью определились, стали искать, где её можно приобрести, да не просто приобрести, а еще и с доставкой в нашу «глубинку». И это стало дополнительным квестом, т.к. далеко не все продавцы предлагают доставку крупногабаритного товара до квартиры, у многих доставка предлагается только до подъезда, а дальше уже мучайся как хочешь – или знакомого бери, или водителя уговаривай, или отдельных грузчиков нанимай. Ситуацию еще осложняет временной диапазон доставки, который в большинстве случаев покрывает весь световой день, а о конкретном времени тебя известят только за 10-30 минут до непосредственно самого момента доставки. То есть, даже нанять грузчиков заранее не выйдет. Но и эта проблема, в конечном счете, была разрешена и продавец с доставкой непосредственно до квартиры был найден. Правда, он не предлагал совершенно никакой услуги сборки, но к тому времени я уже посмотрел пару роликов по сборке дорожки на ютюбе, поэтому был морально (и физически) готов собрать её самостоятельно.

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

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

Последующая эксплуатация дорожки как будто и не заслуживает дополнительного внимания, так как она совершенно стандартная – включил, выбрал скорость и наклон, включил на планшете любимый канал и пошел совмещать приятное с полезным. И тут, кстати, размещение дорожки на лоджии имеет неоспоримый плюс – всегда можно открыть окно на улицу и добавить к своему увлекательному путешествию на одном месте аромат и ветерок настоящего свежего воздуха – прямо 5D-погружение, как в современном кинотеатре.

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

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

Резюмируя произошедшее, по какой-то причине на дорожке за такой короткий промежуток времени износилось беговое полотно, у него поднялось механическое сопротивление движению, что увеличило нагрузку на мотор, который такого не выдержал, начал сильно греться и вонять. Да, несмотря на то что на дворе 2025 год, в дорожке стоит обычный коллекторный мотор постоянного тока 180 В 7.5 А (то есть, 1350 Ватт при заявленной мощности дорожки 3.25 лошадиных силы), на котором даже нет минимального термодатчика, позволяющего контроллеру следить за температурой двигателя! И это при цене изделия в 70 тысяч.


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

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

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

Технические характеристики

Чтобы понимать, что, собственно, надо сделать, начал проектирование устройства с желаемых технических характеристик:

  • Измерение тока не менее 100 раз в секунду.
  • Отображение текущего, а также минимального и максимального значения тока за последнюю пару секунд.
  • Точность не хуже 0.1 А.
  • Максимальный измеряемый ток до 20 А в пике, 10 А долговременно.
  • Построение небольшого графика тока потребления за последнюю пару секунд – поможет выявить какие-либо отклонения в работе.
  • Контроль температуры двигателя с помощью внешнего термодатчика.
  • Выдача предупреждающего звукового сигнала при слишком высоком нагреве двигателя.
  • Собственный блок питания устройства, чтобы исключить какое-либо вмешательство в электрическую схему и плату контроллера дорожки.
  • Простота решения, чтобы устройство можно было быстро реализовать на имеющихся компонентах без необходимости закупки и ожидания доставки новых.

Немного подумав над элементной базой, остановился на следующих компонентах:

  • Шунт 5 мОм из манганина. Комплект таких я покупал при изготовлении зарядки для Макиты, там они показали себя крайне хорошо. При токе 10 А на шунте будет падать 50 мВ и 0.5 Вт, что, с одной стороны, вполне достаточно для измерения, а с другой стороны не будет приводить к чрезмерному его нагреву.
  • Микроконтроллер ATtiny85. Покупались давно, но всё еще есть в наличии, так как использовались редко. В принципе, это достаточно слабый МК с маленьким количеством выводов, но для данной конкретной задачи его возможностей должно хватить, всё же он имеет 8 КБ ПЗУ и 512 байт ОЗУ. Зато его система команда и архитектура давно мне известна, что серьезно упростит написание программного кода. Также у ATtiny85 оказалась «киллер-фича», сделавшая его еще более подходящим – у его АЦП есть режим дифференциального измерения со встроенным усилителем с коэффициентом усиления 20. То есть, он сможет считывать напряжение прямо с шунта без дополнительного ОУ.
  • Монохромный OLED-экран 0.96 дюйма с разрешением 128х64 точек и подключением по протоколу I²C. Он просто был, давно лежал и «просился» поставить его куда-нибудь, но для большинства задач его размер оказывался слишком маленьким, а вот для данной – самое то.
  • В качестве датчика температуры двигателя решил использовать имеющиеся микросхемы TMP100. Они хорошо зарекомендовали себя в предыдущих проектах, имеют разрешение 0.06 градуса, а также работают по протоколу I²C, что позволит подключить такой датчик прямо параллельно дисплею и не потребует дополнительных выводов МК.

Поскольку общее максимальное потребление устройства я оценил как 5 В 200 мА, первоначально для его питания хотел использовать самую слабую из имеющихся готовых плат блоков питания на напряжение 5 В, однако, чуть поразмыслив решил и блок питания сделать свой. А что, ведь раньше я любил этим занимался, почему бы не вспомнить былые времена? Так как мощность нужна минимальная, делать решил на самом младшем ШИМ-контроллере серии TNY27x, который у меня есть, и им оказался TNY275. Обратноходовый БП на этом контроллере предельно прост, требует минимум внешних деталей и не нуждается в отдельной обмотке трансформатора для питания контроллера, так как контроллер умудряется питаться непосредственно от высокого напряжения. То есть, бери и делай, остается только трансформатор посчитать.

Схема

Полистав документацию на выбранные компоненты, нарисовал следующую схему устройства:


Входное напряжение 220 В через гасящий резистор R6 и предохранитель F1 поступает на диодный мост D1. Резистор и предохранитель специально установлены в разных сетевых проводах – поскольку цепь двигателя, куда будет подключаться устройство непосредственно связана с сетью (об этом расскажу чуть подробнее далее), и если в устройстве вдруг произойдет какой-либо пробой, ток короткого замыкания пойдет только по одному из двух сетевых проводов, причем неизвестно заранее, по какому именно, поэтому каждый из них должен иметь какую-либо защиту.

После диодного моста установлен накопительный конденсатор С1 ёмкостью 2.2 мкФ. Традиционно при разработке импульсного БП для напряжения 220 В придерживаются эмпирического соотношения 1 мкФ ёмкости накопительного конденсатора на 1 Вт выходной мощности, однако у меня в наличии оказались конденсаторы на 2.2 мкФ, поэтому решил ставить такой. Дальнейшая высоковольтная часть схемы блока питания стандартная и взята непосредственно из даташита на ШИМ-контроллер, поэтому детально разбирать её не буду. Отмечу только, что с помощью конденсатора С2 ёмкостью 1 мкФ ШИМ-контроллер переводится в режим пониженного тока (режим совместимость с предыдущей моделью TNY274), а также что схема снаббера тут более сложная – и на конденсаторе, и на супрессоре.

Вторичная цепь блока тоже достаточно стандартная, это выпрямитель и стабилизатор напряжения на TL431 с обратной связью через оптрон. Резистор R4 параллельно светодиоду оптрона необходим для того, чтобы ток холостого питания TL431 не вызывал свечения диода и, таким образом, не передавал сигнал обратной связи контроллеру постоянно. Конденсатор С5 в цепи обратной связи TL431 оказался не нужен, блок работает лучше без него (это связано с особенностью ШИМ-контроллера), однако место на плате под него я решил оставить, поэтому на схеме его ёмкость обозначена как 0 нанофарад.

Напряжение с выхода блока питания подается непосредственно на дисплей, схему зуммера и датчик температуры, а вот микроконтроллер питается через дополнительный двойной фильтр на дросселе L3 и резисторе R17, призванном минимизировать помехи от работы блока. Скорее всего, применение двухзвенного LRC-фильтра тут излишне, хватило бы и однозвенного LC-варианта, но в какой-то момент я почему-то решил, что нужно именно два звена.

Для подключения датчика температуры и дисплея на плате устройства предусмотрены два отдельных разъема I²C, соединенных параллельно. Также к контроллеру подключен разъема SPI для осуществления его внутрисхемного программирования.

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

Ну и, наконец, токоизмерительным шунтом схемы являются пара резисторов R19/R29, включенных параллельно. В реальности на плате будет установлен только один из них, потому что для моей задачи сопротивление в 5 мОм является оптимальным. Однако, если вдруг схему захочется использовать для другого диапазона измерения, я предусмотрел возможность установки двух резисторов типоразмера 2510 параллельно. Сигналы с шунта через резисторы R10 и R11 подаются на соответствующие входы АЦП МК, образуя совместно с конденсаторами С10 и С11 ФНЧ для фильтрации высокочастотных помех.

Шунт установлен в схеме так, что его нижний конец оказывается жестко заземлен и, таким образом, инверсный вход АЦП всегда сидит на земле, что фактически превращает дифференциальный вход АЦП в однополярный. Да, действительно, в данном устройстве нет необходимости в дифференциальном АЦП, потому что схема имеет свой собственный блок питания и ток нагрузки ни коим образом не проходит по питающим дорожкам платы, то есть, не создает на них никакого дополнительного падения напряжения. Однако, режим усиления 20х в АЦП МК доступен только в дифференциальном варианте включения, поэтому пришлось реализовывать именно его. Но зато это позволит быстро перепрофилировать устройство на питание от измеряемой схемы, если вдруг это понадобится для какой-либо другой задачи.

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


Чтобы было более понятней, я частично нарисовал основные высоковольтные цепи блока управления дорожкой, прозвонив их предварительно мультиметром. Вопрос вызывает лишь шунт R1 на плате контроллера – его я визуально не увидел, а мультиметром найти такие вещи нельзя, т.к. его сопротивление составляет всего единицы миллиом, как и в моем устройстве. Однако, он определенно должен быть, так как контроллер должен следить за потреблением двигателя, поэтому будем считать, что он есть. Возможно, он в SMD-исполнении и находится с нижней стороны платы, куда обзор закрыт алюминиевой защитной пластиной.

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

Также из схемы становится понятно, что высоковольтные части двух разных блоков питания оказываются дополнительно соединены через межобмоточную ёмкость трансформатора Т1 и через защитный конденсатор С7. То есть, подключение амперметра в цепь двигателя добавляет к ней дополнительную ёмкость, и, например, включить его в разрыв плюсового провода двигателя уже было бы нельзя, ведь эта ёмкость оказалась бы подключена к точке соединения силовых транзисторов и очень негативно влияла бы на их переключение. К счастью, в минусовом проводе она никакого влияния оказывать не будет, так как там ожидается только наличие шунта, параллельно которому и так должен стоять какой-либо фильтрующий конденсатор.

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

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

Расчет трансформатора

Поскольку основные рабочие параметры у TNY275 фиксированные, расчет трансформатора для преобразователя значительно упрощается – нет необходимости заниматься выбором тока ключа и расчетом передаваемой энергии, трансформатор рассчитывается и изготавливается под те параметры, которые имеет ШИМ-контроллер. Вот и начнем с того, что выпишем их из даташита:

F = 132 KHz
Fmax = 140 KHz
Tmin = 7.14 мкс
Dmax = 65%
I = 250 mA
Imax = 300 mA (с запасом)

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

Возьмем отраженное рабочее напряжение в первичной обмотке Uinv = 150 В. Такое значение, с одной стороны, обеспечит достаточно быстрый «разряд» индуктивности, с другой – относительно невысокое напряжение на закрытом ключе (~310 В + 150 В = ~460 В при максимально допустимом 700 В). Dmax у TNY275 составляет 65%, что дает рабочие временные характеристики Tonmax = 4.64 мкс и Toffmin = 2.5 мкс. Так как количество энергии, которое входит в катушку за Ton должно равняться количеству энергии, которое выходит из неё за Toff, отношение данных временных характеристик (1.856) определяет минимальное напряжение, от которого преобразователь всё еще сможет работать на полной мощности (если вам что-то непонятно, задавайте вопросы в комментариях, я поясню). В данном случае оно составит Uinv/1.856 = 81 В, что очень даже неплохо (хотя и совершенно не нужно для разрабатываемого устройства).

Теперь у нас есть вся необходимая информация, чтобы рассчитать индуктивность первичной обмотки. Она должна быть такой, чтобы при напряжении 81 В ток в ней поднялся до 250 мА за 4.64 мкс:

L1 = (UΔt)/I = (81*4.64*10⁻⁶)/0.25 = 1.5 мГн

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

Aimp = (LI²)/2 = (1.5*10⁻³*(0.25)²)/2 = 46.9 мкДж
P = Aimp*F = 46.9*10⁻⁶*132000 = 6.2 Вт

То есть, преобразователь на TNY275 с таким трансформатором вполне мог бы обеспечить на своем выходе 5 В 1 А во всем диапазоне входного питающего напряжения от 100 до 230 В! Неплохо, конечно, но мне нужно всего 1 Вт, поэтому мотать трансформатор я буду на самом маленьком сердечнике, который только у меня есть:


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

Площадь магнитопровода S = 2.5*4.8 = 12 мм²
Средняя длина магнитной линии l = 30 мм
Зазор g = 0.6 мм

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

L = (µ₀*S*N²)/g

Или

N = sqrt((L*g)/(µ₀*S)) = sqrt((1.5*10⁻³*0.6*10⁻³)/(4π*10⁻⁷*12*10⁻⁶) = 244 витка

А теперь проверим результат, сравнив его с измеренной индуктивностью изначально намотанной на сердечнике обмотки, которая составила 2.13 мГн для 256 витков. Т.к. индуктивность пропорциональна квадрату числа витков, при таких исходных данных получим, что для 1.5 мГн надо всего 215 витков. 215 и 244, конечно, числа близкие, однако всё равно отличаются друг от друга достаточно сильно, поэтому я предпочту использовать данные, полученные практическим путем – так результат будет более точным. Ведь формула, которую я представил выше – приближенная, если углубляться во все детали теории электромагнитного поля, на точный расчет одного трансформатора не хватит даже объема всей статьи.

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

Imax = (Bmax*g)/(µ₀*N) = (0.25*0.6*10⁻³)/(4π*10⁻⁷*215) = 555 мА

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

Посчитаем число витков во вторичной обмотке. Если в первичной обмотке будет 215 витков при напряжении 150 В, для получения 6 В во вторичной обмотке понадобится 215*6/150 = 8.6 витка. Так как намотать 8.6 витка нельзя, следует выбрать одно из двух ближайших целых значений – 8 или 9 витков. Если взять 8 витков, напряжение на вторичной обмотке получится 5.58 В, если же взять 9 витков, напряжение будет 6.28 В. Так как падение напряжения на выпрямительном диоде может составить 0.8 – 1 В, в принципе, можно выбрать любое из этих значений. Я возьму 9 витков – это даже чуть уменьшит отраженное напряжение в первичной обмотке (до примерно 143 В).

Наконец, остался последний момент – выбор толщины провода для обмоток. По-хорошему, диаметр провода выбирается исходя из среднеквадратического значения тока, но я поступлю проще – изначальная обмотка из 256 витков была намотана проводом диаметром 0.18 мм без какой-либо межвитковой изоляции и занимала практически все место на каркасе. Мне надо намотать чуть меньше витков, но нужна изоляция и вторичная обмотка, так что проводом 0.18 мм намотать первичку я уже не смогу – для него просто не хватит места. То есть, надо брать что-то потоньше. Оптимально, наверное, был бы провод диаметром 0.15 мм, но у меня такого нет, есть только 0.11 мм. Значит, им и буду мотать, и тогда гарантированно освободится достаточно места для межвитковой изоляции и вторичной обмотки, для которой я уже возьму провод потолще, скажем, 0.35 мм.

Итого, имеем следующие данные для намотки:

Первичная обмотка – 215 витков провода диаметром 0.11 мм.
Вторичная обмотка – 9 витков провода диаметром 0.35 мм.

Теперь можно приступить непосредственно к намотке трансформатора. Первым делом я намотал на голую катушку два слоя каптонового скотча – он немного сгладит углы, уменьшая возможные повреждения изоляции провода, а также создаст дополнительную изоляцию обмотки от катушки. Затем намотал первую половину (110 витков) первичной обмотки и снова проложил два слоя скотча, после чего намотал вторую половину (105 витков). Финальную изоляцию между обмотками делал также из каптонового скота, только уложил его уже в 4 слоя. После намотки первичной обмотки временно вставил половинки сердечника в катушку и замерил получившуюся индуктивность:


Шикарная точность, отклонение от требуемой индуктивности получилось менее 1%! После замера я снова вынул сердечник и намотал поверх изоляции вторичную обмотку из 9 витков, после чего замотал весь трансформатор своим любимым зеленым малярным скотчем:


После сборки трансформатора я повторно замерил индуктивность первичной обмотки, и она чуть возросла – стала примерно 1.53 мГн. Произошло так потому, что скотч сильнее прижал половинки сердечника друг к другу и, таким образом, уменьшил немагнитный зазор. Но это не страшно, отклонение получилось очень незначительное. Также попробовал замерить и индуктивность рассеяния – делается это достаточно просто, во время измерения индуктивности первичной обмотки вторичная замыкается накоротко. Это как бы замыкает и всю ту часть первичной обмотки, которая связана со вторичной, оставляя для измерения лишь несвязанную часть, которая и называется индуктивностью рассеяния. Результат получился весьма высоким – на частоте 100 КГц индуктивность рассеяния составила порядка 210 мкГн.

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

Плата

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

Сначала я расположил все детали в длинную узкую полоску, но потом понял, что плату такой длины я не смогу поместить в свой фотополимерный принтер (он у меня достаточно маленький), поэтому перекомпоновал плату в более квадратную, всё равно места в корпусе дорожки достаточно:


Дальше последовала стандартная процедура изготовления односторонней печатной платы с помощью фоторезиста. Поскольку делаю я платы мало, у меня еще не израсходовался старый Ordyl 350, срок годности которого закончился аж в 2017 году, так что снова использовал его. Как видите, он еще работает, правда, в этот раз мне показалось, что плата получилась чуть похуже, чем раньше. Возможно, пора придется переходить на более свежие запасы.


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


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

Далее я решил проверить, насколько сильно блок греется от расчетной нагрузки в 200 мА. После 30-ти минут работы платы на открытом воздухе картина нагрева была такой:


Видно, что вся плата нагрета более-менее равномерно – температура и ШИМ-контроллера, и трансформатора, и снаббера составила порядка 42 градусов. Чуть сильнее грелся только выходной диод, его температура приближалась к 50-ти градусам. Но для электронных компонентов это сущие мелочи, поэтому можно смело считать, чтоб блок питания сможет выдать 1 Вт выходной мощности в любых разумных условиях эксплуатации.

Пульсации напряжения на выходном конденсаторе получились в районе 40 мВ PP:


После LCR-фильтра (без нагрузки) амплитуда пульсаций упала и составила менее 5 мВ РР:


Тогда я собрал остальную часть платы:


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

Теперь перейдем к датчику температуры TMP100. Чтобы ускорить процесс, я взял одну из имеющихся у меня печатных плат, которые остались от предыдущих проектов. Выбрал самую маленькую, где не разведены перемычки, позволяющие изменять адрес датчика на шине I²C. Датчик должен подключаться к основной плате устройства с помощью четырехпроводного кабеля, и вот тут, вспомнив про то, что ШИМ-контроллер дорожки может создавать сильные помехи, я захотел использовать экранированный кабель. Но где его взять?

Выручил Чиподип – оказалось, что нашем городе в наличии есть волшебный четерыхпроводный экранированный микрофонный кабель КММ-4х0.12 в шикарной толстой ПВХ-изоляции, способной выдержать аж 600 В! Последний момент очень важен, ведь через блок управления дорожкой низковольтная часть амперметра тоже оказывается связанной с сетью, а металлический корпус дорожки, рядом с которым будет проходить кабель заземлен. То есть, между экраном кабеля и корпусом дорожки будет действовать полное сетевое напряжение, поэтому изоляция кабеля должна быть достаточно надежной.

Итак, кабель был куплен, после чего датчик был запаян на плату:


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

С другой стороны кабеля я установил стандартный 4-контактный JST-разъем с шагом 2.54 мм, где уже соединил экран с общим проводом питания схемы:


После чего затянул датчик в термоусадку:


По мне, получилось весьма красиво. Когда все части устройства были собраны, провел еще одно испытание самодельного блока питания, но теперь уже с реальной нагрузкой. Оказалось, он вполне запускается от постоянного напряжения 30 В на входе! И потом сохраняет нормальную работу при его снижении чуть ниже 20 В! Выглядело это просто нереальным, ведь это в 10 раз меньше номинального значения, но такие уж особенности у обратноходовых блоков питания. По входу, кстати, потребление составило около 150 мВт, то есть, намного ниже 1 Вт, на который я рассчитывал изначально.

Корпус

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

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


А корпус и крепление дисплея к трубе получились такими:


Внешне корпус дисплея очень похож на наручные часы и состоит из четырех частей – собственно корпуса, стекла дисплея, дужки крепления на трубу и маленькой планки прижима кабеля. Стекло я вырезал из какой-то прозрачной упаковки от конфет, а остальные детали напечатал:


Для крепления частей друг к другу в основном корпусе дисплея сделаны полости, куда необходимо вплавить обычные гайки М3 – в них со стороны дужки будет закручиваться винт с шестигранной головкой. Сам дисплей и планка прижима кабеля будут закреплены мелкими саморезами 2х6. С основным блоком, находящемся в моторном отсеке дисплей будет соединен тем же экранированным микрофонным кабелем КММ-4х0.12, что и датчик температуры. Экран здесь я тоже решил подключать к общему проводу только со стороны платы.

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

А вот установка дисплея в корпус оказалась еще более сложной задачей. При проектировании я учитывал размер платы дисплея, и она сама в корпус входила нормально, хоть и чуть впритык. Но при сборке я решил сначала припаять к плате кабель, чтобы сделать это красиво и в свободной обстановке на столе, а плату поместить в корпус уже потом. И вот тут меня ждало фиаско – с подпаянным кабелем плату совершенно не удавалось расположить под тем углом, под которым она проходила бы в корпус. Помучившись некоторое время, я неудачно схватил плату пинцетом и отколол сбоку от дисплея маленький кусочек стекла. Вроде как он ни за что на дисплее не отвечает, однако после откалывания у изображения пропали все четные строки. Пользоваться таким дисплеем было уже нельзя.

Вдвойне усиливало проблему то, что дисплей этот был у меня в единственном экземпляре, второго такого в наличии не было. На часах был час ночи по московскому времени, все радиомагазины города были, естественно, закрыты, поэтому изрядно расстроенный я пошел копаться в своей коробке с околоардуиновыми платами. И вдруг совершенно случайно нашел там похожий дисплей, только с несколько другой платой, сконфигурированной для подключения по протоколу SPI. Но на плате были указания, как переключить её на протокол I²C, что я и попытался сделать:


Я перепробовал несколько разных вариантов и, конечно, у меня ничего не вышло, плата по I²C не заработала. Переделывать готовый код на SPI совершенно не хотелось, но тут вдруг я осознал, что можно просто перепаять сам дисплей с контроллером с этой платы на предыдущую, ведь у них совершенно одинаковые шлейфы. С помощью жала 1402 для Т12 сделать это оказалось совершенно несложно, его ширина идеально совпала с шириной шлейфа, и где-то к двум часам ночи дисплей был восстановлен. Небольшим удивлением для меня оказался его цвет – предыдущий OLED был голубым, а этот оказался белым, но внешне это выглядело даже более красиво.

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


Поскольку дисплей будет находиться достаточно далеко от основной платы, длина соединительного кабеля тоже вызывала у меня опасения – будет ли работать весьма высокоомная шина I²C с кабелем такой длины? Но эти опасения развеялись очень быстро, когда после сборки дисплея я подключил его к плате через весь остаток кабеля длиной 4.5 метра, и дисплей прекрасно заработал. Если уж через такое расстояние работает, то через полтора (которые мне нужны) будет работать абсолютно точно.

На следующий день мне, наконец, удалось установить всё на беговую дорожку. Плату приклеил скотчем к основанию моторного отсека, как и хотел:


А дисплей установил на трубу и затянул винтами:


Во включенном состоянии это выглядит так:


Интерфейс пользователя

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

Так как дисплей монохромный, один байт данных отвечает за отображение сразу 8-ми пикселей на экране. С точки зрения слабого МК ATtiny это удобно, ведь надо передавать меньше данных. А вот с точки зрения компоновки изображения – нет, ведь соседние элементы интерфейса могут попасть в один и тот же байт дисплея и их надо будет как-то совмещать программно. Еще надо учитывать, что байты данных у этого контроллера дисплея расположены вертикально, а не горизонтально, как мы привыкли, то есть, один байт заполняет сразу 8 строк в одной колонке экрана.

Еще немного подумав, я понял, что эта особенность даже мне на руку – достаточно сделать шрифт высотой 8, 16 или 24 пикселей и тогда никакого наложения элементов интерфейса никогда не произойдет, каждый из них будет находиться целиком в своем байте. Проведя небольшой эксперимент, я понял, что оптимальным для меня будет шрифт высотой 16 пикселей, так как шрифт высотой 8 выглядит нереально маленьким, а со шрифтом высотой 24 или больше на экран влезет слишком мало информации.

Готового шрифта подходящего размера я не нашел, поэтому как во времена Спектрума просто нарисовал по пикселям в фотошопе свой, тем более, мне не нужны все 96 символов ASCII, достаточно было нарисовать и закодировать лишь те, которые я буду использовать. Ими оказались 10 цифр, стрелки вверх и вниз, заглавная буква «А», значок градуса, 5 картинок небольшой звездочки и, как ни странно, пробел:


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


Программный код

Задача у программного кода амперметра, в целом, несложная – считывать данные с АЦП и датчика температуры, сохранять в память, преобразовывать в числовые значения и отображать на дисплее. Ну, и еще пищалкой управлять. Но обо всем по порядку.

I²C

У ATtiny85 есть аппаратная поддержка последовательных протоколов, но она сильно кастрированная. Например, сдвиговый регистр вроде и аппаратный, но управлять им, включая сдвиг битов, надо программно. Тем не менее, буду использовать что есть и начну с поддержки протокола I²C.

Сам протокол, по сути, достаточно простой и состоит из двух сигнальных линий – тактовой SCL и линии данных SDA. На шине может сидеть много устройств, которые делятся на два класса – главные (Master) и подчиненные (Slave). Главные устройства управляют шиной и генерируют тактовые импульсы, а подчиненные – только пляшут под их дудку. Все устройства имеют выходы с открытым коллектором (стоком), а сама шина подтянута к плюсу питания через резисторы, что создает аппаратное объединение сигналов по AND и не вызывает физических проблем, если вдруг два устройства заходят вывести на одну шину разные уровни. Для шины определены несколько сценариев использования, основные из которых – Start, Stop, Repeated Start, Master Write и Master Read. Передача каждого байта данных физически занимает 9 бит, так как предусматривает 9-й бит ответа от принимающего устройства, которое должно подтвердить прием. Стандартной (высокой) частотой следования тактовых импульсов для I²C считается 400 КГц.

Любую передачу данных всегда инициирует главное устройство, она начинается со сценария Start, после чего Master передает 7-битный адрес подчиненного устройства и 8-й бит типа операции – чтение (1) или запись (0). Если адресованное подчиненное устройство есть на шине, оно отвечает 9-м битом низкого уровня (ACK), если же его нет или оно не в настроении отвечать (такое тоже возможно), оно ничего не делает и за счет подтяжки к плюсу на шине формируется сигнал высокого уровня, который расценивается мастером как NACK.

Если изначально была инициирована команда записи (Master Write), после передачи адреса и получения ACK мастер начинает передавать данные. Подчиненное устройство подтверждает прием каждого байта отдельным ACK’ом, а если такого не случилось, передачу требуется прервать. Если же была инициирована команда чтения (Master Read), то после передачи адреса и получения от подчиненного устройства ACK, мастер начинает генерировать тактовые импульсы на шину, а данные передает подчиненное устройство. В этом случае уже мастер должен подтверждать получение каждого байта отправкой ACK. Транзакция завершается сценарием Stop или Repeated Start. Последний эквивалентен двум последовательным сценариям Stop + Start, однако позволяет не терять владения шиной (для шин с одним мастером не актуально).

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


Если посмотреть код внимательно, будет видно, что, по сути, аппаратная поддержка I²C в ATtiny85 не очень-то и упрощает задачу – всё то же самое можно было бы легко сделать и на чистых операциях ввода/вывода в порты. Кстати, если кто вдруг не знает как в этом случае реализовать выход с открытым стоком, то это очень просто – в сам порт выводим постоянное значение 0, а вывод данных осуществляем переключением режима работы порта на ввод (при выводе логической 1) или на вывод (при выводе логического 0).

Да, еще один важный момент – скорость передачи данных. Поскольку аппаратная поддержка I²C в МК очень слабая, тайминги приходится соблюдать программно, для этого я написал две функции задержки на ассемблере:


Для правильной работы этих функций необходимо предварительно определить две константы — CPU_SPEED_KHZ и I2C_SPEED_KHZ. Из названий понятно, что они задают скорости работы процессора МК и шины в килогерцах. Исходя из этих констант рассчитывается, сколько пустых циклов необходимо сделать процессору, чтобы добиться нужной задержки между сигналами. Если необходимости соблюдать строгие тайминги нет и нужна максимальная скорость, можно определить макрос I2C_MAX_SPEED, и тогда задержки превратятся в вызовы пустых функций.

Дисплей

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


Теперь пришло время для вывода текста. Поскольку байты у контроллера дисплея располагаются вертикально, логично и вывод делать не по привычной схеме вправо-вниз, а по обратной – сначала вниз, потом вправо, благо контроллер такой режим поддерживает. Тогда и шрифты в памяти можно хранить в таком же формате. Поскольку все символы имеют строго одинаковую высоту и отличаются только шириной, решил не создавать отдельной структуры, описывающих каждый символ, а просто хранить массив указателей на них. Тогда ширину символа можно будет вычислить по разности между адресом начала текущего и следующего символов непосредственно при выводе. В итоге, код вывода даже обошелся даже без ассемблера:


Ну, и, конечно же, для преобразования числа в строку перетащил из своего предыдущего проекта функцию I16ToString. Поскольку операции деления в AVR не завезли, работает она по принципу циклического вычитания и написана, соответственно, на ассемблере. Если интересно, её код можно посмотреть в исходниках.

АЦП

Так как в данном устройстве считывать надо всего лишь один канал, решил, что АЦП будет уместно работать в автоматическом непрерывном режиме. В документации пишут, что оптимальной для АЦП является частота тактирования от 50 КГц до 200 КГц, поэтому выбрал коэффициент деления 128, что дает частоту 125 КГц. Каждое преобразование занимает 13 тактов АЦП, то есть, в итоге я буду получать примерно 9615 преобразований в секунду. Это сильно больше, чем мне надо, поэтому сразу решил складывать результат 64 последовательных преобразований. Почему именно 64? Во-первых, это понижает результирующую частоту до подходящих для меня 150 измерений в секунду, во-вторых, АЦП в AVR 10-битный и максимально возможное оцифрованное значение – 1023, то есть, сумма из 64-х таких значений всё еще умещается в 16-битную переменную.

Если вспомнить изначальные требования, я хотел выводить на экран график потребления дорожки в реальном времени. Экран имеет ширину 128 точек, то есть, для вывода графика мне нужно 128 последних измерений. Но если АЦП будет производить 150 измерений в секунду, на экран не влезет статистика даже за последнюю секунду, а это значительно снизит её информативность. Поэтому решил обновлять график один раз в три измерения АЦП – это и хорошую скорость обновления в 50 Гц даст, и позволит на экране отображать статистику за последние 2.5 секунды. Также из этого буфера я буду брать минимальное и максимальное значения, чтобы тоже выводить их на экран в численном виде.

Но тут возникает вопрос, как правильно усреднить три измерения в одно? Конечно, можно найти среднее арифметическое, но это будет означать, что фактически у меня останется лишь 50 измерений в секунду, а это уже мало. Поэтому я решил не усреднять их никак – буду считать минимальное и максимальное значение из трех, и график буду выводить не точкой, а отрезком от минимума до максимума, потому что это значительно улучшит визуальное отображение. В итоге, алгоритм получился такой – прерывание АЦП производит 150 измерений в секунду, в каждом из которых обновляет две глобальных переменных g_adcValueMin и g_adcValueMax. А основной код 50 раз в секунду считывает и сбрасывает эти значения, начиная, таким образом, новый цикл измерений.

Вывод графика

Для вывода графика тока потребления мне нужно хранить в ОЗУ МК результаты последних 128-ми измерений АЦП. Но каждое измерение теперь состоит из двух значений – минимума и максимума, то есть, мне нужно хранить в памяти МК 128 пар 16-битных значений или 512 байт данных. Выбранный МК имеет всего 512 байт ОЗУ, и очевидно, что какую-то его часть надо оставить под служебные нужны, например, под стек, значит, хранить такой объем данных я просто не могу. Поэтому я решил хранить не сырые 16-битные значения, а уже вычисленные значение тока, которые имеют две цифры после запятой и, таким образом, вполне умещаются в 12 бит с максимально возможным значением 40.95 А (то есть, даже в два раза больше, чем мне нужно). Два таких значения занимают лишь 3 байта, что позволяет всему массиву уложиться в 384 байта и, таким образом, оставить 128 байт для всех остальных задач.


График по вертикали имеет размер всего 32 точки, поэтому если за минимум всегда принять значение 0 А, а за максимум – 40 А, реальные изменения тока будут практически не видны в таком масштабе. Значит, масштабировать его имеет смысл динамически, чтобы минимальное значение тока находилось всегда в самой нижней строке, а максимальное – в самой верхней. Математически это выглядит как формула:

y(n) = (I(n) – Imin)*31/(Imax – Imin)

Посмотрев на неё внимательней, я понял, что мне нужно сократить размерность хранимых данных с 12-ти бит до 11-ти, тогда максимальное хранимое значение будет 2047 и для умножения его на 31 снова хватит 16-ти бит. На пользовательские характеристики это никак не повлияет, т.к. изначально запланированный максимальный ток составлял как раз 20 А и для хранения такого значения 11-ти бит достаточно. А больший ток, прежде всего, нельзя пропускать через шунт сопротивлением 5 мОм, т.к. даже при постоянных 20 А на нем будет падать целых 2 ватта, что разогреет его до слишком высокой температуры и он просто отпаяется от платы.

Когда с форматом и преобразованием данных было решено, оставалась последняя небольшая задача – написать функцию, которая будет быстро рисовать на экране вертикальный отрезок от y1 до y2. Учитывая, что допустимым значением для параметров является диапазон [0..31], это дает всего 1024 возможных варианта результата, что при его размере в 4 байта, в принципе, позволяет использовать лукап-таблицу, размер которой составит 4 КБ. И это даже влезет в ПЗУ МК, но отдавать его половину под такую таблицу мне совершенно не хотелось.

С другой стороны, т.к. речь идет всего о 32-х пикселях, можно сделать отрисовку и обычным циклом – такая функция не потребует вообще никакой таблицы, но будет занимать достаточно много процессорного времени. Тоже не самое лучшее решение для маленького и слабого МК, поэтому я решил найти некоторый компромисс.

Для начала я напишу некую функцию F, которая будет принимать только один параметр N и рисовать на экране столбик в диапазоне [N..31], то есть, от указанной точки по вертикали до верха графика. Если результат этой функции проинвертировать, я автоматически получу другую функцию, которая рисует на экране столбик в диапазоне [0..N), то есть, от нуля и на один пиксель меньше, чем указанная по вертикали точка. А тогда искомый мной отрезок можно будет получить с помощью следующих вычислений:

R = F(y1) AND (NOT F(y2 + 1))

Теперь задача упрощается – надо быстро нарисовать столбик пикселей в диапазоне [N..31]. В принципе, здесь уже можно воспользоваться лукап-таблицой, так как она будет занимать всего 128 байт, но я решил попробовать более интересное решение, основанное на математике. Если предположить, что результат – это 32-битное значение, где младший бит представляет собой самую верхнюю точку, а старший – самую нижнюю, то математически функцию F можно описать как:

F(n) = 2⁽³²⁻ⁿ⁾ – 1

И именно такую функцию я и решил реализовывать:


Функция все еще использует лукап-таблицу для быстрого вычисления 2ⁿ для 0 <= n <= 7, но такая таблица занимает всего 8 байт. Еще функция использует интересную особенность AVR, что первые 32 байта адресного пространства ОЗУ на самом деле попадают на 32 регистра общего назначения процессора R0 – R31. Это позволяет команде st Z, R18 осуществлять запись байта в нужный регистр результата R22 – R25.

В итоге, рисование столбика занимает 25 тактов процессора без учета команд вызова и возврата из подпрограммы. Для сравнения, если бы я использовал лукап-таблицу из 128-ми байт, функция могла бы занимать 18 тактов.

Используя все наработки, описанные выше, я написал функцию display::UpdateDiagram(), которая:

  • Высчитывает минимальное и максимальное значение тока за последние 128 измерений и помещает их в переменные g_samplesMin и g_samplesMax.
  • Рассчитывает масштаб отображения исходя вычисленных значений.
  • Выводит график последних 128 измерений на дисплей с учетом минимального и максимального тока в каждом измерении.
  • Сдвигает значения в памяти на одно измерение влево (если смотреть по экрану).

Теперь требовалось оценить производительность полученной функция. Точных подсчетов я не делал, но по приблизительным оценкам сверху функция UpdateDiagram тратит не более двух тысяч тактов на обработку каждого измерения (включая вывод на экран) или около 256К тактов на весь график. Поскольку желаемая частота обновления составляет 50 Гц, между соседними обновлениями будет 320К тактов, что оставляет мне запас в 64К тактов на выполнение каких-либо других действий.

Это хорошо, но для данного устройства не совсем критично – ведь если бы я не уложился в отведенный лимит, я бы просто чуть повысил тактовую частоту I²C, ускорив, таким образом, отправку байтов на дисплей. Это значительно ускорило бы функцию рисования графика целиком, потому что основную задержку в неё вносит именно отправка. Контроллер дисплея, кстати, это позволяет сделать вплоть до работы в режиме MAX_SPEED, который на поверку оказывается в 2-2.5 раза быстрее стандартного. Вопрос оставался бы лишь в том, потянет ли такую частоту TMP100. Но испытывать, к счастью, не пришлось.

Среднеквадратическое значение тока

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

По сути, здесь никаких сложностей не возникло – я просто беру каждое максимальное значение из 128-ми пар, возвожу его в квадрат, складываю все полученные квадраты, после чего делю сумму на 128 и извлекаю из полученного значения квадратный корень. Поскольку значения в буфере хранятся 12-битные, их квадрат помещается в 24 бита, сумма – в 32 бита, а среднее значение квадратов – снова в 24 бита. Остается только написать код вычисления квадратного корня из 24-разрядного числа:


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

Главный экран

Основной элемент главного экрана – график тока, который надо обновлять 50 раз в секунду. Все остальные отображаемые числовые значения надо обновлять значительно реже, около 5 раз в секунду, иначе они будут мелькать и станут совершенно нечитаемыми. Но просто взять и обновить все числовые значения сразу нельзя, потому как такое обновление займет слишком много времени и вызовет подергивание движения графика тока.

Поэтому решил, что каждый раз после обновления графика тока буду выполнять только одно ресурсоёмкое действие – выводить максимальный ток, выводить минимальный ток, рассчитывать среднеквадратический ток, выводить среднеквадратический ток, получать температуру с датчика TMP100 или выводить температуру на экран. Каждое из таких действий гарантированно укладывается в остающиеся от вывода графика тока 64К тактов процессора и, таким образом, не нарушит равномерность отображения.


Screen saver

К сожалению, у OLED-дисплеев есть одно неприятное свойство – их диоды в процессе эксплуатации способны выгорать и терять яркость свечения, поэтому если постоянно выводить на дисплей одну и ту же картинку, со временем она «отпечатается» на матрице диодов и будет мешать нормальному отображению других данный. Это можно очень хорошо наблюдать на моей паяльной станции Т12, которой уже несколько лет:


Чтобы немного защитить дисплей амперметре, решил добавить ему хранитель экрана (Screen Saver). Подумал, что если максимальный ток двигателя в течение минуты не превышает какого-либо предела, например, 0.5 А, то очищу весь экран, чтобы снизить бессмысленное выгорание пикселей. Однако, наблюдать чисто черный экран неинтересно, ведь даже не будет видно, что устройство работает, поэтому решил выводить на экран небольшую анимацию зажигания и угасания маленькой звездочки, возникающую по случайным координатам. Саму звездочку я предварительно нарисовал как 6 символов шрифта, где один из символов полностью пустой. Это позволяет не задумываться о необходимости стирания с экрана текущей звездочки перед выводом новой.

Но теперь появилась новая задача – где взять генератор случайных чисел для получения случайных координат? В теории, можно было воспользоваться тем, что есть в стандартной библиотеке С++, но я решил просто перенести уже имеющийся код генератора из одного из предыдущих проектов:


Генератор основан на LFSR — Linear-feedback shift register. Это простой сдвиговый регистр, на вход которого подается сигнал обратной связи, посчитанный исходя из текущего состояния некоторых битов регистра. Для сложения битов применяется функция XOR, т.к. она не теряет информации своих операндов. Следует отметить, что правильно спроектированный LFSR позволяет перебирать 2ⁿ — 1 (то есть, все кроме одного) своих состояний в некой псевдослучайной последовательности, поэтому и подходит для генератора псевдослучайных чисел. В моем конкретном случае используется регистр длиной 31 бит с обратной связью XNOR от битов 27 и 30 (если считать от 0). Использование XNOR позволяет регистру начать свою работу с полностью нулевого состояния, чего было бы невозможно добиться использованием функции XOR, в остальном никаких отличий между ними нет.

Кстати, если вам 40+, скорее всего вы познакомились с LFSR гораздо раньше, чем узнали, что это вообще такое. Помните тот переключатель на 4 елочных гирлянды с 7-ю режимами на логических микросхемах серии К155? Он был опубликован в журнале Радио № 11 за 1986-й год:


У него был «магический» 6-й режим, который по описанию авторов должен был «повторять разнообразие всех предыдущих режимов», но для его работы требовалась отдельная логическая микросхема ИЛИ-НЕ К155ЛЕ1, которую было сложно найти, поэтому даже не все радиолюбители его реализовывали. Так вот, узел, собранный на этой микросхеме (я обвел его на схеме красным прямоугольником) был ни чем иным, как элементом «Исключающее ИЛИ» или, по-современному, XOR. А совместно со сдвиговым регистром на 4-х D-триггерах он образовывал LFSR размером 4 бита с обратной связью от битов 2 и 3. И именно эту бегущую псевдослучайную последовательность из 15 разных состояний, генерируемую LFSR авторы и представили как интересный дополнительный режим переключения ёлочных гирлянд.

Кстати, схемотехника LFSR очень проста, что позволяет с легкостью реализовывать его аппаратно. И раньше это любили делать внутри больших микросхем, например, для синтеза «белого шума». За один сдвиг LFSR генерирует 1 бит псевдослучайной последовательности, соответственно, если вам нужно 8, сдвинуть регистр надо 8 раз. Брать результат можно из любого бита регистра (т.к. рано или поздно один и тот же бит проедет по всему регистру), главное делать это всегда из одного и того же места.

Защита от перегрева

Полноценную защиту от перегрева двигателя без изменения схемотехники дорожки реализовать невозможно, можно только уведомлять пользователя, что двигатель достиг слишком высокой температуры. Именно это я и решил сделать. Уведомление происходит в несколько этапов – когда двигатель разогревается до 60 градусов, устройство издает одиночный звуковой сигнал. Если нагрев двигателя продолжается, то при достижении температуры 61 градус устройство издаст двойной звуковой сигнал. При достижении 62 – тройной и так далее до 65 градусов, после чего устройство будет пищать непрерывно. Отключение звукового сигнала и сброс состояния происходит при охлаждении двигателя до 58 градусов.

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

Итоги

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

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

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

Что касается получаемой точности измерений, на своем приборе я заметил, что не смотря на усреднение 64 последовательных выборок АЦП, текущие показания тока прыгают в пределах 0.08 А. Точность RMS значения тока выше, и составляет около 0.02 А, но она вообще меняется значительно медленней. Таким образом, при максимальном измеряемом значении в 20 А можно считать, что разрешение прибора составляет 0.1 А, а точность – не хуже 1%±0.1 А. Результаты не особо выдающиеся, но вполне подходящие для всех описанных выше задач. Кстати, причиной такого большого разброса мгновенных показаний я склонен считать встроенный в МК усилитель АЦП, так как без него разброс значений значительно ниже.

Исходный код проекта, схему, плату и корпус можно найти в репозитории по ссылке:

github.com/kdekaluga/continuous_current_meter

На этом у меня всё, спасибо за внимание.
Добавить в избранное
+109 +148
свернутьразвернуть
Комментарии (132)
RSS
+
avatar
0
  • Pavel_VL
  • 02 сентября 2025, 14:44
просто вопрос про токоизмерение, хотел узнать с какого значения начнет работать мощный 12-в движок, попросил у работяг токовые клещи, замерил, показания разнятся с линейным измерением тестером более чем в два раза, клещи занижают. какой смысл в бесконтактных токоизмерительных клещах если они даже в попугаях так кратно ошибаются.
+
avatar
+1
  • yg-25
  • 02 сентября 2025, 14:50
Смотря какие клещи, мои унит и киоритсу в дк режиме боле-менее показывают сопоставимо с проводным включением тестера.
+
avatar
-1
  • Pavel_VL
  • 02 сентября 2025, 14:54
точно, это были uni-t ut210d), полный шлак! больше 2 000 дедушке Ляо на подъём.
+
avatar
+2
У меня uni-t UT210E, и они показывают более-менее нормально. Первый же вопрос — а правильно ли вы измеряли и какой вообще в цепи был ток? Клещами «захватывать» надо строго один провод, если захватить два — показания будут около нуля.

Ну и точность клещей на малых токах действительно низкая. Они используются при больших токах — в сотни ампер, где значительно выигрывают у классических амперметров в удобстве.
+
avatar
+2
попросил у работяг токовые клещи
так нужны не абы какие, а правильные клещи, которые умеют inrush current вычислять. про это сначала намекнут в цене, а уже потом в инструкции укажут.

fluke из 370-ой серии, или fluke 381 например.
не знаю насколько узкие пики они могут измерять, но их обычные показометры типа Fluke 183/185 кроме min/max имеют функцию fast min/max
так что я предполагаю что там пики в тех же диапазонах мерятся, в районе 1мс.
т.е. 1000 раз в секунду?
+
avatar
0
  • Opostrof
  • 06 сентября 2025, 12:52
Как уже говорилось. Если вы чего то не умете и не понимаете, то это прежде всего проблема ваших ожиданий. Токовые клещи — инструмент! А инструментом надо уметь пользоваться и понимать принцип их работы. Тогда и проблем в работе не будет, и необоснованных глупостей писать не будете.
+
avatar
0
не совсем понятно что и как именно вы измеряли, какие токи, на каких пределах, правильно ли работали, обнуляли ли клещи, да и вообще — вплоть до правильного выбора постоянного и переменного тока.
вообще клещи измеряют достаточно точно, но нужно уметь потому что есть нюансы
+
avatar
+4
  • yg-25
  • 02 сентября 2025, 14:47
Не читал, но одобряю. Судя по объему текста работа проделана большая или очень большая. Закинул в избранное, для более обстоятельного прочтения, в торопях не хочется такой труд читать.
+
avatar
+11
наконец то diy, которому приятно поставить +
+
avatar
+6
Спасибо)
+
avatar
+5
Извините, всю портянку не осилил — слишком много. Но всего одна мысль билась в голове — «И вот это вот всё вместо одного стрелочного прибора?»
Имхо, у вас просто слишком много свободного времени )
+
avatar
+17
  • Skylab
  • 02 сентября 2025, 15:00
В разделе DIY есть два вида самых распространенных каментов — про «свободное время» и «троллейбус из буханки».
+
avatar
+7
слишком много
Я предупреждал)
И вот это вот всё вместо одного стрелочного прибора?
А что покажет стрелочный прибор? Он недостаточно медленный, чтобы показать среднее и недостаточно быстрый, чтобы правильно показать минимум и максимум.
у вас просто слишком много свободного времени )
Нет, времени свободного как раз немного, такими вещами занимаюсь постепенно, по мере возможности, так как нравится.
+
avatar
+1
А что покажет стрелочный прибор?
А вы попробуйте — удивитесь.

Он недостаточно медленный, чтобы показать среднее и недостаточно быстрый, чтобы правильно показать минимум и максимум.
Зачем вам мгновенное значение мощности? Его длительность измеряется миллисекундами, и для оценки нагрузки на двигатель не нужно. А что касается минимального — не совсем понятно, для чего оно в рамках данного случая.
+
avatar
+4
А вы попробуйте — удивитесь.
Думаете, я никогда не работал со стрелочными приборами? Как раз работал, поэтому больше не хочу возвращаться к такому. И стрелочный прибор вам RMS не покажет, т.к. зависимость магнитного поля от тока линейная, а мощности от тока — квадратичная. То есть, стрелочник тут вообще ни к селу, ни к городу.
не совсем понятно, для чего оно в рамках данного случая.
Мне интересна амплитуда изменения тока, а для её оценки надо два значения. Плюс, минимум всё равно нужен, чтобы график масштабировать. В остальном, я считаю и отображают правильное RMS-значение.
+
avatar
0
Мне интересна амплитуда изменения тока, а для её оценки надо два значения.
Ну ок, у коллекторного двигателя пусковой ток в разы больше номинального. Будем считать пусковой за норму?
+
avatar
+1
Не понимаю, к чему вы клоните. У данной дорожки есть контроллер, пуск тут плавный, пусковой ток 2 А, то есть, в два раза меньше рабочего и в 4 раза меньше пикового.
+
avatar
0
Не понимаю, к чему вы клоните.
К цели данной самоделки. Вы ведь хотели контролировать пиковые (в вашем понимании) значения для контроля за умиранием двигателя?
+
avatar
+2
К цели данной самоделки.
А вы статью читали? Я там четко написал, что я хотел:
Отображение текущего, а также минимального и максимального значения тока за последнюю пару секунд.
В процессе эксплуатации я заменил текущее значение тока на RMS, т.к. текущее оказалось совершенно неинформативно.

Каким образом вы собираетесь выполнить этот пункт (я уж молчу про график) с помощью стрелочного прибора?
+
avatar
0
Каким образом вы собираетесь выполнить этот пункт (я уж молчу про график) с помощью стрелочного прибора?
Прямо, по назначению.
Переходные процессы в ходе эксплуатации дорожки происходят настолько медленно, что стрелочный амперметр их покажет.
Единственный минус, который я вижу — нужно знать верхний предел потребляемого тока, чтобы выбрать правильный амперметр. Ну, или делать шунт самому.
+
avatar
+4
обычный микроампетр стрелочный (типично на 50-100мкА) с трудом отображает колебания даже в районе 10 Гц (и то большую часть амилитуды теряет по пути)

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

как раз недавно видео смотрел на этот счет:
, освежал в памяти.
+
avatar
0
  • MikeW
  • 03 сентября 2025, 00:24
Обычная измерительная головка может музыку играть. Если измерять именно ток, на головку с низким сопротивлением — то там все будет видно.
Да, готовый мультиметр со входным делителем и тяжёлой стрелкой не так поворотлив, но если взять любой индикатор из советского магнитофона, то он будет отплясывать на ура.
+
avatar
+1
  • vlo
  • 03 сентября 2025, 02:45
издавать звук и показывать адекватные значения — это сильно разная амплитуда.
+
avatar
+3
с трудом отображает колебания даже в районе 10 Гц (и то большую часть амилитуды теряет по пути)
а 100Гц он вообще не увидит никогда, оно сквозь него пройдет. т.е. всплески длиной десяток миллисекунд он не замечает.
Ещё раз — зачем в данном случае измерять мощность(ток) даже 10 раз в секунду?

А в вашем ролике передёргивание страшное — ставят диагноз по колебаниям с размахом в 0.1 В. Ну смешно же. Потом показывают колебания в 2 В, но почему-то только на третьем приборе, «медленном». И даже на «медленном» они более вменяемы, чем на цифровом. А вот на «быстром» «Симпсоне» эти колебания не показывают. Странно, да?

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

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

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

Поэтому, если уж начинать DIY, то делать качественно, делать такое устройство, которое будет закрывать все потребности, а не костыль в виде стрелочного прибора, который «дергается и ладно».
+
avatar
0
Зачем вам мгновенное значение мощности? Его длительность измеряется миллисекундами
бмс на батареях за милисекунды отключает выход при значительном повышении тока, если она умная, то можно при помощи такого приборчика выставить параметры, при которых пусковой ток выбивать не будет, а вот кз она все же перекроет
+
avatar
+4
Иван, поэтому ты и 'не осилил", что не понимаешь зачем это. А сотня ( может уже больше), увлеченных людей прочитали эту великолепную статью.
+
avatar
+2
  • DIMAace
  • 02 сентября 2025, 15:17
В данной статье пойдет речь о простом самодельном амперметре
Да уж. Сначала не обратил внимание на размер бегунка прокрутки, потом понял, что не совсем простое.
+
avatar
0
что не совсем простое
А что сложного? ) Если исключить блок питания, останется практически один «голый» микроконтроллер, вот и всё устройство.
+
avatar
+2
  • DIMAace
  • 02 сентября 2025, 18:51
Ну да, нарисуйте овал, а дальше всё просто — сова сама нарисуется.
+
avatar
+3
Вы про программный код? Так мне его писать интересно, а если вы решите вдруг повторить, вам это уже делать не надо будет, сможете взять готовый. То есть, для меня, как для изначального автора сложность устройства чуть выше. Но для повторения оно весьма простое.
+
avatar
+2
О, увидел схему переключателя гирлянд, которую я делал в 1988 году… и делал полную схему и да, там было больше программ… я ставил не галетный переключатель, а на группе переключателей П2К и если нажать клавиши в произвольном порядке, по 2-3 сразу… она переключала гирлянды рандомно… я насчитывал несколько десятков режимов :)) Эту схему я делал для защиты диплома в училище на слесаря КИПиА… кем всю жизнь и работаю
+
avatar
+3
которую я делал в 1988 году
В это время или чуть раньше её делали очень многие, т.к. вот этот 6-й режим из 15-ти последовательных комбинаций был весьма необычным для того времени. Я тоже собирал, но мне родители запретили работать с 220 В, поэтому переделывал всю гирлянду на 12 В и понижающий трансформатор.
+
avatar
+1
да, смотрелось это все как цветомузыка, а не просто переключатель… и даже иногда попадало в такт с музыкой :)) и у меня это устройство просили продать или подарить, но я оставил себе. Эх… где то.утерялось во времени. Было все штатное, на 220в, подключались красивые цветные фонари… покупал в Минске. Но все утерялось… жаль
+
avatar
+1
Хм… Шунт и осциллограф копеечный с али не проще чем вот это вот всё? Осциллограф потом еще куда-то можно применить, когда наиграетесь.
+
avatar
+3
С первого взгляда проще. Но если углубиться в детали, там тоже есть свои нюансы типа источника питания, измерения температуры и т.д.
еще куда-то можно применить, когда наиграетесь.
В этом и дело, что я не хочу временных решений. Если уж контролировать потребление, то пусть это будет постоянное решение, работающее всегда. Я вот сейчас думаю сделать еще одно похожее, но уже для измерения тока потребления электроинструмента.

Да и некуда мне применять игрушечные осциллографы.
+
avatar
+3
Вот это я понимаю, DIY здорового человека
+
avatar
+1
Спасибо)
+
avatar
0
  • kotmorse
  • 02 сентября 2025, 15:48
«у ATtiny85 оказалась «киллер-фича», сделавшая его еще более подходящим – у его АЦП есть режим дифференциального измерения со встроенным усилителем с коэффициентом усиления 20»

C термопарой k-type напрямую сможет работать? Если ТЭДС +250С=10.153mV,
-150C=-4.913 mV, т.е. диапазон измерения напряжений от -5мВ до +10мВ.
+
avatar
+4
У термопар К-типа ТЭДС примерно 40 мкВ на градус. Умножим это на 20, получим 800 мкВ на входе АЦП. Минимальное встроенное опорное напряжение — 1.1 В, при разрядности в 10 бит это дает примерно 1.1 мВ на единицу младшего разряда. То есть, полученное решение будет обладать разрешением хуже одного градуса и погрешностью градусов 5. Для каких-то применений это пойдет, для каких-то уже нет.
+
avatar
0
  • kotmorse
  • 02 сентября 2025, 16:19
спасибо, понял, что мне не подойдет.
+
avatar
+2
Мы в итоге остановились на MCP3421 для термопары. Плюсы — дешевый, диф вход, без ОУ. Но его надо калибровать для субградусного измерения: t.me/vvzvlad_lytdybr/911
+
avatar
+1
Сначала не понял, зачем измерять ток потребления автомобильного двигателя 150 раз в секунду и зачем ему нахрен вообще его потреблять.
+
avatar
+2
Поправил название, спасибо.
+
avatar
0
Радиокот на муське? Уважуха конечно, но тяжеловато для этого сайта. За обзор плюс.
+
avatar
0
но тяжеловато для этого сайта
Отмечу для себя.
+
avatar
+2
  • KBlack
  • 02 сентября 2025, 21:10
Мне показалось довольно доступно написано и подробно. Но конечно нужен хотя бы начальный бэкграунд для понимания. Спасибо за обзор.
+
avatar
0
Оффтоп: вопрос есть к людям, понимающий в аналоговой схемотехнике.

Есть солнечная панель мелкая, при дневном свете ее мощности не хватает питать мелкий двигатель, однако, если поставить кондер тысяч на 10мкф то зарядив его и разрядив на двигатель вполне хватает чтобы он некотрое время вращался.

Вопрос — можно ли на аналоге собрать триггер такого плана:
режим1: нагрузка включена, по достижении напряжения нижнего порога — включать режим2

режим2: нагрузка выключена, по достижении напряжения верхнего порога, переключиться в режим1

Да, я понимаю, что двигатель будет импульсами вращаться, меня бы это устроило.
+
avatar
+1
а что дает аналоговая схема? меньше жрать должна?

«компаратор» поможет отследить уровень относительно порога и выдаст логический сигнал (0 — меньше или 1 — если больше). подключение нагрузки при уровне 1 не сложно сделать, например мосфетом. заодно и отключение зарядки при уровне 1 — тоже. вприципе любые подойдут, сдутые например с дохлой материнки. Надо лишь будет поискать с нужным типом для задачи, потому что на материнке обычно все одного типа. А тут, будто бы для задачи отключения зарядки высоким логическим уровнем нужен depletion-mode MOSFET. Или вместо этого добавить инвертор логического уровня, тогда и делать все на enhancement mode MOSFETS, которых в изобилии на материнке. Логический инвертор на коленке — тобишь усилитель инвертирующего типа, тоже чуть ли не из пары транзисторов делается.

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

а так, возможно далее подскажут что вместо ОУ в роли компаратора, можно будет обойтись таймером 555, или вообще парой-тройкой транзисторов для этой цели. т.к. сверх точность в обработке порога не требуется, то можно будет очень по-разному задачу решать.
+
avatar
0
Да, аналог именно чтобы меньше жрало. Спасибо за инфу.
+
avatar
0
Есть логические мсхемы, когда при возникновении на ноге низкого/высокого уровня Эн вольт триггерятся другие ножки
+
avatar
0
  • TheLamer
  • 02 сентября 2025, 17:42
Вопрос — можно ли на аналоге собрать триггер такого плана:
режим1: пока напряжение выше нижнего порога — нагрузка включена, ниже этого порога включать режим2.
режим2: нагрузка выключена, по достижению верхнего порога напряжения переключиться в режим1
Ну да, просто взять электромагнитное реле. Подобрать с желаемым напряжением срабатывания и напряжением удержания.
P.S. Для «мелкой солнечной панельки» даже у мелкого реле может быть великоват ток потребления, тогда смотреть на твердотельные, они тоже бывают с гистерезисом.
+
avatar
0
Там очень низкие пороги — я конечно не спец, но врядли есть твердотелка с гистерезисом 1в-3в.
+
avatar
0
  • TheLamer
  • 02 сентября 2025, 18:54
Если это напряжение является и питающим, то на полупроводниках разве что триггер Шмитта на германиевых транзисторах вообще работать сможет (дискретные полевики с Vgs(th) меньше 1V найти в продаже нереально, кремниевый биполярный на 1V питании работать не сможет), но при этом вы не сможете коммутировать сколь-либо большие токи (пуск двигателя, прямой заряд конденсатора) и потери у вас будут огромны.
А вот трёхвольтовых электромагнитных реле на рынке пруд пруди и напряжение удержания у них как раз порядка 1V и будет. В крайнем случае, можно взять несколько реле с разным номиналом (3V, 4V, 4.5V, 5V, 6V) и проверить на месте. У большинства реле реальное напряжение срабатывания существенно (20%-50%) ниже номинального и варьируется от экземпляра к экземпляру, поэтому так вы сможете максимально точно подогнать верхний порог под ваши 3V. Ну а нижний порог — удержания (если реле разборное, ну или «условно -разборное») можно в некоторой степени регулировать, наклеивая слои скотча на торец магнита.
+
avatar
0
  • IWRY
  • 02 сентября 2025, 19:32
Сколько жрёт такое реле?
Надо же иметь в виду, что оно будет жрать непрерывно, и в процессе нарастания — тоже.
+
avatar
0
  • IWRY
  • 02 сентября 2025, 19:15
Там очень низкие пороги —… 1в-3в
А напряжение питания этого триггера — тоже оттуда же, 3В макс?
+
avatar
0
  • IWRY
  • 02 сентября 2025, 20:20
del
+
avatar
+1
Я бы делал на компараторе/ОУ с положительной обратной связью и каком-нибудь источнике опорного напряжения (специализированный или стабилитрон/диод). Плюсы — всё можно посчитать и устройство даже не придется настраивать. Минусы — схема достаточно большая, да и ОУ имеет потребление.

Альтернативно можно попробовать сделать на К561ЛН1 — она потребляет мало, а из двух инверторов можно собрать триггер с положительной обратной связью. Но тут пороговое напряжение вызывает вопросы, надо экспериментировать.

Или натурально брать триггер из двух транзисторов и подбирать/рассчитывать его параметры так, чтобы переключался при нужных напряжениях. Но будет зависимость от характеристик транзисторов.
+
avatar
0
  • IWRY
  • 02 сентября 2025, 19:07
Какой-нибудь УД1208 на минимуме жрет что-то там совсем чуть, микроампер 30-50, вроде, надо еще суметь на рассыпухе сделать меньше…
Схема — один ОУ и немного мелочи.
Вот на чём сделать микроамперный опорник — хз, надо поискать.
+
avatar
0
Вот на чём сделать микроамперный опорник — хз, надо поискать.
От требуемой точности зависит. Можно же микроамперы просто через диод/стабилитрон пропустить и получить на выходе какое-то напряжение.
+
avatar
0
  • IWRY
  • 02 сентября 2025, 19:27
У известных мне стабилитронов рабочая зона начинается с миллиампер, что он настабилизирует на микроамперах — ваще непонятно…
зыж «микротоковый стабитрон» нашёл от 50 мкА )))
ОУ жрет меньше
+
avatar
+2
  • IWRY
  • 02 сентября 2025, 20:02
Нашёл!!!
www.chipdip.ru/product/ltc1440cs8-analog-devices-8013611853
Компаратор с опорником в сборе, типовой Icc всего 2мкА, это просто чудо какое-то!
+
avatar
0
всего 2мкА, это просто чудо какое-то!
Согласен, правда стоит аж 1000 рублей )
+
avatar
+1
  • IWRY
  • 03 сентября 2025, 07:04
За пару!))
На Али 500р за 5 штук:
aliexpress.ru/item/1_71639388.html
+
avatar
0
А вот это можно взять (пока не закрыли) :).
+
avatar
-1
  • IWRY
  • 02 сентября 2025, 20:14
del
+
avatar
0
  • IWRY
  • 02 сентября 2025, 20:21
www.chipdip.ru/product/ltc1440cs8-analog-devices-8013611853
Собственно, только ПОС посчитать и низковольтный мосфет найти на выход.
Питание организовать от того же источника через диод шоттки и отдельный конденсатор.
+
avatar
0
Спасибо всем, дали пищу, ушел читать!
+
avatar
0
Я ведь верно понимаю, что там надо еще какой-то триггер ставить перед мосфетом? иначе как только напряжение станет ниже верхнего уровня сразу сработает компортаор по нижнему уровню?
+
avatar
0
  • IWRY
  • 03 сентября 2025, 08:53
триггер ставить перед мосфетом
Нет.
Достаточно одной этой микросхемы, на её выход сразу мосфет, ему в нагрузку — моторчик.
Нужно увеличить гистерезис компаратора и слегка сместить его в плюс, это три резистора, которые посчитать или подобрать.
Ну и питание компаратора организовать отдельно, это один диод и один конденсатор.
На солнечную панель посадить накопительный конденсатор моторчика и диод от питания компаратора.
Всё, это полный перечень, больше ничего не нужно.
+
avatar
+2
  • IWRY
  • 03 сентября 2025, 10:14
Проверенная на симуляторе схема:
Батарейка с резистором — аналог солнечной панели, лампочка — моторчик.
Резисторы поставил навскидку и практически попал:
.
Это напряжение на главном конденсаторе, на время не смотрите — для скорости эмуляции я уменьшал ёмкости на два порядка.
Можно чуть приподнять график и уменьшить амплитуду, если поставить оба 1МОм по 1,1 МОм.
Всю работу за Вас сделал )))
+
avatar
0
Спасибо огромное!!!

Ну вот в аналоге я совсем плох, спасибо что есть спецы такие.

Я правильно понимаю, что 10uf конденсатор слева я могу заменить на 10000мкф как накопитель?
+
avatar
+1
  • IWRY
  • 03 сентября 2025, 13:50
Там 10 миллиФарад указано, это и есть 10000мкФ)
Он никак на схему не влияет, только на время накопления/работы, можно подобрать по желанию.
Мосфет важно найти с низким пороговым напряжением затвора, их полно на чипеидипе, типа такого:
www.chipdip.ru/product/irlml6244tr-tranzistor-n-mosfet-20v-6.3a-1.3vt-sot-23-3-umw-9001231129
Желательно оба конденсатора дополнительно зашунтировать керамическими фильтрашками, от греха, моторчик-то коллекторный…
Ну и если совсем параноить, можно параллельно моторчику обратный диод воткнуть, хотя я бы поленился до первого выбитого мосфета, чего почти наверняка не случится))
ЗЫЖ диод на питание компаратора, напоминаю, очень желательно шоттки на таких мелких напругах.
+
avatar
0
Ещё раз огромное спасибо!

А диод шмотки любой можно? А то тот, что в схеме не вижу в чипедипе, микрухи заказал уже) плату развожу)
+
avatar
+1
  • IWRY
  • 03 сентября 2025, 19:09
диод шмотки любой можно?
Тот, что в схеме, я взял первый попавшийся из базы Мультисима.
Можно ваще любой мелкий, у меня вон коробочка с ними валяется, и купленными, и выпаянными из разных БП в разное время, но через инет не предаётся пока))
+
avatar
+1
  • IWRY
  • 04 сентября 2025, 09:39
Можно чуть приподнять график и уменьшить амплитуду, если поставить оба 1МОм по 1,1 МОм.
Тут немножко фигню написал… чтобы приподнять график, надо увеличивать верхнее плечо делителя, которое 810к. Остальное верно, вроде.
+
avatar
+1
для генерации псевдослучайных чисел обычно еще очень важен seed (стартовое значение).

откуда его значение берется?

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

тут судя по коду используется R23, что есть регистр микроконтроллера. который скорее всего автоматически очищается после сброса, еще задолго до начала работы программы. нету ли возможности залезть в процедуру обработки прерывания сброса микроконтроллера (и вклиниться до момента очистки памяти) — чтобы прочитать оттуда случайное значение? или тут достаточно просто прочитать последний байт из памяти или что-то такое?

просто не уверен, что код, который будет включен компилятором из «стандартной» библиотеки не делает чего-то лишнего, в т.ч. и очистку памяти при старте.
+
avatar
0
У тиньки достаточно adc считать любое и использовать правые n-бит этого как сид, дальше стандартный рандом-xor.
+
avatar
+1
Было уже. Стоит поставить рядом мощный источник помех с заведомой последовательностью и рандом adc не такой уж рандом
+
avatar
+1
Не, ну знаете ли )))

Тогда аппартаный генератор ставить если уж надо железно.
А так — ADC можно померять температуру проца — помех будет меньше, тинька это умеет.
+
avatar
0
откуда его значение берется?
В данной конструкции ниоткуда — генератор всегда начинает работать с нуля. Частично ситуацию спасает то, что пока дорожкой пользуются, происходит вызов кода генератора, то есть, можно сказать, что в стартовое значение включается время до перехода к screen saver'у, которое в реальности будет достаточно разным. Ну, и задача скрин сейвера сама по себе не накладывает каких-либо серьезных требований на качество случайных чисел.
тут судя по коду используется R23, что есть регистр микроконтроллера
Это очень похоже на ответ какой-то нейросети.
чтобы прочитать оттуда случайное значение?
Такая возможность, думаю, есть, но я не уверен, что содержимое памяти МК или его регистров будет настолько уж случайным, чтобы смело использовать его как seed. Например, в случае быстрого перезапуска устройства очень велик шанс, что содержимое памяти практически полностью сохранится, и тогда этот метод не даст ожидаемых результатов.
Мне кажется, если прямо есть задача найти качественное стартовое значение, лучше всего использовать АЦП — собрать несколько тысяч выборок, сложить их и использовать младший байт полученного результата. Вот его значение уже будет случайным в гораздо большей степени.
+
avatar
+2
  • Leoniv
  • 02 сентября 2025, 18:06
Настоящий DIY, плюсую.
Квадратный корень можно вычислять с помощью итерационной формулы Герона. Алгоритм быстро сходится, количество итераций можно делать малым (на компьютере можно промоделировать, сколько нужно для конкретного случая). Вот пример извлечения корня из 32-разрядного числа:

#define INIT_APPROX 1000
#define ITER_NUMBER 10

uint16_t Sqrt(uint32_t d)
{
  uint32_t x = INIT_APPROX;
  for(uint8_t i = 0; i < ITER_NUMBER; ++i)
    x = (d / x + x) >> 1;
  return(x);
}
+
avatar
+2
Спасибо.

Я знаю эту формулу, но почему-то у меня в голове она сохранена под именем «метод Ньютона». Реализовывал её для STM32, для моей задачи хватило всего 3-х итераций, максимальная ошибка составила 1. Но там был ключевой момент — правильный выбор начального значения с помощью команды CLZ, она очень сильно ускоряла (или повышала точность). В итоге, занимала функция около 50 тактов, но команда деления там аппаратная.

Здесь 24-битное деление придется писать самому, и не факт, что то количество итераций, которое даст хорошую точность во всем диапазоне входных значений окажется сильно быстрее, чем простой подбор 12-ти битов. Хотя, конечно, можно же и сначала биты посчитать.

В общем, определенно, если надо сделать метод максимально быстрым, надо провести дополнительное исследование)
+
avatar
0
  • Leoniv
  • 02 сентября 2025, 19:52
Можно и так называть. Формула Герона — это частный случай метода Ньютона для решения уравнений. Выбор начального значения важен при очень маленьком количестве итераций. Дальше значение все равно сходится к нужному. Лучше всего в каждом конкретном случае промоделировать и выбрать оптимальные значения.
+
avatar
0
Поднял ту реализацию, вот так было:

// FastIntSqrt is based on Wikipedia article:
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots
// Which involves Newton's method which gives the following iterative formula:
//
// X(n+1) = (X(n) + S/X(n))/2
//
// Thanks to ARM CLZ instruction (which counts how many bits in a number are
// zeros starting from the most significant one) we can very successfully
// choose the starting value, so just three iterations are enough to achieve
// maximum possible error of 1. The algorithm uses division, but fortunately
// it is fast enough here, so square root computation takes only about 50-55
// cycles with maximum compiler optimization.
uint32_t FastIntSqrt (uint32_t value)
{
	if (!value)
		return 0;

	uint32_t xn = 1 << ((32 - __CLZ (value))/2);
	xn = (xn + value/xn)/2;
	xn = (xn + value/xn)/2;
	xn = (xn + value/xn)/2;
	return xn;
}
Прошел по ссылке, статью в Вики полностью обновили, даже название)
+
avatar
+2
  • Leoniv
  • 02 сентября 2025, 22:59
Да, это тот же самый алгоритм, только здесь жестко заданы 3 итерации. CLZ — это приятный бонус, но можно и без него, брать фиксированное начальное значение. Итераций при этом может потребоваться больше.

Для создания цифровых шрифтов пользовался вот этой утилитой. Достаточно набрать в любом редакторе все цифры в одну строку, затем копию экрана сохранить как картинку и подсунуть этой утилите. Она делает h-файл. Если размер шрифта в пикселях большой, то вручную становится делать трудно.
+
avatar
0
Интересно, спасибо. Последний раз, когда такое было надо, я писал программу под винду — она в памяти DC создавала, выводила туда нужный символ, потом байты считывала и в текстовом виде оформляла.
+
avatar
+2
  • IWRY
  • 02 сентября 2025, 18:57
Ох, блин!!!
Прочитал с огромным удовольствием, олдскулы заклинило, слеза ностальгии навернулась, поставил бы пять плюсов, было бы можно))
+
avatar
0
Спасибо)
+
avatar
0
  • mooni73
  • 02 сентября 2025, 19:38
Когда читал, невольно вспомнился анекдот «ошибка в расчетах». Понятно, что вещь создана для удовольствия и никакие советы, типа «используй смартрозетку» не уместны, но один момент напряг — звуковой индикатор перегрева. Вроде народ в наушниках бегает, да и моторчик шумит — можно не услышать.
+
avatar
0
используй смартрозетку
Смартрозетки у меня нет, а вот ваттметр пробовал — ничего хорошего не показал) Такое чувство, что если потребляемая мощность быстро меняется, он не успевает диапазоны переключать и вообще зависает. Но это, возможно, мой так себя вел. Но даже если бы и показал, тут результаты сложнее интерпретировать — мощность линейно зависит от скорости и еще дополнительно зависит от тока. То есть, с увеличением скорости будет очень быстро расти, и какое значение считать нормой, а какое нет, понять будет сложнее.
Вроде народ в наушниках бегает, да и моторчик шумит — можно не услышать.
Если постоянно пищать начнет, то даже через наушники слышно. За счет резонансной частоты и удвоенного напряжения пищит излучатель сильно.
+
avatar
0
  • kvarkk
  • 02 сентября 2025, 20:16
Датчик температуры в термоусадке — спорное решение. Термоусадка имеет немалок тепловое сопротивление. За обзор плюс однозначно.
+
avatar
0
спорное решение. Термоусадка имеет немалок тепловое сопротивление
Да, тепловое сопротивление большое, но ведь и мотор нагревается медленно — десятки минут. То есть, тут главное, чтобы тепло от датчика сильно не уходило в окружающую среду, и тогда тепловое сопротивление уже не имеет такого значения. Ну и если будет занижать на пару градусов — не принципиально.
+
avatar
0
Выбор температуры 60 градусов чём-то обусловлен?
Там же ротор более всего должен нагреваться, и при 60 на корпусе, обмотка ротора должна быть гораздо горячее.
+
avatar
+1
Да, ротор, конечно, горячее. Но его температуру замерить простой возможности нет.

60 градусов выбрал из опыта — предположительно, запах от неисправного двигателя начинался при температуре корпуса более 70 градусов. С другой стороны, исправный двигатель с исправным полотном после часа ходьбы имеет температуру корпуса порядка 45 градусов. Но это сейчас, когда похолодало (начальная температура двигателя около 20 градусов), а если взять жару и предположить, что начальная будет 30 градусов, после часа занятий следует ожидать 55.

Поэтому решил, что 60 будет предупреждение, а 65 — уже критическая температура.
+
avatar
0
Температура измеряется непосредственно на корпусе?
По фрагменту фото сложно понять какой именно мотор установлен, но предположу, что на роторе есть крыльчатка охлаждения. Не будет ли более надёжно измерять температуры выходящего воздуха, что теоретически, может уменьшить инерционность?
+
avatar
+1
Да, на роторе есть крыльчатка, но в реальных режимах эксплуатации мотор вращается весьма медленно, она не создает должного потока охлаждения. Поэтому замер выходящего воздуха не будет давать надежные результаты.

Ну, и повторюсь, инерционность здесь совсем не критична — мотор разогревается за десятки минут, даже на полностью неисправной дорожке можно было заниматься 15 минут. То есть, оценка температуры корпуса вполне имеет право на существование.
+
avatar
+1
  • vlo
  • 03 сентября 2025, 04:41
на тему готовых рисовалок графика потребления — есть ToolkitRC WM150 mysku.club/blog/china-stores/78614.html
из неудобств — он всего до 50В (но ток рисовать можно и без напряжения), ну и шунт внутри корпуса — подключать в случае вроде описанного неудобно, надо тянуть наружу силовой кабель.
+
avatar
+1
Посмотрел. С одной стороны, интересное устройство, положу в корзину, может и закажу) Кстати, таким измеряют потребление электроинструмента.

Но вот только 150 А — это они явно преувеличили, т.к. шунт там 1 мОм, и пропускать через него 150 А, это так себе идейка)
+
avatar
0
  • Leoniv
  • 03 сентября 2025, 10:19
JST-разъем с шагом 2.54 мм
Для таких разъемов действительно часто пишут шаг 2.54, хотя по факту там 2.5.

байты данных у этого контроллера дисплея расположены вертикально, а не горизонтально, как мы привыкли, то есть, один байт заполняет сразу 8 строк в одной колонке экрана
Это боль таких дисплеев. Выводить всё кратно 8-ми точкам по вертикали — это слишком жесткое ограничение, невозможно нормально сдизайнировать экран. Читать память дисплея по шинам I2C и SPI невозможно, поэтому единственный выход — держать в ОЗУ контроллера копию экрана. Но это 1 кб, маленькие контроллеры сразу отпадают.

логично и вывод делать не по привычной схеме вправо-вниз, а по обратной – сначала вниз, потом вправо, благо контроллер такой режим поддерживает. Тогда и шрифты в памяти можно хранить в таком же формате
Шрифты храню в одинаковом виде что для OLED, что для TFT. В байте кодируются точки для строки, так визуально понятнее, легче вручную править знакогенератор. Для цифр использую моноширинные шрифты, так как очень некрасиво, когда длина строки прыгает при изменении выводимого числа.

	0x00, 0x00, //               
	0x0F, 0x80, //     #####     
	0x3F, 0xC0, //   ########    
	0x30, 0xE0, //   ##    ###   
	0x00, 0x60, //          ##   
	0x00, 0xE0, //         ###   
	0x07, 0xC0, //      #####    
	0x07, 0xC0, //      #####    
	0x00, 0xE0, //         ###   
	0x00, 0x60, //          ##   
	0x00, 0x60, //          ##   
	0x60, 0xE0, //  ##     ###   
	0x7F, 0xC0, //  #########    
	0x3F, 0x80, //   #######     
	0x00, 0x00, //               
+
avatar
0
Как вы редактируете сообщение через такой интервал времени? У меня практически сразу ссылка «редактировать» исчезает.
Для таких разъемов действительно часто пишут шаг 2.54, хотя по факту там 2.5.
Честно говоря, не очень силен в таких тонкостях, но буду иметь в виду, спасибо. Тут вспоминаю проблему из 90-х, когда советские микросхемы имели шаг 2.5 мм, а импортные панельки — 2.54 мм. В результате, 40-выводные микросхемы (типа ВВ55) вставлялись в панельки криво и с трудом. А вот на 14-выводных обычно проблемы не замечалось.
Это боль таких дисплеев. Выводить всё кратно 8-ми точкам по вертикали — это слишком жесткое ограничение, невозможно нормально сдизайнировать экран.
Согласен, если бы байт был в привычной горизонтальной ориентации, компоновать было бы проще, но сложнее выводить. А вот на счет жесткости ограничения на дизайн не соглашусь — во времена спектрума всё старались компоновать по квадратам 8х8 из-за гранулярности раскраски, и серьезных сложностей это не доставляло. Тем более, если делать высоту шрифта не кратной 8, придется еще биты сдвигать при выводе.
поэтому единственный выход — держать в ОЗУ контроллера копию экрана
Ну, не совсем. Даже если вы спроектировали шрифт, скажем, высотой 20 точек, и у вас накладываются в одном байте соседние строки, можно при изменении одной строки посмотреть, что находится в другой и совместить нужные байты на лету. Задача, конечно, будет сложнее, но если именно проблема в размере ОЗУ, то сделать такое вполне реально.

Но, конечно, совершенно непонятно, что мешало разработчикам контроллера дисплея реализовать вертикальное окно с разрешением 1 пиксель и просто отсекать лишние биты, оставляя предыдущие значения. Тогда бы проблемы наложения не было бы вообще.
Для цифр использую моноширинные шрифты
Да, это прямо обязательное условие. Не понимаю, почему существуют шрифты, где это не так. Ведь такие даже при печати на бумагу могут проблемы создать — в тех же таблицах цифры не будут друг под другом.
+
avatar
0
  • Leoniv
  • 03 сентября 2025, 19:16
Как вы редактируете сообщение через такой интервал времени?
Окно редактора висело открытым.

Тут вспоминаю проблему из 90-х, когда советские микросхемы имели шаг 2.5 мм, а импортные панельки — 2.54 мм.
Да, с этим проблем было много. Тот же PCAD 4.5, в котором иногда рисовали в «советских дюймах», точно равных 25 мм :) При изготовлении фотошаблонов это надо было указать, иначе масштаб получался не тот.

А вот на счет жесткости ограничения на дизайн не соглашусь
Прямо сейчас у меня в работе прибор с OLED 128х64, сначала пробовал всё сделать кратным 8 — не выходит. Плюнул, сделал вывод шрифтов любого размера и по любым координатам. Тогда всё влезло и красиво расположилось. Хорошо, что место в ОЗУ есть для буфера.

можно при изменении одной строки посмотреть, что находится в другой
А как это посмотреть? Чтение дисплея по SPI или I2C невозможно. Если бы на экране был только текст одного размера, можно было бы хранить копию экрана в текстовом виде. Но обычно экран сложнее.

что мешало разработчикам контроллера дисплея реализовать вертикальное окно с разрешением 1 пиксель
Это было бы идеально. Но — увы…
+
avatar
0
Хорошо, что место в ОЗУ есть для буфера.
Ну, конечно, если есть место в ОЗУ, то проще делать именно так. Более того, отправку данных по I2C можно осуществлять в фоне из этого буфера аппаратно, тогда мы получим полный аналог видеопамяти. И, в принципе, даже в atmega328 такое уже можно сделать, у неё ОЗУ 2 КБ и полностью аппаратный контроллер I2C.
А как это посмотреть? Чтение дисплея по SPI или I2C невозможно.
Я имел в виду, что вы же всегда знаете, что именно у вас отображается на дисплее. Например, там строки:
Voltage: XXXXV
Current: YYYYA
И вам надо обновить значение XXXX, но оно затрагивает ячейки, содержащие YYYY. Вы смотрите, какое сейчас YYYY выведено на экран и комбинируете руками его байты с байтами ХХХХ. В результате получается, что вы перерисовываете только ХХХХ визуально не меняя YYYY, хотя и обновляете байты, которые оно занимает на экране. Это не самый простой метод, но если у вас, например, обозреваемый МК с 512 ОЗУ и 8 КБ ПЗУ, то у вас есть место под лишний код, но нет лишнего места в ОЗУ, и так вполне можно так заморочиться. Была бы необходимость, я бы так сделал, для меня это выглядит интересной программной задачей.
+
avatar
0
  • Leoniv
  • 03 сентября 2025, 22:04
отправку данных по I2C можно осуществлять в фоне
Многие агитируют делать обмен с дисплеем с помощью DMA. Но у меня не получается. Такое бывает редко, что надо обновить весь экран. Обычно выводятся какие-то строки, символы, примитивы. Каждый раз перерисовывается лишь малая часть экрана. И все эти функции работы с дисплеем разбросаны по всей программе. Как тут применить DMA — не понимаю. Другое дело, если видео какое-то показывать, или слайд-шоу.
+
avatar
0
Как тут применить DMA — не понимаю
Так я ровно то же и предлагаю) Организовать буфер экрана в памяти, который через DMA отправлять в дисплей, скажем, 60 раз в секунду. У вас будет полный аналог видеопамяти — вам будет достаточно лишь менять байты в памяти, а на дисплей они будут попадать сами. Кстати, на СТМ это даже быстрее будет — вообще, можно сказать, ресурсов на обмен тратиться не будет.
+
avatar
0
  • Leoniv
  • 04 сентября 2025, 00:11
Ну, DMA тоже занимает внутренние шины процессора. А главное — зачем так нерационально поступать с передачей данных? Типичная ситуация — сижу в меню и редактирую параметр. На дисплее перерисовывается одна цифра, это крошечная часть дисплея. И только когда меняется, а не 60 раз в секунду. Постоянное обновление экрана здесь ни к чему. В отдельных случаях можно запускать DMA, напрмиер, когда происходит переход на другую страницу меню и перерисовывается весь экран.
+
avatar
0
Постоянное обновление экрана здесь ни к чему.
Ни к чему, но так может оказаться даже проще — вам не надо будет инициировать передачу и устанавливать окно вывода в контроллере каждый раз, когда вы выводите символ. Также, если вы выводите несколько символов подряд, основному коду не надо будет ждать, пока предыдущая передача закончится.

А обновлять весь экран, на самом деле, можно и не 60 раз в секунду — вот обновили вы цифру в меню, тогда и перерисовать весь экран. Так, наверное, будет лучше.

Но тут каждый волен выбирать свой путь)
+
avatar
0
  • IWRY
  • 04 сентября 2025, 10:37
зачем так нерационально поступать с передачей данных?
А почему не?
Это приблизит тепловую смерть Вселенной? )))
Если так проще алгоритмически и меньше хлопот на коде, то это хороший путь.
Было бы в миллионную серию… впрочем, нынче и в миллионных сериях такими мелочами не заморачиваются, ибо зачем?
+
avatar
+1
  • Leoniv
  • 04 сентября 2025, 10:44
Почему не? Сложно объяснить словами, но есть какое-то внутреннее чувство рациональности, которое не позволяет. Если бы делал работу за деньги, тогда любой тяп-ляп прошел бы. А когда делается бесплатно, хочется сделать максимально хорошо.
+
avatar
0
  • IWRY
  • 04 сентября 2025, 12:54
Мне кажется странным отношение к «гонянию данных» как к какой-то работе… сижу вот за монитором, отвечаю Вам, и как-то нисколько не напрягает, что по HDMI при этом непрерывным огромным потоком текут терабайты данных, вместо того, чтобы аккуратно перерисовывать только те места на экране, где я набиваю буквы.
Никакого ощущения нерациональности.
Вы как-то иначе это воспринимаете?
+
avatar
+1
  • Leoniv
  • 04 сентября 2025, 13:16
На компьютер никак повлиять нельзя. Там действительно куча неоптимальностей, например, огромное число постоянно работающих ненужных служб. Плюнул на него и каждый раз плачу деньги за более мощное железо вместо оптимизации. Но делать своё устройство с лишней предачей данных как-то не очень приятно. Опять же — за деньги сделаю, но для себя — нет.
+
avatar
0
HDMI при этом непрерывным огромным потоком текут терабайты данных
Да, это общепринятая практика, что данные на дисплей идут непрерывным потоком, поэтому ничего зазорного в том, чтобы сделать точно так же с маленьким дисплеем по I2C нет. Более того, если подумать глубже, так оказывается более правильно — можно постепенно перерисовать отображаемую картинку, а потом сразу одним пакетом отправить её на дисплей, так обновление экрана произойдет «мгновенно».

Но если прямо передавать лишние данные совсем не хочется, можно в коде хранить границы измененного прямоугольника и передавать только его.
+
avatar
0
  • Leoniv
  • 04 сентября 2025, 13:43
I2C будет всегда загружен, больше ничего по нему не подключить. Опять же, выше уровень помех. И потребление выше. Главное — зачем?

В приборах на AVR так делал — выводил сначала в память, в процессе запоминая границы окна и расширяя его при необходимости. А затем обновлял это окно. На STM32 скорость обновления достаточная, для упрощения алгоритма отказался от этой затеи. Просто посимвольно вывожу на дисплей и в память. Из памяти потом беру данные для борьбы с наложением, которое здесь обсуждалось.

Наверное, в процедурах вывода можно сделать флаг, который будет включать режим вывода только в память. А потом делать обновление из памяти всего дисплея. Такой механизм можно использовать в некоторых местах программы, где сменяется сразу весь экран.
+
avatar
0
  • IWRY
  • 04 сентября 2025, 14:10
передавать лишние данные совсем не хочется, можно
Как по мне, лишние телодвижения с кодом имеют смысл только тогда, когда практически оправданы.
Ну, к примеру, если бы это было супер-автономное устройство, где каждый миллиджоуль батарейки на вес золота.
А в привязанном к сети устройстве усложнять программу ради… даже не знаю чего… я бы точно не стал.
Но принимаю как аргумент личные эстетические предпочтения, это неоспоримо в принципе и достойно уважения )
+
avatar
0
есть какое-то внутреннее чувство рациональности, которое не позволяет. Если бы делал работу за деньги, тогда любой тяп-ляп прошел бы
А это не тяп-ляп, это общепринятая практика работы с дисплеями — данные туда идут непрерывно независимо от того, были ли изменения. Что касается рациональности, то далеко не факт, что этот метод нерационален. Например, вы отправляете лишь те данные, которые поменяли и вам нужно вывести строку символов. Вы рисуете первый символ в ОЗУ, после чего инициируете отправку данных (в фоне) на дисплей. Затем рисуете второй, и тут вам нужно дождаться окончания отправки первого или организовывать очередь отправки. Очевидно, что оба решения нерациональны.

С другой стороны, вы быстро выводите всю строку, после чего инициируете отправку всего буфера экрана — с точки зрения шины получается нерационально, но с точки зрения кода наоборот, очень оптимально.
+
avatar
0
  • Leoniv
  • 04 сентября 2025, 13:46
У каждого свои представления о прекрасном. Вам же нравится такты процессора считать и на ASM делать вставки, хоть без этого можно обойтись, сделав менее рациональный код. Так и с обменом. Я не спорю, что обновление всего экрана будет работать, и использовать его проще. Но не нравится, и всё тут.
+
avatar
0
  • vlo
  • 04 сентября 2025, 01:24
Это не самый простой метод, но если у вас, например, обозреваемый МК с 512 ОЗУ и 8 КБ ПЗУ, то у вас есть место под лишний код, но нет лишнего места в ОЗУ, и так вполне можно так заморочиться.
но… зачем для единичного устройства-то? понятно когда тираж в миллионы, тут можно ощутимо сэкономить, но изощряться из-за сотни рублей вместо того что бы взять мк чуть пожирнее можно только из интереса к процессу.
+
avatar
+1
но изощряться из-за сотни рублей вместо того что бы взять мк чуть пожирнее можно только из интереса к процессу.
Так я всегда говорил, что мне нравится программировать на маленьких МК и решать там более сложные задачи. Когда всего в избытке, код можно написать совершенно любой, и он будет работать. А вот если чего-то не хватает, тогда начинается самое интересное — оптимизация.
+
avatar
0
  • vlo
  • 04 сентября 2025, 01:22
Окно редактора висело открытым.
это не помогает — тогда при сохранении ругнется, если прошло больше минут 20ти, чтоль.
+
avatar
+5
  • Berlin
  • 03 сентября 2025, 12:51
ТС мастодонт. Может кто-нибудь подскажет прибор, чтобы измерять ток так же до 20А 12 Вольт, но с Bluetooth и с выводом графика пускового тока на экран телефона. На страйкбольных приводах когда редуктор перебираешь бывает слишком сильно перетянешь винты и ток повышенный.
+
avatar
0
  • vlo
  • 04 сентября 2025, 01:19
если отвлечься от пускового — можно приспособить mysku.club/blog/china-stores/104053.html
если там что-то механически перетянуто, от вырастет же не только пусковой, но и рабочий.
+
avatar
+2
Жму руку! Работа гигантская проделана.
+
avatar
0
Спасибо ТС за подробное описание хода технической мысли.

Пара замечаний:

1. Судя по графику Вы измеряете параметры процесса с частотой около 1.6 герца (4 периода за 2.5 секунды). Почему Вы выбрали скорость измерения в районе 100 Гц? Зачем так часто оцифровывать сигнал? По идее для сигнала с частотой около 1.6 герца достаточно цифровать с частотой 16 герц. Зачем собирать так много данных?
2. Раз уж Вы поставили в цепь мотора свой датчик тока, то почему бы не поставить и реле для размыкания цепи мотора в случае перегрева?
+
avatar
+2
1. На графике приведен пример ходьбы на дорожке со скоростью, кажется, 4 км/ч. Но это далеко не предел, например, на ней можно бежать со скоростью 12 км/ч. И тогда частота колебаний увеличится раза в 3, то есть, будет уже 4.8 Гц. И по вашему же подсчету тут уже надо будет 48 измерений в секунду. А график как раз и обновляется со скоростью 50 раз в секунду. Сами измерения происходят чаще, 150 раз в секунду, но это позволяет, во-первых, регистрировать короткие пики (а они тут реально короткие), а, во-вторых, график за счет этого выглядит значительно красивее, практически непрерывным.

2. Во-первых, не известно, что произойдет с контроллером дорожки, если на ходу вдруг отключить двигатель. В лучшем случае он выпадет в ошибку. Во-вторых, если вы бежите на дорожке с приличной скоростью, например, 9 км/ч и вдруг отключить двигатель, с большой долей вероятности, вы врежетесь в переднюю часть или просто свалитесь с неё, потому что полотно остановится достаточно резко. То есть, тут однозначно лучше просто сообщать о перегреве, но не принимать никаких действий.
+
avatar
+1
Спасибо за статью. Очень полезна для пополнения знаний в схемотехнике. Так же, интересно было посмотреть как автор пишет код. Многое распечатаю для обучения. Прочитал «от корки до корки».
+
avatar
+2
Спасибо за оценку.
Многое распечатаю для обучения.
По сути, именно на это и рассчитывал, т.к. сам люблю читать такие статьи.
+
avatar
+1
  • Krascher
  • 09 сентября 2025, 12:37
Всегда было интересно… Существуют ли приборы, способные определить поведение электродвигателя с момента пуска и до выхода на рабочий режим… Скажем, максимальный бросок потребляемого тока,…
Особенно актуально это (мне лично, например) для ручного аккумуляторного электроинструмента.
Ну и, соответственно — потребляемый от аккумуляторов ток при нагрузке на этот самый электроинструмент.
Хоть, бери пишущий осциллограф и рисуй график тока. (Есть ли такое?)
Просто, лет пять назад купил т.н. «микроболгарку».
В первый, как и во второй день — был разочарован. Болгарка запускалась, но, работать отказывалась. Дохла при любых попытках что либо резать-шлифовать. Забросил на антресоли. Через пару лет увидел вполне рабочую — такую же у знакомого.
Ещё через годик — встретил несколько обзоров на подобные девайсы…
Понял, что проблема у меня — в самих аккумуляторах.
Стал переделывать. Вроде, заработало.
Попутно — весь остальной свой «парк инструмента» переводил на единый «форм-фактор» — «макитовский».
И, вот здесь уже потребность в подобном токоизмерительном приборе встала в полный рост.
А в целом, статья отличная. Жаль «не по сеньке шапка»…
+
avatar
0
Скажем, максимальный бросок потребляемого тока,…
Так это вам просто амперметр нужен. Здесь рекомендовали ToolkitRC WM150

mysku.club/blog/china-stores/78614.html

На первый взгляд, прибор интересный и как раз ваши потребности закрыть должен.
потребляемый от аккумуляторов ток при нагрузке на этот самый электроинструмент.
Если свои хотите значения получать, то вот этим прибором можно. В целом, если говорить про Макиту LXT, общая тенденция такая — шуруповерты до 40 А, особо мощные — до 50 А. Болгарка — до 60 А — 70 А, но это если жать сильно. Так в 40 А можно уложиться.
Просто, лет пять назад купил т.н. «микроболгарку».
Да, в комплекте к ней идет шлак, а не аккумуляторы — у меня были банки с сопротивлением 50 мОм (против 14 у нормальных). Менять сразу, и тогда ей что-то уже можно пилить. А еще говорят, лучше брать обычные огрызки от наших дисков, а не китайские, они тоже лучше пилят.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.