Výtah se 3 podlažími

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
Odpovědět
Marty+-
Příspěvky: 35
Registrován: 12 pro 2018, 12:12
Reputation: 0

Re: Výtah se 3 podlažími

Příspěvek od Marty+- » 17 úno 2019, 12:23

Tento kod vypisuje patra a jedzími tak, že když držím jedno tlačítko jede dolů a druhý jede nahoru.

Kód: Vybrat vše

#include <Stepper.h>  
int tlacitko = 3; //Směr proti hod.ruč.
int tlacitko2 = 2;  //Směr hod.ručiček
int tlacitko3 = 5; // tlacitko to už je přidný jako 3 patro zatím nic nedělá
int kroky = 50;      //Kroky ke každému stisknutí tlačítka  
int cteni = 0;      //Uloží hodnotu čtení tlačítka po směru hod.ruč.
int cteni2 = 0;   //Uloží hodnotu čtení tlačítka proti směru hodinových ručiček 
int digitalpin1 = 7; //sensor pin
int digitalpin2 = 6;
int digitalpin3 = 5;
// navody.arduino-shop.cbool aktualniPatro;
int stav = 0;
int stop;
// knihovny pro LCD přes I2C
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// nastavení adresy I2C (0x27 v mém případě),
// a dále počtu znaků a řádků LCD, zde 20x4
LiquidCrystal_I2C lcd(0x27, 20, 4);

const int stepsPerRevolution = 500;   
Stepper myStepper(stepsPerRevolution, 8,10,9,11);        
   
void setup()   
{  
  pinMode(tlacitko, INPUT);  
  pinMode(tlacitko2, INPUT); 
  pinMode(tlacitko3, INPUT);  
  pinMode(digitalpin1, INPUT); 
  pinMode(digitalpin2, INPUT);
  pinMode(digitalpin3, INPUT);
  myStepper.setSpeed(60); 
  lcd.begin();
}  
   
void loop()  
{         
  if(digitalRead(digitalpin1)){    //zde se čtou hodnoty ze senzorů
    stav = 1 ;}
    
  if(digitalRead(digitalpin2)){
    stav = 2;}
    
  if(digitalRead(digitalpin3)){
    stav = 3;}

//směr proti hod.ruc.
  cteni = digitalRead(tlacitko);   
  if (cteni != 0)
  {
    myStepper.step(-kroky);   
  }  

  //směr hod.ruč.
  cteni2 = digitalRead(tlacitko2);  
  if (cteni2 != 0)  
  {  
    myStepper.step(kroky);   
  }
     
 lcd.setCursor(0,0); // vypisuje patra na lcd display
lcd.print("jak je ");
lcd.print(stav); 

}

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: Výtah se 3 podlažími

Příspěvek od petan » 17 úno 2019, 13:34

Netestoval jsem to...

Kód: Vybrat vše

#include <Stepper.h>  
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

//tlačítka pater
int PINbtn1 = 3;
int PINbtn2 = 2;
int PINbtn3 = 5;
bool btn1, btn2, btn3;

//snímače pater
int PINsensPatro1 = 7;
int PINsensPatro2 = 6;
int PINsensPatro3 = 5;
bool sensPatro1, sensPatro2, sensPatro3;

//nastavení motoru
const int stepsPerRevolution = 500;   
Stepper myStepper(stepsPerRevolution, 8,10,9,11);    

//displej
LiquidCrystal_I2C lcd(0x27, 20, 4);

//proměnné k logice programu
int pozadovanePatro;
int aktualniPatro; 

    
   
void setup(){  
  //tlačítka
  pinMode(PINbtn1, INPUT);  
  pinMode(PINbtn2, INPUT); 
  pinMode(PINbtn3, INPUT); 

   //senzory
  pinMode(PINsensPatro1, INPUT); 
  pinMode(PINsensPatro2, INPUT);
  pinMode(PINsensPatro3, INPUT);

  //nastavení motoru
  myStepper.setSpeed(60);

   //nastavení displeje
  lcd.begin();
  lcd.setCursor(0,0);
  lcd.print("Nauc se to!!");
  
  delay(1000); //čekání po inicializaci
  lcd.print("              ");
}  
   
