← Modellezési projektek

VIDRA MŰHELY / MODELLVASÚT

Ha jön a vonat,
a fények szólnak.

Útátjáró fényjelző Arduino Unóval

Két Viessmann 9059 MÁV fénysorompó, közös ütemben. A lézeres fénykapu automatikusan érzékeli a kitakarást, egyetlen nyomógombbal pedig átvehető a vezérlés.

Arduino UnoViessmann 9059 · H0Automata + kézi üzem

A közösen megépített, kipróbált összeállítás dokumentációja

ÉLŐ ELŐNÉZETAUTOMATA
LÉZER BELDR
SZABAD · fehér villogás
Kitakarva < 400Megvilágítva ≥ 400

Hosszú nyomás: kézi üzem. Kéziben rövid nyomás: szabad / tilos.

Böngészős szemléltetés, nem kapcsolódik az Arduinóhoz.

01 / AUTOMATA VAGY KÉZI

Egy gomb. Két üzemmód.

Bekapcsolás után automata üzem indul. Az üzemmódváltás a legalább 2 másodpercig tartott gomb felengedésekor történik.

AUTOMATA / D13 = LOW

A fénykapu figyel

A lézer világít az LDR-re. Ha az A1-en mért érték 400 alá esik, a két piros fény váltakozik. 400-tól felfelé a fehér villog. A 400-as küszöb a saját összeállításban, gyakorlati próbával vált be.

  • Lézer: bekapcsolva
  • Érzékelő: aktív
  • Az Uno beépített L LED-je: kikapcsolva
  • Rövid gombnyomás: nincs hatása
KÉZI / D13 = HIGH

Te választod a jelzést

Az LDR értékét a program figyelmen kívül hagyja, a lézer kikapcsol. Egy rövid gombnyomás a fehér villogás és a váltakozó piros között kapcsol. Újabb hosszú nyomás visszaadja a vezérlést az érzékelőnek.

  • Lézer: kikapcsolva
  • Érzékelő: figyelmen kívül hagyva
  • Az Uno beépített L LED-je: világít
  • Rövid gombnyomás: szabad ↔ tilos

Két jelző, egy ütem

Mindkét jelző ugyanazokat az állapotokat kapja. A fehér be/ki váltás és a pirosak közötti váltás egyaránt 750 ms-os időközhöz kötött.

Kitakarásra reagál

Az eredeti kód a fénykapu pillanatnyi állapotát követi. Nincs vonatszámlálás vagy külön, a teljes áthaladás végéig tartó foglaltsági tárolás.

Egyszerű Arduino-program

A villogást millis() időzítés végzi. A kód az Uno alapfunkcióit használja, külön telepítendő könyvtár nélkül.

02 / A TEREPASZTAL ALATT

Néhány alkatrészből működő átjáró.

Viessmann 9059 MÁV fénysorompópár eredeti csomagolásában, vezérlőelektronika nélkül.
Viessmann 9059 MÁV fénysorompó
Két jelző, három-három vezetékkel. A termékfotón dupla András-kereszt látható; a projekt jelzőin szimpla kereszt is használható.
Fotó és termékazonosítás: vasutmodell.com ↗
Kétvezetékes hengeres lézermodul, piros pozitív és kék negatív vezetékkel.
Kétvezetékes, 5 V-os lézermodul
A felhasznált típushoz hasonló kivitel. A fotó nem bizonyítja a saját modul pontos típusát vagy áramfelvételét.
Fotó: BerryBase LDI-650 ↗
Arduino Uno R32 × Viessmann 9059 jelző5 V-os kétvezetékes lézermodulLDR fényellenállás1 kΩ ellenállásZáró nyomógombUSB-kábel + vezetékek

03 / PONTOSAN A KÓD SZERINT

Hat vezeték a jelzőknek.
Két bemenet a vezérlésnek.

A rajz a csatolt program lábkiosztását és a saját, korábban kimért jelzők háromvezetékes vezérlését mutatja. Ez a közös projekt bekötése; nem a Viessmann gyári kapcsolási rajza.

