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

推荐订阅源

Recorded Future
Recorded Future
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Forbes - Security
Forbes - Security
N
News and Events Feed by Topic
SecWiki News
SecWiki News
T
The Exploit Database - CXSecurity.com
S
Security @ Cisco Blogs
H
Heimdal Security Blog
Security Latest
Security Latest
T
Threatpost
V2EX - 技术
V2EX - 技术
C
Cybersecurity and Infrastructure Security Agency CISA
GbyAI
GbyAI
The Last Watchdog
The Last Watchdog
Recent Announcements
Recent Announcements
P
Privacy International News Feed
K
Kaspersky official blog
P
Proofpoint News Feed
L
LangChain Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
T
Threat Research - Cisco Blogs
博客园_首页
T
Tor Project blog
M
MIT News - Artificial intelligence
The Hacker News
The Hacker News
The GitHub Blog
The GitHub Blog
月光博客
月光博客
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
F
Full Disclosure
MyScale Blog
MyScale Blog
The Register - Security
The Register - Security
Engineering at Meta
Engineering at Meta
Y
Y Combinator Blog
Cyberwarzone
Cyberwarzone
L
LINUX DO - 最新话题
量子位
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
O
OpenAI News
T
The Blog of Author Tim Ferriss
S
Schneier on Security
小众软件
小众软件
The Cloudflare Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Know Your Adversary
Know Your Adversary
Microsoft Security Blog
Microsoft Security Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
Lohrmann on Cybersecurity
Vercel News
Vercel News

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

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче 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 миллионов точек без потерь
Автоматизируем посёлок ч. 2: светофор своими руками
lak_inside · 2026-05-12 · via Все публикации подряд на Хабре

Уровень сложностиПростой

Время на прочтение7 мин

Охват и читатели140

Туториал

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

Поскольку стояла задача наладить работу шлагбаумов, пришлось разобраться как они устроены. Настроек у них довольно много, однако нам достаточно знать, что 99% всех шлагбаумов и откатных ворот как основной интерфейс для взаимодействия с управляющими устройствами используют "сухие контакты". Другими словами, внутри у них есть пара контактов, которые можно замкнуть — и тогда шлагбаум откроется, и будет открытым до тех пор, пока контакты соединены. После размыкания он ждет некоторое время и закрывается. Прикрепите к этим контактам обычную кнопку — и простейший пульт управления готов. В нашем случае вместо кнопки используются различные устройства, выполняющие ту же функцию (замыкающие 2 контакта). Это ethernet реле (управляемое через REST API или MQTT), домофон, электромагнитная петля на выезд, раньше еще было GSM-реле.

Типичное реле: коробочка с контактами, которые оно замыкает и размыкает по команде

Типичное реле: коробочка с контактами, которые оно замыкает и размыкает по команде

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

Светофор

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

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

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

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

Осталось подключить его к шлагбауму. Логика представлялась простая: когда замкнуты контакты "кнопки" шлагбаума, зеленый свет должен гореть, когда разомкнуты -- не гореть. Как этого добиться? Например, собрать простейшую цепь из источника 12В и светофора и замыкать/размыкать эту цепь теми же реле ("кнопкой"), что используется для управления шлагбаумом. Но практика показала, что так это не работает.

Пробный вариант подключения

Пробный вариант подключения

Шлагбаум определяет, что на его "сухих контактах" появилось напряжение и воспринимает это как сигнал к открытию, и остается открытым независимо от состояния "кнопки". Решение заключается в использовании реле (других, автомобильных): "кнопка" включает два реле, которые уже замыкают контакты шлагбаума и цепь светофора соответственно.

Исправленная схема подключения. Использованы два 4-контактных реле

Исправленная схема подключения. Использованы два 4-контактных реле

Автомобильное 4-контактное реле. Если на два контакта подать 12В, оставшиеся два будут замкнуты.

Автомобильное 4-контактное реле. Если на два контакта подать 12В, оставшиеся два будут замкнуты.

