Modelová železnice

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Uživatelský avatar
kiRRow
Příspěvky: 1208
Registrován: 07 kvě 2019, 07:03
Bydliště: Opava

Re: Modelová železnice

Příspěvek od kiRRow » 25 kvě 2023, 15:47

Pokud se zvažuje více vlakových zastávek a nějaké automatické složitější řízení tratě, bez použití objektového stylu programování v tom programu bude hrozný zmatek. Vzniknou mnohokrát okopírované bloky programu s přečíslovanýma proměnnýma, každou změnu budeš muset opravovat na x řádcích kódu.

Další věc je to, že ty bloky nemůžou být pohromadě v tom programu co se týče jako že tenhle kus programu mi kompletně obsluhuje tuhle výhybku, za ním je kus programu co obsluhuje tamto nádraží, tenhle kus programu za ním zase támhle ten snímač. Blokem se myslí, že nejprve program načte hodnoty všech snímačů, výhybek, nádraží... pak vypočte co chce jak a kde nastaví a v posledním bloku provede to co si vypočetl.

V Objektově Orientovaném Programování je to pojato tak, že ty navrhneš třídu Nadrazi. Této třídě pak přiřadíš různé vlastnosti jako je pinSenzoru, pinRelatka,pinLed, casCekani, casNaOdjezd. A potom podle této třídy jednoduše naklonuješ pět dalších nádraží, ale ne kopírováním ctrl + c, ale pomocí jediného řádku v programu. Vznikne objekt jmenoNadrazi, který bude mít a umět všechno co umí Nadrazi.

V praxi asi jako bys měl učit pět elektrikářů jednoho po druhém a nebo to naučíš celou třídu a pak si jich pět vybereš .... a nebo klidně 20.

daavii
Příspěvky: 20
Registrován: 22 kvě 2023, 11:41

Re: Modelová železnice

Příspěvek od daavii » 25 kvě 2023, 20:14

Jj, už jsem na to taky přišel, že to funguje jen na jednu kolej, vyhýbky neřeším, řeším jen 5 zastávek. Sám to nevyřeším, leda 5x arduino :D

daavii
Příspěvky: 20
Registrován: 22 kvě 2023, 11:41

Re: Modelová železnice

Příspěvek od daavii » 26 kvě 2023, 07:03

Díky za pochvalu, mám to jako léčebnou kůru na zimní měsíce proti depresi, nesnáším zimu :D .

ondraN
Příspěvky: 935
Registrován: 08 srp 2019, 20:01

Re: Modelová železnice

Příspěvek od ondraN » 26 kvě 2023, 07:47

daavii píše:
25 kvě 2023, 20:14
...... leda 5x arduino :D
I to je řešení :mrgreen:
Často i lepší než tahat mraky dlohých drátů z jednoho centra.

Uživatelský avatar
kiRRow
Příspěvky: 1208
Registrován: 07 kvě 2019, 07:03
Bydliště: Opava

Re: Modelová železnice

Příspěvek od kiRRow » 26 kvě 2023, 16:05

daavii píše:
25 kvě 2023, 20:14
Jj, už jsem na to taky přišel, že to funguje jen na jednu kolej, vyhýbky neřeším, řeším jen 5 zastávek. Sám to nevyřeším, leda 5x arduino :D
Pošli sem prosím poslední verzi funkčního programu.

daavii
Příspěvky: 20
Registrován: 22 kvě 2023, 11:41

Re: Modelová železnice

Příspěvek od daavii » 26 kvě 2023, 18:15

Kód: Vybrat vše

//Funguje SUPER zpozdeni ve stanici


int IR1 = A1; //infrared sensor kolej1
//int IR2 = A2; //infrared sensor kolej2
const byte led1 = 3; // led stavu koleje 1
//const byte led2 = 6;// led stavu koleje 2
int rele1 = 4; // rele koleje 1
//int  rele2 = 7; // rele koleje 2

unsigned long startMillis; 
unsigned long currentMillis; 
unsigned long zpozdeni1 = 6000;  //cas zastaveni vlaku led OFF
unsigned long odjezd1 = 3000; // cas pro odjezd vlaku, led ON

boolean vlak = false; // vlak není ve stanici

void setup()
{
  Serial.begin (9600);
  pinMode(led1, OUTPUT);
  pinMode(IR1,INPUT);
  pinMode(rele1,OUTPUT);
  digitalWrite(rele1, HIGH);// vychozi stav rele, dle typu spinani 
}

