惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
O
OpenAI News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Threat Research - Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Google Online Security Blog
Google Online Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
N
News and Events Feed by Topic
S
Security Affairs
SecWiki News
SecWiki News
Project Zero
Project Zero
L
Lohrmann on Cybersecurity
P
Proofpoint News Feed
P
Palo Alto Networks Blog
L
LINUX DO - 最新话题
H
Hacker News: Front Page
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
Intezer
Simon Willison's Weblog
Simon Willison's Weblog
W
WeLiveSecurity
T
The Exploit Database - CXSecurity.com
K
Kaspersky official blog
The GitHub Blog
The GitHub Blog
I
InfoQ
云风的 BLOG
云风的 BLOG
雷峰网
雷峰网
B
Blog
IT之家
IT之家
AWS News Blog
AWS News Blog
Jina AI
Jina AI
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Google DeepMind News
Google DeepMind News
Spread Privacy
Spread Privacy
N
News and Events Feed by Topic
Security Latest
Security Latest
美团技术团队
C
Check Point Blog
WordPress大学
WordPress大学
T
Tenable Blog
S
Security @ Cisco Blogs
Last Week in AI
Last Week in AI
博客园 - 聂微东
月光博客
月光博客
博客园 - 【当耐特】
S
Schneier on Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
Secure Thoughts
Schneier on Security
Schneier on Security
C
Cisco Blogs
Cyberwarzone
Cyberwarzone

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Кто решает судьбу вашего проекта? Разбираем заинтересованные стороны. BABOK #1 Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Лампа плавного пуска
aabzel · 2026-06-13 · via Все публикации подряд на Хабре

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

Постановка задачи
Разработать прототип вело-фары с плавным включением и плавным отключением. Яркость должна изменяться постепенно. Обеспечить возможность дистанционного включения лампы (например по IR пульту). Сделать возможность регулирования яркости свечения через инкрементный энкодер. Настройки интенсивности свечения сохранять в энергонезависимой памяти NVRAM. Попробовать два алгоритма регулирования яркости : PWM и PDM.

Аппаратная часть

В качестве отладочной платы для прототипа я по-прежнему выбрал с JZ-F407VET6.

Распиновка для сборки прототипа такая

GPIO

Pull

Wire Name

Dir

Comment

PE0

Up

Encoder A

in

Инкрементный энкодер

PE1

Up

Encoder B

in

Инкрементный энкодер

PA6

up

IR sensor

in

TSOP-36

PA9

no

USART1_TX

out

CLI

PA10

up

USART1_RX

in

CLI

PA0

none

TIM5_CH1

out

PWM

PA3

none

TIM9_CH2

out

PWM

PE4

none

DeltaSigma

out

PDM

В роли драйвера 12-вольтового LED я выбрал микросхему H-моста DRV8870. Вот так выглядит отладочная плата для этой микросхемы.

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

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

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

Весь прототип выглядит вот так

В чем трудность управления LED фонарями?

1) Главная особенность LED лампы (в отличие от ламп накаливания) в том, что она полностью без инерционная. То есть, если с нуля подать скважность 100%, то лампа в самом деле мгновенно и ослепительно включится на 100%. Выглядит как вспышка. Для меня это как раз нежелательный сценарий. Я хочу сделать искусственную инерционность LED лампы. Чтобы хрусталики глаз могли приспособиться к постепенному нарастанию яркости. Как же мне этого добиться?

2) Вторая особенность LED в том, что LEDы не так-то просто плавно включить. Уже при 0.7 % заполнения LED включается и это тоже визуально воспринимается как резкое включение. Хочется как-то сделать акцент именно на начальной фазе нарастания яркости и на фазе окончательного потухания. Добавить программную инерционность вокруг нулевого заполнения.

Программная часть

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

В коде он выглядит так

Экспоненциальное нарастание и спад яркости LED-а
import matplotlib.pyplot as plt
import numpy as np

max_illum=100.0
scale = 0.5
time_s = np.arange(1, 7)
time_max=10
time_s = np.linspace(0, time_max, 100)
illumination_climax = max_illum*(1.0-  np.exp(-scale*time_s))
illumination_decay =  max_illum* np.exp(-scale*time_s)

plt.plot(time_s, illumination_climax)
plt.plot(time_s, illumination_decay)
 
plt.title('Illumination change')
plt.xlabel('Time,[s]')
plt.ylabel('Light level, [Lx]')
plt.grid()
plt.show()

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

 Логистическая функция

Логистическая функция

Вот ее графики

Можно поэкспериментировать с различными параметрами переходного процесса отрисовывая графики: длительность переходного процесса и коэффициент в степени.

Код построения логистической кривой
import matplotlib.pyplot as plt
import numpy as np

max_illum=100.0
scale = 0.95
time_s = np.arange(1, 7)
time_max=10
time_s = np.linspace(0, time_max, 100)
time1_s=time_s-time_max/2
illumination_climax = max_illum*1.0/(1.0 +  np.exp(-scale*time1_s))
illumination_decay =   max_illum-illumination_climax
 
#illumination_decay1 =   max_illum* np.exp(-scale*time_s)

plt.plot(time_s, illumination_climax)
plt.plot(time_s, illumination_decay)
 