Arduino Uno: D2, D3, D4 az első jelző sárga, piros, fehér vezetékére; D8, D9, D10 a második jelzőre. Lézer piros az 5V-ra, kék a D13-ra. A0 nyomógombon át GND-re. 5V–LDR–A1–1kΩ–GND feszültségosztó.
Csatlakozási táblázat
Uno lábCsatlakozás
D2 / D3 / D41. jelző: sárga / piros / fehér vezeték
D8 / D9 / D102. jelző: sárga / piros / fehér vezeték
A0Záró nyomógomb egyik érintkezője; másik GND
A1LDR és 1 kΩ közös pontja
5VLDR másik lába és lézer piros (+) vezetéke
GND1 kΩ másik lába és nyomógomb
D13Lézer kék (−) vezetéke; egyben üzemmódjelzés

A közvetlen meghajtás feltétele

A rajz a működő összeállítás közvetlen meghajtását dokumentálja. Az Uno I/O lábainak gyártói terhelési értéke 20 mA: a D13-on a teljes lézeráram folyik, ezért utánépítéskor a tényleges modul áramát ellenőrizni kell. Az azonos külsejű modulok terhelése eltérhet; nagyobb áramhoz külön meghajtófokozat szükséges. A jelzők áramkorlátozó alkatrészeit tartsd meg. A lézersugár útját az LDR-nél zárd le, és ne irányítsd szemre.

Arduino Uno gyári lábkiosztás és terhelhetőség ↗

A háromvezetékes jelző működési táblázata

A sárga, piros és fehér a vezetékek színe. A sárga vezetékhez nem tartozik sárga jelzőlámpa. A két pirosat az egymáshoz képesti polaritás választja ki.

JelzésSárga vezetékPiros vezetékFehér vezeték
FehérINPUTHIGHLOW
Jobb pirosHIGHLOWINPUT
Bal pirosLOWHIGHINPUT
Minden sötétOUTPUT LOWOUTPUT LOWOUTPUT LOW

Aktív jelzésnél a nem használt vezetéket a kód INPUT módba teszi, hogy ne gyulladjon fel másik LED is. Ne kösd egyik jelzővezetéket sem állandó 5 V-ra vagy GND-re. A saját példányokon ezt a kiosztást mérés és működési próba támasztotta alá; a háromvezetékes belső hálózathoz gyári rajzot nem sikerült azonosítani.

Fényérzékelő: miért ez az osztóirány?

5 V → LDR → A1 → 1 kΩ → GND. Megvilágítva az LDR ellenállása kisebb, ezért A1 feszültsége magasabb. Kitakaráskor az ellenállás nő és az A1-en olvasott érték csökken. Ez illeszkedik a program tilos = (feny < 400) feltételéhez. A 400 pontosan már szabad állapotot ad.

A kód nem tartalmaz hiszterézist vagy külön analóg szűrést. Az érzékelőt rögzítsd, árnyékold a környezeti fénytől, és a saját környezetben ellenőrizd a két mért tartományt.

04 / ELSŐ PRÓBA

Előbb fények. Utána áthaladás.

  1. Töltsd fel az eredeti programot

    Arduino IDE: Arduino AVR Boards → Arduino Uno. A ZIP-ben a mappa és az .ino fájl neve megegyezik. Nincs külön könyvtárigény. A soros monitor sebessége 9600 baud.

  2. Állítsd be a fénykaput

    A lézer az LDR közepére világítson. Az AUTO feny= sorban látszik az A1 értéke. Szabad sugárnál legyen legalább 400, kitakarva 400 alatti. Az érzékelőt az útátjáróhoz úgy helyezd el, hogy a kívánt áthaladás szakítsa meg a fénysugarat.

  3. Ellenőrizd az automata üzemet

    Szabad sugárnál fehér villogás, kitakarva váltakozó piros látszik mindkét jelzőn. A lézer világít, a beépített L LED sötét.

  4. Vedd át kézzel

    Az A0–GND nyomógombot legalább 2 másodpercig tartsd lenyomva, majd engedd fel. Az L LED világít, a lézer elalszik. Rövid nyomásokkal váltogasd a jelzést; a kitakarás ekkor nem avatkozik be. Újabb hosszú nyomás és felengedés visszaállítja az automata üzemet.

05 / A MEGÉPÍTÉSHEZ

A kipróbált kód, eltéve.

A kapott fájlt változatlanul őriztük meg. Az útmutató és a rajz ezt a programváltozatot követi, 400-as érzékelési küszöbbel.

ARDUINO / FORRÁSKÓD

utatjaro_jelzo.ino

A két jelző szinkron vezérlése, automata és kézi üzemmel, D13 üzemmódkimenettel. Az eredeti melléklettel bájtra azonos.

Forráskód · .ino ↓
ARDUINO IDE / ZIP

Feltöltésre előkészítve

A program az Arduino IDE által elvárt, azonos nevű mappában, rövid feltöltési útmutatóval.

Arduino sketch · ZIP ↓
TELJES PROJEKT / ZIP

Kód + rajz + útmutató

Eredeti firmware, SVG- és PNG-bekötés, csatlakozási táblázat, üzemmódok, fotók és forrásjegyzék.

Projektcsomag ↓
Az eredeti Arduino-kód megtekintése

Ez a letölthető .ino tartalma; megjelenítéskor a sortöréseket a böngészőhöz igazítjuk.

// ======================================================================
//   Két Viessmann 3 LED-es fénysorompó szinkron vezérlése
//
//   AUTOMATA ÜZEM: LDR + lézer alapján működik
//   KÉZI ÜZEM: gomb rövid nyomása -> szabad/tílos váltás
//   2 mp hosszú nyomás -> automata <-> kézi váltás
//
//   LED logika: harmadik láb mindig INPUT, így nem világít össze semmi
//   GOMB: A0 (INPUT_PULLUP) -> LOW = nyomva, HIGH = nincs nyomva
//   MODE kijelző: D13 (LOW=automata, HIGH=kézi)
// ======================================================================


// -------------------
//  JELZŐ 1 lábai
// -------------------
const int S1_SARGA = 2;
const int S1_PIROS = 3;
const int S1_FEHER = 4;

// -------------------
//  JELZŐ 2 lábai
// -------------------
const int S2_SARGA = 8;
const int S2_PIROS = 9;
const int S2_FEHER = 10;

// -------------------
//  Bemenetek
// -------------------
const int LDR_PIN    = A1;   // automata fénykapu
const int BUTTON_PIN = A0;   // gomb (INPUT_PULLUP)
const int MODE_PIN   = 13;   // visszajelző LED (automat/kezi)

// -------------------
//  Állapotváltozók
// -------------------
unsigned long lastToggle = 0;
bool feherState = false;
bool pirosState = false;

unsigned long buttonPressStart = 0;
bool lastButton = HIGH;

bool manualMode = false;     // false = automata, true = kézi
bool manualTilos = false;    // kézi módban aktív jelzés