void loop(){

int IR1Value = digitalRead(IR1); 
 Serial.println(IR1Value);
  currentMillis = millis(); // tady si zjistím aktuální čas
  
  if (IR1Value==LOW) { // něco se děje na senzoru
    if (vlak == false) {  // nepamatuji si že by tam kdy byl vlak - nespínám relé a diodu, chci si jen pamatovat čas a že vlak přijel - sepnu to později
      startMillis = currentMillis; // tady akutální čas zjištěný na začátku loopu uložím
      vlak = true; // zapamatuji si že tam je vlak
    }
  }
 
  if (currentMillis - startMillis >= zpozdeni1) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven period2 - tzn stojí tu pět vteřin
    if(vlak){ // je tam vůbec vlak
      digitalWrite(led1, HIGH); // zapnout ledku
      digitalWrite(rele1, LOW); // zapnout relé
    }
  }

  if (currentMillis - startMillis >= odjezd1 + zpozdeni1) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven oboum periodám, tak vlak odjel - 3s na odjezd + 6s stání
    if(vlak){ // je tam vůbec vlak
      digitalWrite(led1, LOW); // vypnout ledku
      digitalWrite(rele1, HIGH); // vypnout relé
      vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
    }
  
  
  }
delay (500);

}

daavii
Příspěvky: 20
Registrován: 22 kvě 2023, 11:41

Re: Modelová železnice

Příspěvek od daavii » 31 kvě 2023, 17:37

Po veliké spolupráci s kiRRowem vystavuji kód pro zastavení a odjezd vlaku z X (zde 4) nádraží. Lze ním lehce nastavit rozdílné časy zpoždění vlaku a ošetřuje i délku sepnutí relé pro přerušenou kolej dle potřeby pro odjezd tj. délky přerušené koleje. Lze i jednoduše dopsat ovládání návěstidel.

Kód: Vybrat vše

/*
Zastavení vlaku ve stanici na zvolenou dobu a nastaveni odjezdu vlaku dle delky prerusene koleje.

Toto je třída Nadrazi
Tato třída má vždy všechny tyhle všobecné atributy
*/
class Nadrazi{ // třída nádraží vlastní tyto atributy
  private: // privátní část třídy, zde může zapisovat pouze ona třída, nikdo jiný
    int IR;   //proměnná pro pin infrasenzoru
    int led;  //proměnná pro pin indikační ledky
    int rele;  //proměnná pro pin relátka
    //int jevlak; // proměnná pro LCD je vlak "!"
    unsigned long zpozdeni;  // cas zastaveni vlaku led OFF
    unsigned long odjezd; // cas pro odjezd vlaku, led ON  
    
    unsigned long startMillis;  // čas příjezdu vlaku
    unsigned long currentMillis; // čas posledního updatu
    int IRValue; // místo kde si uložím senzor
    
    boolean vlak; // zapamatování si vlaku ve stanici

 
  public: // veřejná část, k této může přistupovat kdokoliv
/*konstruktor - ekvivalent toho co je v setupu
Tohle je nutná součást třídy - slouží k tomu, aby se dle této třídy zkonstruoval objekt, musí se jmenovat stejně jako třída
a program ji zavolá vždy, když bude vytvářet nové nádraží - potřebuje znát pin senzoru, ledky, relé, a časy na zpoždění a odjezd
*/
    Nadrazi(int pinIR, int pinLed, int pinRele, unsigned long zpozdeniVlaku, unsigned long odjezdVlaku) {
      IR = pinIR; // nastavím si do proměnné IRpin
      led = pinLed; // nastavím si ledPin
      rele = pinRele; // nastavím si relePin
      
      pinMode(IR, INPUT); // IR je vstup
      pinMode(led, OUTPUT); // led je vystup
      pinMode(rele,OUTPUT); // rele je vystup
      digitalWrite(rele, HIGH);// vychozi stav rele, dle typu spinani
      
      zpozdeni = zpozdeniVlaku; // jak dlouho ma vlak stat
      odjezd = odjezdVlaku; // jak dlouho odjizdi
      vlak = false; // indikace vlaku ve stanici
      
    }
/*metody - zatím je jen jedna
Každé nádraží, se kdykoliv je to možno může updatovat, načíst si stav čidel, vypočíst časy a dle toho poslat vlak
*/
   void Update(){
      IRValue = digitalRead(IR);  // načti stav svého senzoru
      currentMillis = millis(); // tady si zjistím aktuální čas
    
      if (IRValue == LOW) { // něco se děje na senzoru
        if (vlak == false) {  // nepamatuji si že by tam kdy byl vlak - nespínám relé a diodu, chci si jen pamatovat čas a že vlak přijel - sepnu to později
          startMillis = currentMillis; // tady akutální čas zjištěný na začátku loopu uložím
          vlak = true; // zapamatuji si že tam je vlak
        //digitalWrite(led, HIGH); // kdyz vjede vlak do stanice zapne led
        
        }
      }
     
      if (currentMillis - startMillis >= zpozdeni) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven period2 - tzn stojí tu pět vteřin
        if(vlak){ // je tam vůbec vlak
          digitalWrite(led, HIGH); // zapnout ledku, tato LED se rozviti při odjezdu vlaku, pokud chces aby se sigalizoval i vjezd-odkomentuj na radku. 53
          digitalWrite(rele, LOW); // zapnout relé

        }
      }
    