Схема работает, все хорошо, но хочется большего: поведения "настоящего светофора".

Цикл работы шлагбаума светофор горит пока "кнопка" нажата.

Цикл работы шлагбаума светофор горит пока "кнопка" нажата.

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

Желаемый цикл работы светофора, с мигающим зеленым и красным.

Желаемый цикл работы светофора, с мигающим зеленым и красным.

Готовых решений для такого найдено не было, а значит, настало время колхозить самостоятельно. Поскольку шлагбаумы работают и на въезд, и на выезд, светофор было решено сделать двухсторонним, вторая сторона для тех кто выезжает из посёлка. Получилось 4 светодиодных модуля: 2 зеленых и 2 красных. Был взят контроллер Wemos D1 Mini (подойдет любой ардуино-подобный, он просто имелся под рукой), а к нему -- модуль на 4 реле.

К двум пинам контроллера подключаем две "кнопки" (у нас два шлагбаума, въезд и выезд), вторые контакты "кнопок" -- к пину GND. Wemos D1 умеет работать с кнопками без дополнительного подтягивающего резистора, главное не забыть включить нужную опцию при настройке работы пина. Еще к 4 пинам подключаем реле.

Код для контроллера
const int buttonPin = D5;     // пин первой "кнопки"
const int button2Pin = D6;     // пин второй "кнопки"
const int red1Pin = D1;     // реле дла первого красного светофора
const int green1Pin = D2;     // реле дла первого зеленого светофора
const int red2Pin = D3;     // реле дла второго красного светофора
const int green2Pin = D4;     // реле дла второго зеленого светофора


unsigned long debounceDelay = 50;    // debounce для "кнопок"
unsigned long flashDuration = 350;    // длительность "мигания"

bool buttonState = HIGH;     
bool lastButtonState = HIGH; 

unsigned long lastDebounceTime = 0;  // время последнего изменения статуса кнопки 1
unsigned long flashSequenceStart = 0;  // время начала моргания
unsigned long timeFromFlashingStart = 0;  // текущая длительность моргания

bool buttonState2 = HIGH;      
bool lastButtonState2 = HIGH;

unsigned long lastDebounceTime2 = 0;  
unsigned long flashSequenceStart2 = 0; 
unsigned long timeFromFlashingStart2 = 0;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP); // встроенный подтягивающий резистор для кнопки
  pinMode(button2Pin, INPUT_PULLUP); 
  pinMode(red1Pin, OUTPUT);
  pinMode(green1Pin, OUTPUT);
  pinMode(red2Pin, OUTPUT);
  pinMode(green2Pin, OUTPUT);
  digitalWrite(red1Pin, LOW); // В начале включаем зеленый и выключаем красный
  digitalWrite(green1Pin, HIGH); 
  digitalWrite(red2Pin, LOW); 
  digitalWrite(green2Pin, HIGH); 
}

void loop() {
  loop1();
  loop2();
}

void loop1() {
  // Читаем положение кнопки 1
  bool reading = digitalRead(buttonPin);

  // debounce для кнопки 
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if (millis() < lastDebounceTime) {
    lastDebounceTime = 0;
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // подождали 50 мс, чтобы исключить много коротких нажатий (debounce) 
    if (reading != buttonState) {
      buttonState = reading;
      // если кнопка отпущена, начинаем моргать
      if (buttonState == HIGH) {
        flashSequenceStart = millis();
      }

    }
  }

      // "кнопку" нажали
      if (buttonState == LOW) {
        digitalWrite(green1Pin, LOW); // Turn LED on
        digitalWrite(red1Pin, HIGH); // Turn LED on
      } 
      // "кнопку" отпустили
      else {
        // моргаем 3 раза (по времени, прошедшему с отпускания кнопки, определяем, какой свет зажечь сейчас)

    timeFromFlashingStart = millis() - flashSequenceStart;

    if (timeFromFlashingStart >= 0 and timeFromFlashingStart < flashDuration) {
      digitalWrite(green1Pin, HIGH);
    }
    if (timeFromFlashingStart >= flashDuration and timeFromFlashingStart < flashDuration * 2) {
      digitalWrite(green1Pin, LOW);
    }
    if (timeFromFlashingStart >= flashDuration * 2 and timeFromFlashingStart < flashDuration * 3) {
      digitalWrite(green1Pin, HIGH);
    }
    if (timeFromFlashingStart >= flashDuration * 3 and timeFromFlashingStart < flashDuration * 4) {
      digitalWrite(green1Pin, LOW);
    }
    if (timeFromFlashingStart >= flashDuration * 4) {
      digitalWrite(green1Pin, HIGH);
    }
    if (timeFromFlashingStart >= flashDuration * 6) {
      digitalWrite(red1Pin, LOW);
    }
      }
  // Save the current reading for next loop
  lastButtonState = reading;
}

