• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Sterowanie semaforem kolejowym
#1
Witam
Na bazie ARDUINO NANO chcę zrealizować sterowanie semaforem 4 komorowym (diody LED) na makietę kolejową. Wykorzystując komendę „while” „napisałem” prosty program, ale mam pewien problem. O ile w przypadku definiowania 2 sygnałów za pomocą 2 przycisków (wejść) wszystko jest OK., to w przypadku wprowadzeniu 3 sygnału i 3 wejścia muszę załączać je po kolei tak jak zdefiniowałem je w programie i nie mogę przełączyć się z np. sygnału 2 na sygnał 1 lub z 1 na 3 i z powrotem na 1, tylko muszę wybierać je po kolei (1,2,3) aby powrócić do stanu „początkowego” jakim jest sygnał S1 stój czyli „czerwone”.
Będę wdzięczny za podpowiedź innego rozwiązania umożliwiającego swobodne przełączanie sygnałów.
Dziękuję.
 
Odpowiedź
#2
Wróżbitów tu nie ma. Pokaż program i schemat.
 
Odpowiedź
#3
   
Witam
Poniżej listing programu i schemat

void setup()
{
  pinMode(9, OUTPUT); //Dioda czerwona jako wyjście
  pinMode(10, OUTPUT); //Dioda zielona jako wyjście
  pinMode(11, OUTPUT); //Dioda zółta jako wyjście
  pinMode(12, OUTPUT); //Dioda biała jako wyjście
  pinMode(2, INPUT_PULLUP); //Przycisk jako wejście-sygnał S1
  pinMode(5, INPUT_PULLUP); //Przycisk jako wejście-sygnał S10
  pinMode(7, INPUT_PULLUP); //Przycisk jako wejście-sygnał Ms2
  digitalWrite(9, LOW); //Stan początkowy-sygnał S1
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
  digitalWrite(12, HIGH);
}
 
void loop()
{


while (digitalRead(2) == HIGH) {} //Jeśli przycisk wciśnięty-sygnał S1
    digitalWrite(9, LOW); //Włącz diodę czerwoną
    digitalWrite(10, HIGH); //Włącz diodę zieloną
    digitalWrite(11, HIGH);//Wyłącz diodę żółtą
    digitalWrite(12, HIGH);//Wyłącz diodę białą

  while (digitalRead(5) == HIGH) {} //Jeśli przycisk wciśnięty-sygnał S10
    digitalWrite(9, HIGH); //Wyłącz diodę czerwoną
    digitalWrite(10, LOW); //Włącz diodę zieloną
    digitalWrite(11, LOW);//Włącz diodę żółtą
    digitalWrite(12, HIGH);//Wyłącz diodę białą
 
 while (digitalRead(7) == HIGH) {} //Jeśli przycisk wciśnięty-sygnał Ms2
    digitalWrite(9, HIGH); //Wyłącz diodę czerwoną
    digitalWrite(10, HIGH); //Wyłącz diodę zieloną
    digitalWrite(11, HIGH);//Wyłącz diodę żółtą
    digitalWrite(12, LOW);//Włącz diodę białą
}
 
Odpowiedź
#4
Rezystor do led jest jeden, to oznacza, że nie da się wyświetlić wszystkich sygnałów na sygnalizatorze, bo niektóre wymagają świecenia kilku komór.
Nie likwidujesz drżenia styków, to poważny błąd! Prędzej czy później takie rozwiązanie będzie powodowało dziwne zachowania programu.

Przejdźmy do sedna problemu. Po resecie, program wpada w pętlę
Kod:
while (digitalRead(2) == HIGH) {}
Siedzi tam tak długo dopóki nie naciśniesz przycisku podłączonego do wejścia D2, gdy to zrobisz, wyświetli S1 po czym wpada w kolejna pętlę
Kod:
while (digitalRead(5) == HIGH) {}
i siedzi w niej, tak długo dopóki D5 nie przyjmie poziomu niskiego, wtedy wyświetla S10 itd.

Domyślam się, ze nie znasz C czy C++ ani innego języka wysokiego poziomu. Metodą prób ii błędów, bez zrozumienia "while" użyłeś go i działa jak każesz. Powinieneś użyć "if".
 
Odpowiedź
#5
Dzięki za odpowiedź.
To prawda-nie znam języków programowania (no może jakieś totalne podstawy Wink)