void loop(){
  //načtení tlačítek do proměnných       
  btn1 = digitalRead(PINbtn1);
  btn2 = digitalRead(PINbtn2);
  btn3 = digitalRead(PINbtn3);

  if(btn1){
    pozadovanePatro = 1;
  }

  if(btn2){
    pozadovanePatro = 2;
  }

  if(btn3){
    pozadovanePatro = 3;
  }

  //načtení aktuálního patra
  sensPatro1 = digitalRead(PINsensPatro1);
  sensPatro2 = digitalRead(PINsensPatro2);
  sensPatro3 = digitalRead(PINsensPatro3);

  if(sensPatro1){
    aktualniPatro = 1;
  }

  if(sensPatro2){
    aktualniPatro = 2;
  }

  if(sensPatro3){
    aktualniPatro = 3;
  }

  if(aktualniPatro < pozadovanePatro){
    //výtak je níž, musí jet nahoru
    myStepper.step(50); 
  }

  if(aktualniPatro > pozadovanePatro){
    //výtak je výš, musí jet dolu
    myStepper.step(-50); 
  }

  
  //výpis aktuálního patra
  lcd.setCursor(0,0); // vypisuje patra na lcd display
  lcd.print("patro: ");
  lcd.print(aktualniPatro); 

}

Marty+-
Příspěvky: 35
Registrován: 12 pro 2018, 12:12
Reputation: 0

Re: Výtah se 3 podlažími

Příspěvek od Marty+- » 17 úno 2019, 16:32

Jediné 1 patro nefunguje. Ostatní funguje.

Marty+-
Příspěvky: 35
Registrován: 12 pro 2018, 12:12
Reputation: 0

Re: Výtah se 3 podlažími

Příspěvek od Marty+- » 17 úno 2019, 16:53

Už nic. Už je to dobrý.

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: Výtah se 3 podlažími

Příspěvek od petan » 17 úno 2019, 20:14

A čím to bylo?
Řekni mi, proč tohle utrpení trvalo přes dva měsíce a stejně si to nedal do kupy? :lol:

Marty+-
Příspěvky: 35
Registrován: 12 pro 2018, 12:12
Reputation: 0

Re: Výtah se 3 podlažími

Příspěvek od Marty+- » 17 úno 2019, 21:40

Jen špatně daný odpor.

Hafajs
Příspěvky: 151
Registrován: 10 bře 2019, 10:19
Reputation: 0

Re: Výtah se 3 podlažími

Příspěvek od Hafajs » 17 bře 2019, 22:27

petan píše:
25 pro 2018, 13:39
No, konečně nějakej kód... Jako, nejlepší ověření je zkusit si ten program nahrát do Arduina. Když máš HW, tak to můžeš rovnou odzkoušet. Ale jak to vypadá, tak sis nezkusil program ani přeložit! Tak do psích náušnic, trošku se do toho taky zapoj...

Kde jsou definovaný proměnný "btn1", atd.? Nemá tam spíš být btnPatro, nebo tak něco?

Kód: Vybrat vše

pinMode(btn1,INPUT);
pinMode(btn2,INPUT);
pinMode(btn3,INPUT);

buttonState = digitalRead(btn1);
buttonState2 = digitalRead(btn2);
buttonState3 = digitalRead(btn3);
V Setupu bude lepší, když si pinMode dáš všechny pod sebe. Program pak bude přehlednější. Takhle nastavuješ výstupy, pak něco mezi tím, pak zas vstupy... Chyba to není, ale je to přehlednější.

