Модель железной дороги дома (часть 6)

Опубликовано: 23.12.2020
Автор: Виталий Бочкарев
Поддержать автора статьи по этой ссылке

Начало в заметке "Быт - Модель железной дороги (часть 5)".

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

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

Электроника разворотной петли

Компоненты:

  1. Контроллер Arduino UNO R3 (или Arduino Mini со стабилизатором LM2596).
  2. Блок из 2 реле.
  3. Блок из 4 реле.
  4. Привод стрелки PIKO 55271.
  5. Изоляторы рельс PIKO 55291.
  6. Герконы 2.
  7. Резисторы 10 кОм.
  8. Соединительные провода.
  9. Клеммная колодка.
  10. Корпус или подложка для крепления электроники.

Home railway model - 52

 

Алгоритм работы разворотной петли

Home railway model - 53

Схема 0 – выключено
- На магистраль подан сигнал DCC;
- На контроллер Arduino питание не подано;
- На разворотную петлю сигнал DCC не подан;
- Реле RL1: K1 и K2 разомкнуты – питание на привод стрелки не подано, стрелка в неизвестном состоянии;
- Реле RL2: K1 и K2 разомкнуты – питание на разворотную петлю не подано;
- Реле RL2: К3 и К4 в положении, подготовленном для прямого питания петли;
- От датчиков D1 и D2 нет никакого сигнала.

Схема 1 – подготовка к работе
- На магистраль подан сигнал DCC (далее этот пункт не указывается, подразумевается, что на магистрали напряжение есть всегда);
- На контроллер Arduino подано питание;
- Контроллер дает команду на перевод стрелки S1 в правое положение (если смотреть от входящего поезда);
- Контроллер дает команду на замыкание RL2.1 и RL2.2
- На разворотную петлю подан прямой сигнал DCC;
- Биты памяти M1 и М2 пустые;
- Разворотная петля готова к приему поезда

Home railway model - 54

Схема 2 – прием поезда справа
- Поезд входит в разворотную петлю и пересекает датчик D1;
- Датчик D1 посылает сигнал в контроллер, что на участке есть состав (геркон замыкается магнитом на днище локомотива);
- Контроллер устанавливает в памяти бит M1 в 1;

Схема 3 – подготовка к переключению полярности
- Поезд находится в разворотной петле и пересекает датчик D2;
- Датчик D2 посылает сигнал в контроллер, что на участке есть состав;
- Контроллер проверяет в памяти бит M1, если M1 = 1, то это означает, что поезд выходит из петли слева – необходимо перевести стрелку влево;

Схема 4 – переключение полярности, фаза 1 - обесточивание петли
- Контроллер посылает сигнал на размыкание RL2.1 и RL2.2;
- Разворотная петля обесточивается – поезд останавливается;
- Контроллер посылает сигнал на размыкание RL2.3 и RL2.4;

Схема 5 – переключение полярности, фаза 2 - подключение к магистрали с обратной полярностью
- Контроллер посылает сигнал на перевод стрелки S1 в левое положение;
- Контроллер посылает сигнал на замыкание RL2.1 и RL2.2;
- На разворотную петлю посылается обратный DCC сигнал;
- Поезд может выходить из разворотной петли;

Схема 6 – выход поезда
- Датчики D1 и D2 не фиксируют нахождение поезда в течении 30 секунд;
- Контроллер очищает биты присутствия поезда M1 и M2;
- Разворотная петля готова к приему поезда слева.

Home railway model - 55

Схема 7 – прием поезда слева
- Поезд входит в разворотную петлю и пересекает датчик D2;
- Датчик D2 посылает сигнал в Arduino, что на участке есть состав;
- Arduino устанавливает бит M2 в 1;

Схема 8 – подготовка к переключению
- Поезд находится в разворотной петле и пересекает датчик D1;
- Датчик D1 посылает сигнал в Arduino, что на участке есть состав;
- Arduino проверяет бит M2, если M2 = 1, то поезд выходит из петли справа – необходимо перевести стрелку вправо;

Схема 9 – переключение фаза 1
- Arduino посылает сигнал на размыкание RL2.1 и RL2.2;
- Разворотная петля обесточивается – поезд останавливается;
- Arduino посылает сигнал на замыкание RL2.3 и RL2.4;

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

 

Листинг программы для контроллера Arduino

//#include <Bounce2.h>

#define SERIAL_SPEED 9600   // скорость порта ввода-вывода
#define SENSOR_DELAY 30000  // время на прохождение петли 30 секунд
#define RELAY_DELAY 100     // время задержки переключения реле
#define SWITCH_TIME 500     // время переключения стрелки

// Установка номеров контактов
const byte Sensor1_Pin = 2;
const byte Sensor2_Pin = 4;
const byte Led_Pin =  13;
const byte SwitchRight_Pin =  8;
const byte SwitchLeft_Pin =  9;
const byte Power1_Pin =  10;
const byte Power2_Pin =  11;

// Инверстная логика реле
const byte RelayON = LOW;
const byte RelayOFF = HIGH;

// флаги прохода датчиков
byte Sensor1_Passed = 0;
byte Sensor2_Passed = 0;

// таймеры датчиков
long Sensor1_Timer = 0;
long Sensor2_Timer = 0;

// флаг положения стрелки: 0 - вправо, 1 - влево
byte TurnOutPosition = 1;

