Skocz do zawartości

Dwa przyciski i dwa wyjścia?


Pomocna odpowiedź

Napisano

Witam,
jako że dopiero zaczynam swoją przygodę z arduino, chciałbym prosić doświadczonych kolegów o pomoc.

Chciał bym zrobić coś takiego

1. Jeśli zostanie wciśnięty "PRZYCISK1" (nie ważne jak długo) to na wyjściu "LED1" ma pojawić się sygnał na 2 sekundy,

2. a stan "PRZYCISK2" się nie zmieni przez 5 sekund od naciśnięcia "PRZYCISK1" to na wyjściu "LED2" ma pojawić się sygnał na 2 sekundy.

Jak stan "PRZYCISK2" się nie zmieni przez 5 sekund od naciśnięcia "PRZYCISK1" to nie rób nic.

3. Jeśli zostanie wciśnięty "PRZYCISK2" (nie ważne jak długo) to na wyjściu "LED2" ma pojawić się sygnał na 2 sekundy.

Przerobiłem na swoje potrzeby kod znaleziony w internecie,

punkt 1 i 3 działa ale z 2 mam problem bo nie wiem jak to zrobić.

long cm;
long pm,pm_1;
long licznik;
byte start;
int stat,start_1;
byte czas_oczekiwania = 5;

long cm1;
long pm1,pm_11;
long licznik1;
byte start1;
int stat1,start_11;
byte czas_oczekiwania1 = 5;

#define LED1 5
#define LED2 6
#define PRZYCISK1 12
#define PRZYCISK2 13

void setup() {
 Serial.begin(9600);
pinMode(LED1, OUTPUT );
pinMode(LED2, OUTPUT );
pinMode(PRZYCISK1, INPUT_PULLUP);
pinMode(PRZYCISK2, INPUT_PULLUP);
}

void loop() {

cm = millis()/100;

if ( digitalRead(PRZYCISK1) == HIGH )stat = 0;

if ( digitalRead(PRZYCISK1) == LOW and stat == 0 )
   {start ++;stat = 1;pm = cm;}

if ( start >= 1 ){
 if ((cm - pm) == 1){licznik ++;pm = cm;}}

if ( licznik > czas_oczekiwania and digitalRead(LED1) == 0 )
   {licznik = 0;start = 0;}

if ( start >= 1 )
   {digitalWrite(LED1,HIGH);}

if ( digitalRead(LED1) == HIGH ){
 licznik = 0;start = 0;
 if ((cm - pm_1) > 0){start_1 ++;pm_1 = cm;}
 if ( start_1 > 10 ){digitalWrite(LED1,LOW);start_1 = 0;}}


cm1 = millis()/100;

if ( digitalRead(PRZYCISK2) == HIGH )stat1 = 0;

if ( digitalRead(PRZYCISK2) == LOW and stat1 == 0 )
   {start1 ++;stat1 = 1;pm1 = cm1;}

if ( start1 >= 1 ){
 if ((cm1 - pm1) == 1){licznik1 ++;pm1 = cm1;}}

if ( licznik1 > czas_oczekiwania1 and digitalRead(PRZYCISK2) == 0 )
   {licznik1 = 0;start1 = 0;}

if ( start1 >= 1 )
   {digitalWrite(LED2,HIGH);}

if ( digitalRead(LED2) == HIGH ){
 licznik1 = 0;start1 = 0;
 if ((cm1 - pm_11) > 0){start_11 ++;pm_11 = cm1;}
 if ( start_11 > 10 ){digitalWrite(LED2,LOW);start_11 = 0;}
 }
}

"Chciał bym zrobić coś takiego"

Dlaczego? Możesz nam wytłumaczyć co będziesz tym sterował? Tak z ciekawości pytam, bo dziwnie to wygląda jak na zachciankę mrugającą diodkami. A jeśli jest w tym jakiś głębszy zamysł (i nie jest to tekst pracy domowej - one potrafią być tak głupie) to chętnie bym usłyszał co zamiast diodek podłączysz.

EDIT: Kolejne dziwne sterowanie z przyciskami w ciągu krótkiego czasu:

https://www.forbot.pl/forum/topics74/zlozony-problem-z-przyciskami-vt15183.htm#123880

Może warto wreszcie o automatach jakiś artykuł napisać, bo ludzie brną w jakieś piętrowe if-y i padają jak muchy... A może moda na rakiety jakaś nastała?