Odnośnie rezystora-wyświetlam wszystkie sygnały (S10 to pomarańczowe i zielone jednocześnie) z tym,że występuje opisany wcześniej problem.
Odnośnie pull-up/down - jestem świadomy tematu Smile.

Po "wyrzuceniu"pętli" wyświetlam tylko 2 sygnały:S1 i S10.
Jak poprawnie zastosować komendę "if"?
Czy konieczne jest wykluczenie "else"?
 
Odpowiedź
#6
(19-11-2018, 15:27)lighter1@wp.pl napisał(a): Jak poprawnie zastosować komendę "if"?
Czy konieczne jest wykluczenie "else"?
Klauzula sumienia, nie pozwala mi na pisanie za kogoś kodu.

Odpowiedzi na swoje pytania znajdziesz w książkach "Programowanie w C" itp  (jest kilka darmowych), kursach (także darmowych), można też użyć Google.

Nie da się pisać programów bez znajomości języka programowania. Czy byłbyś w stanie nauczyć kogoś pisania wierszy gdy ten nie zna alfabetu? Jeśli potrafisz, to ja napiszę kod, którego potrzebujesz.
 
Odpowiedź
#7
Nie oczekuję"napisania za mnie"programu,chdziło mi tylko o jakąś podpowiedź.
Ale i tak dziękuję za odpowiedź.
Będę radził sobie jakoś samemu.
Pozdrawiam
 
Odpowiedź
#8
(19-11-2018, 18:26)lighter1@wp.pl napisał(a): Nie oczekuję"napisania za mnie"programu,chdziło mi tylko o jakąś podpowiedź.
Podpowiedź, proszę bardzo, pierwsze "z brzegu" z Google: http://cpp0x.pl/kursy/Kurs-C++/Poziom-1/...if-else/16
Do tego naprawdę nie potrzeba forum, wystarczy książka. Załączyłem trzy darmowe.

.pdf   _C.pdf (Rozmiar: 1.45 MB / Pobrań: 5)
.pdf   _C Programowanie w jezyku C.pdf (Rozmiar: 979.17 KB / Pobrań: 5)
.pdf   _C prof_mikolajczak_c.pdf (Rozmiar: 3.01 MB / Pobrań: 5)


PS
Za moich czasów takich luksusów nie było. Za książką trzeba było jechać 100km i więcej. Jedną z pozycji kupiłem po blisko 10 latach poszukiwań.
 
Odpowiedź
#9
Do przycisków zainstaluj sobie bibliotekę bounce2 https://github.com/thomasfredericks/Bounce2 , w przykładach pokazane jest jak tego używać, podstaw możesz się nauczyć za darmo również tu: https://forbot.pl/blog/kursy
W tym kodzie wystarczy zamienić while na if, a przypisane do niej instrukcje wziąć wewnątrz klamry {} i jako tako to zadziała, ale nic więcej w tej dziedzinie nie osiągniesz nie mając ochoty na naukę:
Kod:
void setup()
{
 pinMode(9, OUTPUT); //Dioda czerwona jako wyjście
 pinMode(10, OUTPUT); //Dioda zielona jako wyjście
 pinMode(11, OUTPUT); //Dioda zółta jako wyjście
 pinMode(12, OUTPUT); //Dioda biała jako wyjście
 pinMode(2, INPUT_PULLUP); //Przycisk jako wejście-sygnał S1
 pinMode(5, INPUT_PULLUP); //Przycisk jako wejście-sygnał S10
 pinMode(7, INPUT_PULLUP); //Przycisk jako wejście-sygnał Ms2
 digitalWrite(9, LOW); //Stan początkowy-sygnał S1
 digitalWrite(10, HIGH);
 digitalWrite(11, HIGH);
 digitalWrite(12, HIGH);
}

void loop()
{


if(digitalRead(2) == LOW) { //Jeśli przycisk wciśnięty-sygnał S1
   digitalWrite(9, LOW); //Włącz diodę czerwoną
   digitalWrite(10, HIGH); //Włącz diodę zieloną
   digitalWrite(11, HIGH);//Wyłącz diodę żółtą
   digitalWrite(12, HIGH);//Wyłącz diodę białą
}
 if(digitalRead(5) == LOW) { //Jeśli przycisk wciśnięty-sygnał S10
   digitalWrite(9, HIGH); //Wyłącz diodę czerwoną
   digitalWrite(10, LOW); //Włącz diodę zieloną
   digitalWrite(11, LOW);//Włącz diodę żółtą
   digitalWrite(12, HIGH);//Wyłącz diodę białą
}
if(digitalRead(7) == LOW) { //Jeśli przycisk wciśnięty-sygnał Ms2
   digitalWrite(9, HIGH); //Wyłącz diodę czerwoną
   digitalWrite(10, HIGH); //Wyłącz diodę zieloną
   digitalWrite(11, HIGH);//Wyłącz diodę żółtą
   digitalWrite(12, LOW);//Włącz diodę białą
}
}
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#10
Witam po dłuższej przerwie