void setup() {
  Serial.begin(SERIAL_SPEED);
  Serial.println("--- Initialization started ---");
  
  // Инициализация выходов
  pinMode(Led_Pin, OUTPUT);
  pinMode(SwitchRight_Pin, OUTPUT);
  pinMode(SwitchLeft_Pin, OUTPUT);
  pinMode(Power1_Pin, OUTPUT);
  pinMode(Power2_Pin, OUTPUT);
  
  // Отключение всех реле
  digitalWrite(SwitchRight_Pin, RelayOFF);
  digitalWrite(SwitchLeft_Pin, RelayOFF);
  digitalWrite(Power1_Pin, RelayOFF);
  digitalWrite(Power2_Pin, RelayOFF);

  // Инициализация входов
  pinMode(Sensor1_Pin, INPUT);
//  pinMode(Button1bPin, INPUT);
  pinMode(Sensor2_Pin, INPUT);
//  pinMode(Button2bPin, INPUT);
  
  delay(500);
  // Перевод стрелки в начальное положение
  MoveSwitchRight();
  Serial.println("--- Initialization finished ---");
  Serial.println();
}

void loop() {
  
  // прохождение состава справа

  // Прохождение локомотивом датчика 1
  if (digitalRead(Sensor1_Pin) == HIGH && Sensor1_Passed == 0 && Sensor2_Passed == 0) {
    Serial.println("Sensor 1 is ON");
    // Запуск таймера датчика 1
    Sensor1_Timer = millis();
    // Установка флага прохождения датчика 1
    Sensor1_Passed = 1;
    Serial.println("Waiting for Sensor 2");
  }

  // Прохождение локомотивом датчика 2 и проверка, что датчик 1 был пройден
  if ((digitalRead(Sensor2_Pin) == HIGH) && Sensor1_Passed == 1 && Sensor2_Passed == 0) {
    Serial.println("Sensor 2 is ON+");
    // Проверка, что датчики сработали через разрешенное время
    if ((millis() - Sensor1_Timer) < SENSOR_DELAY) {
      Serial.println("Ready for switching");
      // Перевод стрелки влево
      MoveSwitchLeft();
    }
  }

  // прохождение состава слева

  // Прохождение локомотивом датчика 2
  if (digitalRead(Sensor2_Pin) == HIGH && Sensor2_Passed == 0 && Sensor1_Passed == 0) {
    Serial.println("Sensor 2 is ON");
    // Запуск таймера датчика 2
    Sensor2_Timer = millis();
    // Установка флага прохождения датчика 2
    Sensor2_Passed = 1;
    Serial.println("Waiting for Sensor 1");
  }

  // Прохождение локомотива датчика 1 и проверка, что датчик 2 был пройден
  if ((digitalRead(Sensor1_Pin) == HIGH) && Sensor2_Passed == 1 && Sensor1_Passed == 0) {
    Serial.println("Sensor 1 is ON+");
    // Проверка, что датчики сработали через разрешенное время
    if ((millis() - Sensor2_Timer) < SENSOR_DELAY) {
      Serial.println("Ready for switching");
      // Перевод стрелки вправо
      MoveSwitchRight();
    }
  }

// Сброс флагов прохождения и таймеров датчиков
  if ((millis() - Sensor1_Timer) > SENSOR_DELAY && Sensor1_Passed == 1) {
    Serial.println("Sensor 1 is ready for next cycle");
    Sensor1_Passed = 0;
  }

  if ((millis() - Sensor2_Timer) > SENSOR_DELAY && Sensor2_Passed == 1) {
    Serial.println("Sensor 2 is ready for next cycle");
    Sensor2_Passed = 0;
    //Sensor2_Timer = millis();
  }
  
}

/* Функция перевода стрелки вправо */
void MoveSwitchRight () {
  // Проверка, что стрелка еще не переведена вправо
  if (TurnOutPosition == 1) {
    Serial.println("Moving switch to Right");
    // Отключение питания петли
    digitalWrite(Power1_Pin, RelayOFF);
    Serial.println("  Loop power is OFF");
    delay(RELAY_DELAY);
    // Прямая коммутация петли и перевод стрелки
    digitalWrite(Power2_Pin, RelayOFF);
    Serial.println("  Loop power is DIRECT");
    digitalWrite(SwitchRight_Pin, RelayON);
    delay(SWITCH_TIME);
    digitalWrite(SwitchRight_Pin, RelayOFF);
    Serial.println("  Turnout is moved to Right");
    // Включение питания петли
    delay(RELAY_DELAY);
    digitalWrite(Power1_Pin, RelayON);
    Serial.println("  Loop power is ON");
    TurnOutPosition = 0;   
  }
}

/* Функция перевода стрелки влево */
void MoveSwitchLeft () {
  // Проверка, что стрелка еще не переведена влево
  if (TurnOutPosition == 0) {
    Serial.println("Moving switch to Left");
    // Отключение питания петли
    digitalWrite(Power1_Pin, RelayOFF);
    Serial.println("  Loop power is OFF");
    delay(RELAY_DELAY);
    // Обратная коммутация петли и перевод стрелки
    digitalWrite(Power2_Pin, RelayON);
    Serial.println("  Loop power is REVERSED");
    digitalWrite(SwitchLeft_Pin, RelayON);
    delay(SWITCH_TIME);
    digitalWrite(SwitchLeft_Pin, RelayOFF);
    Serial.println("  Turnout is moved to Left");
    // Включение питания петли
    delay(RELAY_DELAY);
    digitalWrite(Power1_Pin, RelayON);
    Serial.println("  Loop power is ON");
    TurnOutPosition = 1;
  }
}

От теории к практике

Home railway model - 56