Chciałbym zrobić zamek na kod, ale że nie mam jeszcze wszystkich gadżetów to ćwiczę na przyciskach. Myślę że ostatecznie PRZYCISK2 zastąpię kontaktronem a 1 płytką z przyciskami.

I tak:

po przyciśnięciu przycisku1 "rygiel" się otwiera, po przyciśnięciu przycisku2 (zmiana stanu kontaktronu)się zamyka.

Problem pojawia się gdy przycisnę przycisk1 a nie otworzę drzwi (są cały czas otwarte).

Dlatego wykombinowałem że po 5 sekundach od otwarcia rygla a nie otwarciu drzwi rygiel automatycznie się zamknął.

I na tym utknąłem, jest jakiś nieskomplikowany sposób żeby to zrobić?

OK, może właśnie najlepiej zacząć tworzenie takich rzeczy od wyobrażenia sobie jak to ma działać docelowo. Jeśli zaczniesz tworzyć kod który tylko częściowo (i trochę na siłę) działa, to potem jego rozbudowa może być tak samo trudna jak napisanie tego od nowa. Szkoda roboty.

Gdybyś miał opisać założenia tego swojego zamka w wersji "All inclusive", to odpowiedz na kilka pytań:

1. Dziesięć (?) przycisków kodowych. Może mniej? Może tylko kilka za to sekwencja kodowa dłuższa? Może wystarczą np. cztery kolory lub symbole lub litery? A może dłuższe i krótsze naciśnięcia jednego przycisku? Masz jakiś fajny pomysł? A może tani czytnik zbliżeniowych kart/breloczków podłączony kilkoma drutami do Arduino? Może odbiornik podczerwieni plus pilot od telewizora (lub inny nadajnik IR) wysyłający kody cyfr/przycisków?

https://botland.com.pl/piloty/8232-pilot-ir-nec-38khz-21-klawiszy.html

https://botland.com.pl/klawiatury/1681-klawiatura-membranowa-numeryczna-12-klawiszy.html

https://botland.com.pl/rfid/6765-modul-rfid-mf-rc522-1356mhz-spi-karta-i-brelok.htm

2. Czy zamek ma się otwierać bezpośrednio po wprowadzeniu poprawnego kodu, czy ma być jakiś przycisk OK/Enter/Open itp, który powoduje analizę wpisanego kodu i otwarcie (lub nie) zamka?

3. Czy jakaś zwłoka, czas martwy po wpisaniu złego kodu? To przydaje się gdy sekwencja jest krótka, żeby nie można było szybko "przelecieć" wszystkich kombinacji.

4. Drzwi mają czujnik otwarcia? I to jest ten kontaktron? Jeśli nie otworzysz ich po wprowadzeniu kodu, system automatycznie się uzbraja po kilku sekundach. Czy ma to samo robić po zamknięciu drzwi?

5. Z czego to będzie zasilane? Jeśli z baterii, to nie może brać dużo prądu w czasie czuwania, nie może świecić żadnymi diodkami (np. Gotowość) w tym czasie itp. Trzeba przewidzieć możliwość wymiany baterii zamka bez otwierania sejfu. A jeśli z sieci, to podtrzymanie bateryjne?

1. Myślę że klawiatura membranowa będzie wystarczająca. Aktywnych przycisków może być 4 i #

2. Zamek ma się otwierać po wprowadzeniu poprawnego kodu i przyciśnięciu #

3. Czasu pomiędzy próbami nie potrzebuje

4. Myślę, że kontaktron będzie najprostszym rozwiązaniem, po otwarciu zmieni się jego stan jak i po zamknięciu co zamykało by zamek. Po wprowadzeniu kodu i nie otwarciu drzwi powiedzmy po 5 sek zamek się zamyka.

5. O tym jeszcze nie myślałem, chwilowo chciałbym użyć jako zamka silnika krokowego.

Dobra, to teraz wyobrażaj sobie jak to działa. Podchodzisz do klawiatury i naciskasz jakieś przyciski. Nie wiesz ile wciśnięć zarejestrowało urządzenie. Nic się nie dzieje więc próbujesz, znów ale teraz jeszcze bardziej nie masz pojęcia w jakim stanie jest program. Czy ostatnie 4 wciśnięcia to były 4 z nowej serii, czy może poprzednio zadziałały tylko 3 klawisze więc pierwszy z nowej serii był naprawdę ostatnim z poprzedniej?