plt.title('Illumination change')
plt.xlabel('Time,[s]')
plt.ylabel('Light level, [Lx]')
plt.grid()
plt.show()

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

PID регулятор

Чтобы решить эту проблему я обратился к PID регулятору. PID-регулятор — это программа, которая читает показания датчика и управляет мощностью так, чтобы значение датчика стало тем, что вы задали. Что, если энкодером и кнопками задавать целевое значение для PID регулятора? При этом PID регулятор уже сам будет как-то делать желаемый переходной процесс. Главная роль тут отводится интегральной части регулятора. Ее вклад в финальное заполнение и будет вносить основной результат. Однако и тут облом. Дело в том, что сразу после установки нового целевого значения яркости образуется максимальная ошибка (погрешность). Это приводит к интенсивному нарастанию яркости на начальном этапе, которое как раз и портит весь визуальный эффект. Как же быть?

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

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

bool pid_target_set(uint8_t num, float target) {
    bool res = false;
    PidHandle_t* Node = PidGetNode(num);
    if(Node) {
        res = is_float_equal_absolute(target, Node->target,0.0001);
        if(!res) {
            LOG_INFO(PID, "PID%u,Set,Target:%f->%f", num, Node->target, target);
            Node->last_target = Node->target; // !!!!!!!
            Node->target = target;
            res = true;
        }
    } else {
        LOG_ERROR(PID, "NodeErr,PID%u", num);
    }
    return res;
}

Затем на каждой итерации PID регулятора вычислять абсолютное значение смещения shift = |out - last_target|

Благодаря вычислению смещения можно на каждой итерации PID регулятора вычислять такое приращение к интегральной части, которое в результате и сделает нам S-образный переходной процесс (см зелёный график d ). Дифферециальная часть PID регулятора тут и вовсе не нужна. Коэффициент D можно обнулить. Однако, чтобы процесс начался нужно сделать ненулевой пропорциональный коэффициент. Код ядра PID регулятора получается такой.

static bool pid_proc_value_ll(PidHandle_t* const Node) {
    bool res = false;
    if(Node) {
        Node->shift = Node->last_target - Node->out;
        Node->d_sum = 0.0f;
        if(0.0 < Node->error) {
            Node->d_sum = MATH_MIN(fabsf(Node->shift),Node->error);
        } else {
            Node->d_sum = MATH_MAX(-fabsf(Node->shift),Node->error);
        }
        Node->error_sum += Node->d_sum;
   
        Node->out = 0.0f;
        Node->out += Node->p * Node->error;
        Node->out += Node->i * Node->error_sum;
        
        LOG_DEBUG(PID, "%s", PidNodeToStr(Node));
        res = true;
    }
    return res;
}

Вот так это работает в реальности. Перед Вами график заполнения PWM от времени прочитанный из реального UART лога. Как видно, это S-образный переходной процесс, который рассчитывается в потоковом режиме.

Управление заполнением PWM от времени

Управление заполнением PWM от времени

Варьируя интегральный коэффициент можно управлять скоростью переходного процесса.

Управление яркостью на низком уровне

Второй вопрос, что выбрать для непосредственного регулирования яркости: PWM или PDM?

Проблема PWM в том, что он не позволяет непрерывно включаться с нуля и включает ярость скачком уже на 0.7% заполнения. Поэтому я попробовал запрограммировать программный PDM.

Настроил прерывания по таймеру 1 c частотой 20kHz. В обработчике прерываний стал делать вычисление PDM семплов.


bool delta_sigma_isr_proc_one_ll(DeltaSigmaHandle_t* Node) {
    bool res = false;
    Node->error = Node->target - Node->dac_out;
    Node->sum_error += Node->error;
    Node->pdm = adc_1bit(Node->sum_error, Node->comparator_middle);

    res = gpio_logic_level_set(Node->Pad, (GpioLogicLevel_t)Node->pdm);
    Node->dac_out = dac_1bit(Node->pdm, Node->min, Node->max);
    Node->sample_cnt++;
    return res;
}

Однако это дело не улучшило. PDM дает заметное мерцание на малой яркости. В результате я выбрал PWM, который по крайней мере не мерцает.

В результате, прошивка приняла такую структуру.

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

Итог

Удалось сделать прототип электроники и прошивки для велосипедной фары, который позволяет производить плавное управление яркостью LED при помощи инкрементного энкодера. Также заложен алгоритм плавного включения и отключения фары. Удалось сделать S-образный переходной процесс при помощи слегка модернизированного PI-регулятора.

Прошивка готова и ее можно скачать на github. Дальнейшим развитием проекта может быть проработка электропитания, разработка миниатюрной PCB, конструктива и крепления вело фары.

Ссылки

Вопросы:
1) Как при помощи PID регулятора сделать S-образный переходной процесс?
2) Как избавиться от мерцания при PDM управлении свечением?
3) Существуют ли в продаже миниатюрные отладочные платы с STM32, GPIO разъемами и драйвером hi-side ключей, чтобы управлять автомобильными LEDами.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Проголосовали 9 пользователей. Воздержался 1 пользователь.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Проголосовали 11 пользователей. Воздержавшихся нет.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Проголосовали 10 пользователей. Воздержавшихся нет.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Проголосовали 10 пользователей. Воздержавшихся нет.