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

Поскольку стояла задача наладить работу шлагбаумов, пришлось разобраться как они устроены. Настроек у них довольно много, однако нам достаточно знать, что 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В, но при отсутствии напряжения замыкает свой дополнительный контакт с одним из оставшихся, тем самым получается ровно то что нам нужно.

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

Комментарии (9)


  1. xSVPx
    12.05.2026 07:33

    Не перекусит ли кого зазевавшегося оная калитка ? Очевидно нужна система безопасности не хуже чем у ворот...

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


    1. lak_inside Автор
      12.05.2026 07:33

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


      1. xSVPx
        12.05.2026 07:33

        Яркость светофора в 99% случаев можно убавить поменяв резистор на плате со светодиодами. (Токозадаюший конечно, не надо последовательно ничего ставить :).

        Т.е. если сосиску засунуть куда-нибудь в петли он ее не повредит ?


        1. lak_inside Автор
          12.05.2026 07:33

          Плата со светодиодами залита герметиком на заводе, ковырять ее желания нет.

          Сосиску не пробовал, но ногой остановить можно и не больно.


          1. xSVPx
            12.05.2026 07:33

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

            Мизинец сувай...


  1. Lotov
    12.05.2026 07:33

    Автономный светофор на солнечной батарее у меня рядом с домом стоит , а я - север некий ( СПБ ) . Круглый год мигает он , а Вам нужно о питание вашей конструкции думать


    1. lak_inside Автор
      12.05.2026 07:33

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


  1. vbifkol
    12.05.2026 07:33

    У меня когнитивный диссонанс от бюджетирования. То "домомфон стоит всего 25000", то "выпилили из фанеры", "был вемос под рукой". Не говоря уже о том, что по сравнению с оплатой охранников и домофон и светофор в сборе - копейки.


    1. lak_inside Автор
      12.05.2026 07:33

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

      И если о светофоре не подумали, то извините, 20 тыс за готовую конструкцию отдать нельзя! А что-то там на коленке и за пару тысяч -- можно, на личном энтузиазме так сказать.

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

      Так что если хочется что-то сделать за деньги товарищества, нужно составить смету, на следующем голосовании (через год например) ее принять, со всех собрать деньги и только после этого купить