Musisz mieć jakąś sygnalizację stanu. Po pierwsze przydałyby się bipnięcia po każdym przycisku, to daje człowiekowi odczucie, że urządzenie "żyje". Po drugie, przydałaby się dioda, która np. normalnie nie świeci (z założenia oszczędzamy prąd), a po wykryciu pierwszego przycisku z sekwencji zapala się i gaśnie po wprowadzeniu ostatniego przycisku kodu. Gaśnie też np. po 10 sekundach gdy ktoś wprowadzi za krótką sekwencję i/lub odejdzie od klawiatury. Wtedy zawsze podchodząc do zamka wiesz, że nieświecenie diody oznacza gotowość do wprowadzenia pierwszego kodu sekwencji.

Po wprowadzeniu poprawnego kodu powinna zapalać się inna, sygnalizująca otwieranie zamka. Mając silnik krokowy musisz mieć też czujnik stanu rygla. Z tymi silnikami jest różnie i jeśli Twoja mechanika będzie ułomna, może dochodzić do oporów i gubienia kroków. Wtedy nie wiesz ile kroków generować, bo nie znasz pozycji rygla. Dlatego przydałyby się dwa czujniki krańcowe sygnalizujące procesorowi, że rygiel jest całkowicie otwarty i całkowicie zamknięty - to są tanie rzeczy, np. hallotrony, optyczne czujniki odbiciowe lub w ostateczności zwykłe przełączniki naciskane ryglem. Wtedy funkcja komutująca silnik obraca nim aż do napotkania jednej lub drugiej krańcówki - w zależności od kierunku ruchu. To też pozwala sygnalizować błędy, np. alarm od zacięcia rygla. Przemyśl to.

Czy przewidujesz jakieś możliwości zmiany hasła bez przeprogramowywania procesora? Jeśli tak, to też trzeba przewidzieć do tego przyciski (np. gwiazdka czy coś takiego) działająca tylko po podaniu poprawnego klucza i wprowadzająca program w tryb "serwisowy". To może być też nienormalnie długie naciśnięcie # lub wszystkich 4 klawiszy kodowych jednocześnie itp.

Co o tym myślisz? Warto takie rzeczy zaplanować wcześniej, później jest dużo łatwiej i cel jest jasny.

Myślę że moja dotychczasowa wiedza nie pozwala jeszcze na takie fantazje 🙂

choć to bardzo trafne spostrzeżenia. Z biegiem czasu projekt będzie można rozwijać o dodatkowe funkcje.

Moim zdaniem powinienem zacząć od prostych rzeczy a dopiero z czasem i zdobytą wiedzą przechodzić do bardziej złożonych.

Mógłbyś podpowiedzieć jak rozwiązać problem z 1 postu, jakiej funkcji mógłbym użyć?

E tam, nie cackaj się ze sobą. Przecież nikt nie ma pojęcia w tej chwili - ja również - jak program do Twojego zamka miałby docelowo wyglądać. Duże rzeczy robi się małymi kroczkami. Zaczniesz od najprostszych rzeczy i będziesz go rozbudowywał rozumiejąc jak działa wszystko co poprzednio zrobiłeś. Ważne, by zachować jakąś hierarchię, czystość i separację zadań. Inaczej, wrzucając wszystko do jednego wielkiego worka zawsze skończysz jak teraz. To tego właśnie masz się nauczyć robiąc taki projekt - jak sobie radzić z rzeczami, których nie oganiasz już na starcie i co robić, by utrzymać nieuchronnie postępującą komplikację w ryzach.

Jeśli już teraz nie wiesz jak rozepchnąć swój poprzedni kod, to jesteś w czarnej dziurze na samym początku. A gdzie jeszcze silnik krokowy, obsługa kodów itd.. Przyznam, że nawet nie chce mi się analizować tej plątaniny i nawet jeśli coś tam jeszcze wściubisz, to za miesiąc nie będziesz wstanie zmienić/poprawić/dopisać ani literki. Tak się programów nie pisze, przykro mi a brnąc dalej na siłę, nauczysz się tylko tego, że programowanie to generalnie wredna i makabrycznie skomplikowana pisanina. Nie musi tak być, ale to zależy od Ciebie.

Z ciekawości poczekam czy znajdzie się ktoś na Forum, by pomóc Ci rozwinąć Twój program tak jak sobie to wymarzyłeś. I czy będziesz później w stanie dalej samodzielnie go popychać.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...