Do proměnné buttonState ukládáš digitální stav vstupu. Je to proměnná jenom true/false. Nemusíš tedy používat typ proměnné int, ale bool. Sice to s int taky funguje, ale je to špatný přístup. Ušetří se tím taky paměť - bool zabírá polovinu paměti int.
Pokud použijet bool proměnnou v konstrukci if..., můžeš to napsat takhle: if(proměnná){. Pokud je proměnná true, tak se automaticky podmínka provede, pokud false, tak se neprovede. Je to takovej čistší způsob. Pokud by si chtěl nahradit if(proměnná == false){, můžeš to napsat takto: if(!proměnná){. Vykřičník neguje proměnnou.

LOW == false; HIGH == true. Je to jenom jiné pojmenování. Doporučuji používat true/false.

Co má podle tebe dělat tento řádek? zobrazuje(cislo(i)); a řádek show(numbers(i));?
Funkci zobrazuje a shownemáš nikde definovanou. Proměnnou cislo taky ne. Navíc, když to napíšeš takhle, tak proměnná cislo musí být pole. To mi vůbec nedává smysl...

Ve funkci nahoru() a dolu() máš použitou konstrukci for(int b=0; b<700; b++){. Proměnná b (případně a) je v tomto případě deklarovaná jenom uvnitř smyčky. Můžeš tedy pokaždé použít stejný název proměnné. Pokud je smyčka pouze jedna, je taková zvyklost jako název proměnné použít název i. To sice nemá na funkčnost vliv, ale líp to vypadá :)
Uvnitř máš čekání pomocí delay 12ms. Pokud spustíš jednu z těchto funkcí, tak program "zamrzne" na 8,4s. Sice to možná přejede mezi patry, ale když máš čidla, tak tohle kurva vůbec nemusíš použít. Stačí hlídat, jestli je výtah v požadovaném patře a pokud ne, tak sepnout motor na jeden směr. Koukni se, co jsem psal předtím. Tam jsou ty podmínky udělaný. Úplně ten cyklus smaž a hlídej to snímačem!

To je co, jsem zahlídl jen tak letmým pohledem... K samotnému programu.

Představ si, že budeš mít výtah s 30, nebo 60 patry. To budeš do nekonečna pro každé patro a každou pozici výtahu definovat část kódu? Celou tvoji logiku programu můžeš nahradit tím, co jsem ti předtím psal. Doporučuju ti se vyvarovat zejména konstrukci while. Jednat v tomhle případě je zbytečná a to tě tak zacyklí, že pokud nevíš, jak program jede, tak se do toho pěkně zamotáš. Teď není nic, co by nešlo udělat bez IF...

Představ si, že je výtah třeba v 1. patře (podle proměnné, kterou sis definoval hned na začátku programu tam i je). Stiskneš tlačítko pro jízdu do 3. patra. proměnná i (mimochodem zcela nelogicky pojmenovaná) je menší než 3, takže se provede podmínka. Pak se provede podmínka while. Odečte (!) se proměnná i (nyní 0) a výtah jede dolu. Má vůbec kam? Bacha, aby se neproboural do sklepa! Tam jede už zmíněných 8,4s. Pak to na displej vypíše text (toto by šlo vypíchnout do sólo funkce) a vrátí se to zpět na řádek while... Podmínka je stále splněna, protože odečítáš, takže se ti program zacyklí a výtah dojede tak leda do Číny.

Kód: Vybrat vše

if(buttonState3==HIGH){
  
    if(i<3){
      while(i<3) {
      i--;
      dolu();
    Serial.print("jsi na");
    Serial.print(i);
    Serial.println("patro");
   //zobrazuje(cislo[i]);
      }
    }
    
  i=3; //hodnota vytahu 3
     //zobrazuje(cislo[i]);    
  }
  
Jasný, u jiných tlačítek se to chová trochu jinak, protože podmínky nejsou zcela totožný.Ale to budeš pro každý patro vymejšlet samostatnou konstrukci? vzpomeň si na těch 30 pater... Z tohohle pohledu ANO, program lze tak napsat (po pár úpravách by to i jakštakš fungovalo), ale v žádném případě tohle NENÍ dobrá cesta.

Ještě jednou se koukni na můj předchozí kód. Připoj do Arduina ty 3 snímače pater co jsi zde psal na začátku. Ty budou říkat ve kterým poschodí se reálně výtah nachází. Pak si pomocí tlačítek do nějaké proměnné nastavíš do jakého patra chceš jet. A pak jednoduchou podmínkou (viz ten kód) rozhodneš, jestli má jet výtah nahoru, nebo dolu, nebo stát. Nemusíš hlídat žádný počet cyklů, žádný čas. Jednom porovnáváš reálné proměnné. Sám HW výtahu ti řekne, kdy přesně je ve správném patře. Toto lze pak naaplikovat třeba na 100 pater a program se ti zvětší jenom o přiřazení aktuálního patra do proměnné. Logika bude stále na pár řádků.
Moc hezky a inspirativni. Diky ;)

Odpovědět

Kdo je online

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