void loop2() {
  // то же самое но для кнопки 2
  bool reading = digitalRead(button2Pin);

  if (reading != lastButtonState2) {
    lastDebounceTime2 = millis();
  }
  
  if (millis() < lastDebounceTime2) {
    lastDebounceTime2 = 0;
  }

  if ((millis() - lastDebounceTime2) > debounceDelay) {
    if (reading != buttonState2) {
      buttonState2 = reading;
      if (buttonState2 == HIGH) {
        flashSequenceStart2 = millis();
      }

    }
  }

      if (buttonState2 == LOW) {
        digitalWrite(green2Pin, LOW); // Turn LED on
        digitalWrite(red2Pin, HIGH); // Turn LED on
      } 
      else {

    timeFromFlashingStart2 = millis() - flashSequenceStart2;

    if (timeFromFlashingStart2 >= 0 and timeFromFlashingStart2 < flashDuration ) {
      digitalWrite(green2Pin, HIGH);
    }
    if (timeFromFlashingStart2 >= flashDuration and timeFromFlashingStart2 < flashDuration * 2) {
      digitalWrite(green2Pin, LOW);
    }
    if (timeFromFlashingStart2 >= flashDuration * 2 and timeFromFlashingStart2 < flashDuration * 3) {
      digitalWrite(green2Pin, HIGH);
    }
    if (timeFromFlashingStart2 >= flashDuration * 3 and timeFromFlashingStart2 < flashDuration * 4) {
      digitalWrite(green2Pin, LOW);
    }
    if (timeFromFlashingStart2 >= flashDuration * 4) {
      digitalWrite(green2Pin, HIGH);
    }
    if (timeFromFlashingStart2 >= flashDuration * 6) {
      digitalWrite(red2Pin, LOW);
    }
      }
  
  lastButtonState2 = reading;
}
Внутри тумбы шлагбаума вся электроника убрана в пластиковую коробку, на крышке которой закреплены клеммы для подключения и пара тумблеров для открытия шлагбаумов, например, на время ремонта.

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

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

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

Домофон и калитка

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

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

Помимо этого, появилась возможность сделать калитку очень широкой, чтобы в нее точно было легко пройти или проехать. Открывать такую калитку руками было бы неудобно. Управляется привод точно так же как шлагбаум: замкнули 2 контакта и дверь открылась. Остается их замкнуть по команде от домофона. Но вот проблема: домофон разрабатывался под электромагнитные замки, популярные в подъездах, а управляются они совсем иначе. Если на замок подать 12В, то электромагнит начинает работать и удерживает дверь. Если надо открыть дверь, напряжение убирается и магнит её отпускает. Получается, нам нужно чтобы когда на контактах домофона было 12В, контакты привода калитки были разомкнуты, а когда 12В пропало, контакты должны сразу замкнуться. Помогло нам в этом автомобильное реле, очень похожее на описанные ранее, но c одним дополнительным контактом.

5-контактное реле

5-контактное реле

Управляется это реле так же 12В, но при отсутствии напряжения замыкает свой дополнительный контакт с одним из оставшихся, тем самым получается ровно то что нам нужно.

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