Dziękuję za cenne wskazówki, rady i porady.
Po zapoznaniu się z Waszymi wskazówkami, przeanalizowaniu kursu Arduino ze strony forbot.pl  i przełożeniu to na moje potrzeby sterowania semaforem udało mi się uruchomić sterowanie semaforem 4-ro komorowym Big GrinBig GrinBig Grin
Listing poniżej
void setup()
{
  pinMode(9, OUTPUT); //Dioda czerwona jako wyjście
  pinMode(10, OUTPUT); //Dioda zielona jako wyjście
  pinMode(11, OUTPUT); //Dioda zółta jako wyjście
  pinMode(12, OUTPUT); //Dioda biała jako wyjście
  pinMode(2, INPUT_PULLUP); //Przycisk jako wejście-sygnał S1
  pinMode(3, INPUT_PULLUP); //Przycisk jako wejście-sygnał S2
  pinMode(4, INPUT_PULLUP); //Przycisk jako wejście-sygnał S10
  pinMode(5, INPUT_PULLUP); //Przycisk jako wejście-sygnał Ms2
  digitalWrite(9, LOW); //Stan początkowy-sygnał S1
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
  digitalWrite(12, HIGH);
}
 
void loop()
{


while(digitalRead(2) == LOW) { //Jeśli przycisk wciśnięty-sygnał S1
    digitalWrite(9, LOW); //Włącz diodę czerwoną
    digitalWrite(10, HIGH); //Włącz diodę zieloną
    digitalWrite(11, HIGH);//Wyłącz diodę żółtą
    digitalWrite(12, HIGH);//Wyłącz diodę białą
}

 while(digitalRead(3) == LOW) { //Jeśli przycisk wciśnięty-sygnał S2
    digitalWrite(9, HIGH); //Włącz diodę czerwoną
    digitalWrite(10, LOW); //Wyłącz diodę zieloną
    digitalWrite(11, HIGH);//Wyłącz diodę żółtą
   
}
while(digitalRead(4) == LOW){  //Jeśli przycisk wciśnięty-sygnał S10
    digitalWrite(9, HIGH); //Wyłącz diodę czerwoną
    digitalWrite(10, LOW); //Włącz diodę zieloną
    digitalWrite(11, LOW);//Włącz diodę żółtą
    digitalWrite(12, HIGH);//Wyłącz diodę białą
}
while(digitalRead(5) == LOW){ //Jeśli przycisk wciśnięty-sygnał Ms2
    digitalWrite(9, HIGH); //Wyłącz diodę czerwoną
    digitalWrite(10, HIGH); //Wyłącz diodę zieloną
    digitalWrite(11, HIGH);//Wyłącz diodę żółtą
    digitalWrite(12, LOW);//Włącz diodę białą   
}
}

Teraz pracuję nad dodaniem do powyższego sygnału Sz[sygnał zastępczy] (LED czerwona ciągła + LED biała pulsująca.
Na chwilę obecną po poniższym zapisie:

while(digitalRead(5) == LOW){ //Jeśli przycisk wciśnięty-sygnał Sz
    digitalWrite(9, LOW); //Włącz diodę czerwoną
    digitalWrite(10, HIGH); //Wyłącz diodę zieloną
    digitalWrite(11, HIGH);//Wyłącz diodę żółtą
    digitalWrite(12, LOW);//Włącz diodę białą
    delay(500); //Opóźnienie
    digitalWrite(12,HIGH);//Włącz diodę białą
    delay(500); //Opóźnienie
}

sygnał Sz działa tylko przy przytrzymywaniu switch'a.
Pracuję dalej. Po ukończeniu z powodzeniem (brak konieczności podtrzymywania switch'a) pozwolę sobie dać info i listing.

Jeszcze raz dziękuję Wam za pomoc.
Pozdrawiam !
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości