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, ...)
daavii
Příspěvky: 20
Registrován: 22 kvě 2023, 11:41
Reputation: 0

Modelová železnice

Příspěvek od daavii » 23 kvě 2023, 16:53

Dobrý den, a děkuji předem. V 50 letech jsem se rozhodl že zkusím svět Arduina. S vnoučaty stavíme modelovou železnici a zkouším lehce z automatizovat zastavení ve stanici. Něco jsem sesmolil co mi vyhovuje ale má to ale, je tam jedem delay který by brzdil prog. ale nejsem schopen se ho zbavit. Funguje to následně: vlak přijede do zastávky na přerušenou kolej bez napětí - zastaví a sepnete infračidlo, časuje se 5 sec. a sepne rele a led, po 2 sec. potřebných pro odjezd vlaku je rele a led zase OFF. Stačí mi ukázat co a kde do kódu přidat, zbytek zvládnu snad ale věřím si. Zobrazený sketch mi dělá co potřebuji. Prolezl jsem to hodně a nic co by mě přivedlo k úspěchu jsem nenašel, všude samé blikání. Díky za pomoc.

Kód: Vybrat vše

const byte IR1 = 2; //infrared sensor
//const byte IR2 = 5;
const byte led1 = 3; // led stavu koleje
//const byte led2 = 6//;
const byte rele1 = 4;
//const byte rele2 = 7;
unsigned long startMillis; 
unsigned long currentMillis; 
unsigned long period2 = 5000;  //kdyz IR HIGH tak ceka led 5 sec. nez HIGH
unsigned long period1 = 2000; // led bude HIGH 2sec.,IR bude i HIGH i LOW, nez odjede vlak


void setup()
{
   Serial.begin(9600);  
  pinMode(led1, OUTPUT);
  pinMode(IR1,INPUT);
  pinMode(rele1,OUTPUT);
}

void loop(){

int IR1Value = digitalRead(IR1);
 Serial.println(IR1);

if (IR1Value==HIGH) {
  digitalWrite(led1, LOW);
  digitalWrite(rele1, HIGH);
  startMillis = millis(); 
  startMillis = currentMillis;
 
 }
  
 currentMillis = millis(); 
  
  if (currentMillis - startMillis >= period2)

  {
    digitalWrite(led1, HIGH);
    digitalWrite(rele1, LOW); 
  }

{
  delay (2000); // s timto delay to funguje jak potrebuji, ale nechci to tak,  
}
  
}

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

Re: Modelová železnice

Příspěvek od kiRRow » 23 kvě 2023, 18:04

Kód: Vybrat vše

if (IR1Value==HIGH) {
  digitalWrite(led1, LOW);
  digitalWrite(rele1, HIGH);
  startMillis = millis(); 
  startMillis = currentMillis; // <--- zde, omylem si tu přepíšeš startMillis
 
 }
ono to spíš bylo myšleno nějak takhle původně

Kód: Vybrat vše

void loop(){

  int IR1Value = digitalRead(IR1);
  Serial.println(IR1);
  currentMillis = millis(); // tady si zjistím aktuální čas
  
  if (IR1Value==HIGH) {
    digitalWrite(led1, LOW);
    digitalWrite(rele1, HIGH);
    startMillis = currentMillis; // tady akutální čas zjištěný na začátku loopu uložím
  }

  if (currentMillis - startMillis >= period2) { // 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
    digitalWrite(led1, HIGH);
    digitalWrite(rele1, LOW); 
  }

}

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

Re: Modelová železnice

Příspěvek od kiRRow » 23 kvě 2023, 18:20

Akorát následně vznikne problém v tom, že když ten vlak bude v cílové stanici stát v tom senzoru, tak se bude neustále přepisovat startMillis a nikdy nebude ten rozdíl mezi currentMillis a startMillis větší než perioda ... buď tam ten vlak nebude stát a nebo si přidáš ještě jednu proměnnou typu bool, kde si zapamatuješ, že čas příjezdu byl poznamenán a není třeba ho aktualizovat, po odjezdu tuto proměnnou zase smažeš.

Kód: Vybrat vše

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

void loop(){

  int IR1Value = digitalRead(IR1);
  Serial.println(IR1);
  currentMillis = millis(); // tady si zjistím aktuální čas
  
  if (IR1Value==HIGH) { // něco se děje na senzoru
  if (vlak == false) {  // nepamatuji si že by tam kdy byl vlak, sepnu relé a diodu
    digitalWrite(led1, LOW);
    digitalWrite(rele1, HIGH);
    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 >= period2) { // 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, tak vlak odjel
    digitalWrite(led1, HIGH);
    digitalWrite(rele1, LOW); 
    vlak = false; // zapomenu na vlak
  }

}

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

Re: Modelová železnice

Příspěvek od daavii » 23 kvě 2023, 18:31

Děkuji za odpověď, ani sem netušil, že je tam chyba, ale odčasování 5sec.fungovalo dle mých představ, ale řeším ty 2 sec (period1) viz. popis jak to má fungovat. Asi takto: na koleji zastaví vlak, sepne IR, zapne časování 5 sec. sepne relé, vlak jede ALE potřebuji aby to sepnutí trvalo 2-3sec. bez IR HIGH, protože vlak má mezery a když je přerušená kolej delší tak tak neodjede. Mezera vypne rele.

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

Re: Modelová železnice

Příspěvek od kiRRow » 23 kvě 2023, 18:48

Přiznávám, že se trošku ztrácím v zadání ...

Kód: Vybrat vše

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

void loop(){

  int IR1Value = digitalRead(IR1);
  Serial.println(IR1);
  currentMillis = millis(); // tady si zjistím aktuální čas
  
  if (IR1Value==HIGH) { // něco se děje na senzoru
  if (vlak == false) {  // nepamatuji si že by tam kdy byl vlak, sepnu relé a diodu
    digitalWrite(led1, LOW);
    digitalWrite(rele1, HIGH);
    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 >= period1) { // 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 period1
    // zde provést za dvě vteřiny
    digitalWrite(led1, HIGH); // ledka off
    digitalWrite(rele1, LOW);  // relé off
  }

  if (currentMillis - startMillis >= period2) { // 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, tak vlak odjel
    // tady jsou věci co se provádí za pět vteřin
    vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
  }

}
Nebo jako ten vlak tam má přijet, 5vteřin stát a pak se na dvě vteřiny zapne led a relé ?

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

Re: Modelová železnice

Příspěvek od daavii » 23 kvě 2023, 19:02

Přesně tak!. Vlak přijede do stanice, zastaví na 5s. a pak odjede. a na odjezd potřebuje čas 2-3 sec, v průběhu odjezdu mezery vypnou relé a to je ta chyba kterou řeším tím delay a to nechci. Ty 2 sec. jsou jakoby přidržení sepnutého relé na jakémkoliv stavu IR.

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

Re: Modelová železnice

Příspěvek od kiRRow » 23 kvě 2023, 19:03

i když dávalo by to smysl, že .... vlak přijede ... 5s počká a pak se mu pustí napájení na 2s, aby odjel

Kód: Vybrat vše

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

void loop(){

  int IR1Value = digitalRead(IR1);
  Serial.println(IR1);
  currentMillis = millis(); // tady si zjistím aktuální čas
  
  if (IR1Value==HIGH) { // něco se děje na senzoru
    if (vlak == false) {  // nepamatuji si že by tam kdy byl vlak, sepnu relé a diodu
      digitalWrite(led1, LOW);
      digitalWrite(rele1, HIGH);
      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 >= period2) { // 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
    digitalWrite(led1, LOW); // zapnout ledku
    digitalWrite(rele1, HIGH); // zapnout relé
  }

  if (currentMillis - startMillis >= period1 + period2) { // 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 - 2s na odjezd + 5s stání
    digitalWrite(led1, HIGH); // vypnout ledku
    digitalWrite(rele1, LOW); // vypnout relé
    vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
  }

}

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

Re: Modelová železnice

Příspěvek od kiRRow » 23 kvě 2023, 19:06

Pozor, udělal jsem chybu : zapoměl jsem zrušit zapnutí relé a diody v dění se něco na senzoru ...
Oprava :

Kód: Vybrat vše

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

void loop(){

  int IR1Value = digitalRead(IR1);
  Serial.println(IR1);
  currentMillis = millis(); // tady si zjistím aktuální čas
  
  if (IR1Value==HIGH) { // 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 >= period2) { // 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
    digitalWrite(led1, LOW); // zapnout ledku
    digitalWrite(rele1, HIGH); // zapnout relé
  }

  if (currentMillis - startMillis >= period1 + period2) { // 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 - 2s na odjezd + 5s stání
    digitalWrite(led1, HIGH); // vypnout ledku
    digitalWrite(rele1, LOW); // vypnout relé
    vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
  }

}

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

Re: Modelová železnice

Příspěvek od daavii » 23 kvě 2023, 19:11

Děkuji, vyzkouším, nic se testovat nebude a v provozu to nebude déle jak 1-2hod. Kdyby něco nebylo dle mých představ tak se ozvu. Ještě jednou Díky jdu testovat.

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

Re: Modelová železnice

Příspěvek od kiRRow » 23 kvě 2023, 19:15

A další chyba :D :D - je potřena ještě otestovat, jestli tam ten vlak vůbec je .... protože když se to spustí, začnou se počítat currentMillis, ale dokud tam ten vlak nenajede, tak bude startMillis 0 ... a pak projde podmínka že currentMillis - startMillis ...

Kód: Vybrat vše

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

void loop(){

  int IR1Value = digitalRead(IR1);
  Serial.println(IR1);
  currentMillis = millis(); // tady si zjistím aktuální čas
  
  if (IR1Value==HIGH) { // 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 >= period2) { // 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 ten vůbec vlak
      digitalWrite(led1, LOW); // zapnout ledku
      digitalWrite(rele1, HIGH); // zapnout relé
    }
  }

  if (currentMillis - startMillis >= period1 + period2) { // 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 - 2s na odjezd + 5s stání
    if(vlak){ // je tam ten vůbec vlak
      digitalWrite(led1, HIGH); // vypnout ledku
      digitalWrite(rele1, LOW); // vypnout relé
      vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
    }
  }

}

Odpovědět

Kdo je online

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