// ======================================================================
//  Inicializálás
// ======================================================================
void setup() {
  Serial.begin(9600);

  pinMode(S1_SARGA, OUTPUT);
  pinMode(S1_PIROS, OUTPUT);
  pinMode(S1_FEHER, OUTPUT);

  pinMode(S2_SARGA, OUTPUT);
  pinMode(S2_PIROS, OUTPUT);
  pinMode(S2_FEHER, OUTPUT);

  pinMode(LDR_PIN, INPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  pinMode(MODE_PIN, OUTPUT);   // manuális/automata jelzés

  allOff();
}


// ======================================================================
//  Fő loop
// ======================================================================
void loop() {

  // -------------------------------------
  // 1) GOMB KEZELÉSE (INPUT_PULLUP)
  // -------------------------------------
  bool btn = digitalRead(BUTTON_PIN);

  // Lenyomás (LOW)
  if (btn == LOW && lastButton == HIGH) {
    buttonPressStart = millis();
  }

  // Felengedés (HIGH)
  if (btn == HIGH && lastButton == LOW) {
    unsigned long pressTime = millis() - buttonPressStart;

    if (pressTime >= 2000) {
      // hosszú nyomás -> üzemmód váltás
      manualMode = !manualMode;
      Serial.print("MOD VALTAS: ");
      Serial.println(manualMode ? "KEZI" : "AUTOMATA");
    } else {
      // rövid nyomás -> csak kézi módban érvényes
      if (manualMode) {
        manualTilos = !manualTilos;
        Serial.print("KEZI VALTAS: ");
        Serial.println(manualTilos ? "TILOS" : "SZABAD");
      }
    }
  }

  lastButton = btn;


  // -------------------------------------
  // 2) MODE visszajelző (D13)
  // -------------------------------------
  digitalWrite(MODE_PIN, manualMode ? HIGH : LOW);


  // -------------------------------------
  // 3) AUTOMATA / KÉZI ÜZEM LOGIKA
  // -------------------------------------
  bool tilos = false;

  if (!manualMode) {
    // AUTOMATA: LDR vezérlés
    int feny = analogRead(LDR_PIN);
    tilos = (feny < 400);   // határérték
    Serial.print("AUTO feny=");
    Serial.print(feny);
    Serial.print("  tilos=");
    Serial.println(tilos);
  } 
  else {
    // KÉZI: LDR-t ignoráljuk
    tilos = manualTilos;
    Serial.print("KEZI tilos=");
    Serial.println(tilos);
  }


  // -------------------------------------
  // 4) JELZÉS VEZÉRLÉS
  // -------------------------------------
  if (!tilos) {
    feherVillog();
  } else {
    pirosValtakozik();
  }
}



// ======================================================================
//  LED VEZÉRLÉS
// ======================================================================

void allOff() {
  pinMode(S1_SARGA, OUTPUT); digitalWrite(S1_SARGA, LOW);
  pinMode(S1_PIROS, OUTPUT); digitalWrite(S1_PIROS, LOW);
  pinMode(S1_FEHER, OUTPUT); digitalWrite(S1_FEHER, LOW);

  pinMode(S2_SARGA, OUTPUT); digitalWrite(S2_SARGA, LOW);
  pinMode(S2_PIROS, OUTPUT); digitalWrite(S2_PIROS, LOW);
  pinMode(S2_FEHER, OUTPUT); digitalWrite(S2_FEHER, LOW);
}


// FEHÉR: piros HIGH, fehér LOW, sárga INPUT
void feherOn() {
  pinMode(S1_SARGA, INPUT);
  pinMode(S1_PIROS, OUTPUT); digitalWrite(S1_PIROS, HIGH);
  pinMode(S1_FEHER, OUTPUT); digitalWrite(S1_FEHER, LOW);

  pinMode(S2_SARGA, INPUT);
  pinMode(S2_PIROS, OUTPUT); digitalWrite(S2_PIROS, HIGH);
  pinMode(S2_FEHER, OUTPUT); digitalWrite(S2_FEHER, LOW);
}


// JOBB PIROS: sárga HIGH, piros LOW
void jobbPirosOn() {
  pinMode(S1_FEHER, INPUT);
  pinMode(S1_SARGA, OUTPUT); digitalWrite(S1_SARGA, HIGH);
  pinMode(S1_PIROS, OUTPUT); digitalWrite(S1_PIROS, LOW);

  pinMode(S2_FEHER, INPUT);
  pinMode(S2_SARGA, OUTPUT); digitalWrite(S2_SARGA, HIGH);
  pinMode(S2_PIROS, OUTPUT); digitalWrite(S2_PIROS, LOW);
}


// BAL PIROS: sárga LOW, piros HIGH
void balPirosOn() {
  pinMode(S1_FEHER, INPUT);
  pinMode(S1_SARGA, OUTPUT); digitalWrite(S1_SARGA, LOW);
  pinMode(S1_PIROS, OUTPUT); digitalWrite(S1_PIROS, HIGH);

  pinMode(S2_FEHER, INPUT);
  pinMode(S2_SARGA, OUTPUT); digitalWrite(S2_SARGA, LOW);
  pinMode(S2_PIROS, OUTPUT); digitalWrite(S2_PIROS, HIGH);
}


// ======================================================================
//  VILLOGÁS – SZABAD
// ======================================================================
void feherVillog() {
  if (millis() - lastToggle > 750) {
    lastToggle = millis();
    feherState = !feherState;
    if (feherState) feherOn();
    else allOff();
  }
}


// ======================================================================
//  VILLOGÁS – TILOS
// ======================================================================
void pirosValtakozik() {
  if (millis() - lastToggle > 750) {
    lastToggle = millis();
    pirosState = !pirosState;
    if (pirosState) jobbPirosOn();
    else balPirosOn();
  }
}

A bemutató a csatolt programra, a korábbi közös építésnél rögzített mérésekre és a jelenlegi bekötési pontosításokra épül. A 400-as küszöb gyakorlati eredmény. A termékfotók forrásait az alkatrészeknél feltüntettük; a lézer képe kivitelpélda. Új hardveres próbát itt nem végeztünk.

← További modellezési projektek