      if (currentMillis - startMillis >= odjezd + zpozdeni) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven oboum periodám, tak vlak odjel - 3s na odjezd + 6s stání
        if(vlak){ // je tam vůbec vlak
          digitalWrite(led, LOW); // vypnout ledku
          digitalWrite(rele, HIGH); // vypnout relé
          vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
        }
      }
    }
};

/*a teď to kouzlo*/
// pin Senzoru, pinLedky, PinRele, CasCekani, CasNaOdjezd
Nadrazi staniceOpava(A0,2,3,6000,3000); // vytvoření objektu staniceOpava dle návrhu třídy Nadrazi
Nadrazi stanicePraha(A1,4,5,7000,3000); // vytvoření objektu stanicePraha dle návrhu třídy Nadrazi
Nadrazi staniceLipnik(A2,6,7,8000,3000); // vytvoření objektu staniceLipnik dle návrhu třídy Nadrazi
Nadrazi staniceOstrava(A3,8,9,5000,3000); // vytvoření objektu staniceOstrava dle návrhu třídy Nadrazi
//Nadrazi staniceXyz(A4,10,11,10000,3500); // vytvoření objektu staniceXyz dle návrhu třídy Nadrazi

void setup() {

}

void loop() {
  staniceOpava.Update();
  stanicePraha.Update();
  staniceLipnik.Update();
  staniceOstrava.Update(); 
  //staniceXyz.Update(); // dalsi stanice dle libosti
}

Uživatelský avatar
kiRRow
Příspěvky: 1208
Registrován: 07 kvě 2019, 07:03
Bydliště: Opava

Re: Modelová železnice

Příspěvek od kiRRow » 04 čer 2023, 12:27

A jakpak bojuješ s tím displejem ? :)

daavii
Příspěvky: 20
Registrován: 22 kvě 2023, 11:41

Re: Modelová železnice

Příspěvek od daavii » 08 čer 2023, 06:31

Zatím jsem se k tomu nedostal a stále čekám až dorazí větší LCD.

Uživatelský avatar
kiRRow
Příspěvky: 1208
Registrován: 07 kvě 2019, 07:03
Bydliště: Opava

Re: Modelová železnice

Příspěvek od kiRRow » 08 čer 2023, 17:32

No koukal jsem, že je tam řádek //int jevlak; // proměnná pro LCD je vlak "!"
Není nutné vytvářet novou proměnnou, protože to jestli je vlak ve stanici je už uloženo boolean vlak; // zapamatování si vlaku ve stanici ...
Druhá věc je ta, že ani k jedné proměnné se nebudeš moct dostat ani ke čtení ani k zápisu od nikud jinud než z class Nadrazi{ ... }; cokoliv je mimo ty složené uvozovky nesmí pracovat s tím co je označeno jako private: ... to jsou soukromé (systémové) data objektu a nikdo jiný k nim nesmí mít přístup.
A jak na to ?
1) Přesunout boolean vlak; // zapamatování si vlaku ve stanici pod řádek public: // veřejná část, k této může přistupovat kdokoliv
Tím se ti zpřístupní proměnná vlak ... jeOpavaVlak = staniceOpava.vlak;
Je to risk v tom, že to bude fungovat i naopak staniceOpava.vlak = true; tohle prostě nakecá stanici že tam je vlak a může to udělat bugr...

a nebo druhé řešení

2) Vytvořit metodu getVlak ... ta bude součástí objektu a může tedy přistoupit k privátní proměnné vlak a sdělit ji komukoliv kdo se zeptá bez jakéhokoliv rizika, že to někdo omylem přepíše. jeOpavaVlak = staniceOpava.getVlak();
Metoda getVlak bude vypadat takto a bude v public části třídy

Kód: Vybrat vše

	boolean getVlak(){
		return vlak;
	}

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 1 host