Witam.
Na wstępie chciałbym się ze wszystkimi przywitać, bo jestem tu nowym użytkownikiem. Nie posiadam talentu do pisania artykułów także z góry przepraszam jeśli czegoś nie zrozumiecie, pytajcie w komentarzach.
W mojej głowie zrodził się pomysł na wykonanie panelu sterowania otwieraniem uliczki, oraz otwieraniem/zamykaniem/zatrzymaniem bramy wjazdowej.
obsługa tych czynności powinna być chroniona hasłem, w moim przypadku jest to 5 prawie dowolnych znaków z 16 (pomijając *, spełnia ona inne istotne zadanie, ale o tym później).
Tak więc do wykonania swojego projektu zaprzągłem:
-klonu Arduino Mini Pro 5v 16Mhz,
-klawiaturę 4×4,
-dwa moduły przekaźnika,
-buzzer,
-1 diodę (moja jest akurat czerwona),
-1 rezystor 560Ohm (taki akurat miałem pod ręką) podłączony w szeregu z diodą.
Tak wygląda układ po zmontowaniu
Pin P1 jest pinem wspólnym do sterowania bramy, po zwarciu któregoś z pinów od 2 do 4 następuje reakcja.
Dla P2 jest to otwieranie, P3 zamykanie, P4 zatrzymanie ruchu bramy
Piny te są podłączone do odpowiednich wyprowadzeń które posiada mój napęd do bramy.
Natomiast na pin P6 podane jest 12V+, które po załączeniu przekaźnika jest przekazywane na pin P5 i następuje otwarcie elektrycznego rygla furtki.
Buzzer sygnalizuje naciśnięcie przycisku oraz poprawność lub nie wpisanego szyfru, natomiast dioda zapala się po wpisaniu poprawnego szyfru i sygnalizuje dostęp do sterowania ww. urządzeniami, które odbywa się poprzez przyciśnięcie któregoś z przycisków, ja wykorzystałem A-otwarcie furtki, B-otwarcie bramy, C-zamknięcie bramy, D-zatrzymanie bramy.
Kod programu nie jest w pełni mojego autorstwa, oczywiście autor zezwolił na jego modyfikacje i publikację. Nieco go przerobiłem, i dodałem troszkę smaczków.
Program po uruchomieniu sprawdza czy w pamięci eeprom zapisany jest szyfr, jeśli go nie ma wywołuje funkcję która po wpisaniu szyfru zapisuje go w pamięci, dzięki czemu jest on nieulotny. Jeśli kod jest zapisany w pamięci to program przechodzi do funkcji która sczytuje wpisywany ciąg znaków, jeśli jest on identyczny jak ten w pamięci to zostaje wywołana funkcja umożliwiająca nam sterowanie pracą urządzeń, zapala się dioda podłączona do pinu nr 13, na czas około 30sekund, po tym czasie od nowa należy wprowadzić szyfr, a dioda oczywiście gaśnie. Jeśli wpisany kod jest kodem specjalnym (służącym do zmiany szyfru), funkcja wymazuje aktualny szyfr i wymaga wprowadzenia nowego szyfru.
Teraz czas na moje lekkie usprawnienia
- Na wprowadzenie szyfru składającego się z 5 znaków mamy około 15 sekund, od momentu wciśnięcia pierwszego klawisza. Po tym czasie, aktualnie wprowadzany szyfr zostanie wymazany, co zasygnalizuje dioda oraz buzzer, i należy go wprowadzić od nowa.
2.Jeśli się pomylimy podczas wprowadzania szyfru możemy wcisnąć magiczną gwiazdkę (tak to właśnie jej istotne zadanie), która wymazuje aktualnie wprowadzany szyfr i możemy go wprowadzić od nowa.
Te opcję dodałem po tym jak zamontowałem już całość w miejscu docelowym, z uwagi na to że użytkownicy inni niż ja mogli by mieć problem ze sterowaniem furtką, czy bramą.
Program bd, zapewne dalej przeze mnie modyfikowany i usprawniany, w przyszłości mam zamiar dołączyć automatyczne zapalanie lampek oświetlających drogę od furtki do domu po otwarciu furtki, jak i zapalanie oświetlenia we wjeździe po otwarciu bramy. Pewnie coś jeszcze wpadnie mi do głowy.
Teraz pora na kod, z programowaniem nie miałem żadnego problemu, składnia arduino bardzo mi odpowiada, po bojach z Bascomem i C dla AVR. Ten język który wydaje się być identyczny jak C++, jest tym czego szukałem.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 |
/* OPIS: ------------------------------------------------------------ - Klawiatura numeryczna 4X4 poĹ‚Ä…czona do pinĂłw 2-9 Arduino - Pin 10 do poĹ‚Ä…czenia BUZERA - Pin 13 kontrolka sygnalizujaca dostep - Pin A0 - wyjĹ›cie sterujÄ…ce zamkiem - Pin A1-A3 - wyjĹ›cie sterujÄ…ce zamkiem - szyfr 5-cio znakowy - zmiana szyfru po wpisaniu kombinacji: #123# ( lub innej dowolnej 5-cio znakowej - patrz w programie ) -do szyfru nie można użyć *, spełnia ona istotną funkcję w programie :P ---------------------------------------------------------- */ #include <Keypad.h> #include<EEPROM.h> // --- zmiennie ------------------------------------------ const byte wiersze= 4; //ilość wierszy const byte kolumny= 4; //ilość kolumn const float max_czas= 30*1000/30;//czas w sek*1000ms/30ms //czas odblokowania obsługi panelu const float max_czas_na_kod= 15*1000/30; //po przekroczeniu czasu zeruje wpisany szyfr //definicja klawiszy (identycznie jak na klawiaturze) char mapaklawiszy[wiersze][kolumny]= { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte wiersze_piny[wiersze] = {9,8,7,6}; // wiersze 0-3 byte kolumny_piny[kolumny]= {5,4,3,2}; // kolumny 0-3 int pamiec[5]; // pamiÄ™c wciĹ›niÄ™tych klawiszy - 5 znakĂłw volatile int szyfr=0; // szyfr=0 -> brak szyfr=1 jest aktywny volatile int l=0; // zmienna pomocnicza, licznik znakĂłw volatile int result=0; // rezultat porĂłwnania ciÄ…gu 5-ciu znakĂłw volatile int unlock=0;//blokada funkcji; volatile int czas_otwarcia=0; volatile int czas_na_kod=0; int mykey[5]; // tablica wciĹ›nietych znakĂłw Keypad myKeypad= Keypad(makeKeymap(mapaklawiszy), wiersze_piny, kolumny_piny, wiersze, kolumny); // definicja obiektu klasy Keypad // --- funkcje programu: --------------------------------- void warning_0() { digitalWrite(10,1);delay(600);digitalWrite(10,0);delay(30); warning_1(); } // bipper dla OK void warning_1() { digitalWrite(10,1);delay(30);digitalWrite(10,0);delay(30); } // bipper dla wrong code void odczyt_EEPROM() // funkcja sprawdza obecnoĹ›c szyfru w pamiÄ™ci EEPROM { for (int i=0;i<5;i++) {pamiec[i]=EEPROM.read(i);} if(pamiec[0]!=255 && pamiec[1]!=255 && pamiec[2]!=255 && pamiec[3]!=255 && pamiec[4]!=255) szyfr=1; else szyfr=0; // jeĹ›li jest KOD to szyfr =1 else szyfr =0 } void fnowy_kod() // funkcja ustawia nowÄ… kombinacjÄ™ dla szyfru { for(int i=0;i<5;i++)EEPROM.write(i,255); //kasowanie EEPROM //Wprowadz nowy KOD dostepu: while(l<5) { char keypressed = myKeypad.getKey(); if (keypressed != NO_KEY) { EEPROM.write(l,keypressed);l++; // zapis pojedynczego znaku warning_1(); // komunikacja po RS } } for(int k=0;k<3;k++){ warning_1();warning_1();warning_1();warning_1();warning_1();delay(300);} //Kod dostepu zapisany l=0; } void dostep() // funkcja sterujÄ…ca zamkiem { //Wprowadz KOD dostepu: while(l<5) { char keypressed = myKeypad.getKey(); if (keypressed != NO_KEY) { mykey[l]=keypressed;l++;warning_1(); } if (keypressed == '*') { goto poczatek; } czas_na_kod++; if(czas_na_kod>=max_czas_na_kod) { czas_na_kod=0; digitalWrite(13,HIGH); delay(200); digitalWrite(13,LOW); goto poczatek; } delay(30); } if( mykey[0]==pamiec[0] && mykey[1]==pamiec[1] && mykey[2]==pamiec[2] && mykey[3]==pamiec[3] && mykey[4]==pamiec[4] ) { warning_1();warning_1(); // OK ---> OTWIERAM ZAMEK na 3 sekundy mykey[0]='q'; unlock=1; // otwieram zamek na 3 sek } // sprawdzamy czy wybrano specjalny kod do zmiany szyfru else { result++; if(mykey[0]=='#' && mykey[1]=='1' && mykey[2]=='2' && mykey[3]=='3' && mykey[4]=='#' ) { // *666# for(int k=0;k<3;k++){ warning_1();warning_1();warning_1();warning_1();warning_1(); delay(300);} //Wykryto polecenie zmiany kodu dostepu... delay(500);l=0;fnowy_kod(); } else result++; } if(result>1){ // Kod NIEPRAWIDLOWY poczatek: warning_0();delay(500);result=0;} l=0; } void sterowanie() // funkcja sterowania { char keypressed = myKeypad.getKey(); if (keypressed != NO_KEY) { mykey[0]=keypressed; } if(mykey[0]=='A'){ digitalWrite(A0,LOW);delay(3000);digitalWrite(A0,HIGH);//PRZEKAZNIK STEROWANY STANEM NISKIM } if(mykey[0]=='B'){ digitalWrite(A1,LOW);delay(700);digitalWrite(A1,HIGH);//PRZEKAZNIK STEROWANY STANEM NISKIM } if(mykey[0]=='C'){ digitalWrite(A2,LOW);delay(700);digitalWrite(A2,HIGH);//PRZEKAZNIK STEROWANY STANEM NISKIM } if(mykey[0]=='D'){ digitalWrite(A3,LOW);delay(700);digitalWrite(A3,HIGH);//PRZEKAZNIK STEROWANY STANEM NISKIM } if(mykey[0]=='#'){ //blokada dostepu digitalWrite(13,LOW); delay(400); digitalWrite(13,HIGH); delay(400); digitalWrite(13,LOW); delay(400); digitalWrite(13,HIGH); delay(400); digitalWrite(13,LOW); unlock=0; } mykey[0]='q'; } //------------------------------------------------------- void setup() { pinMode(10,OUTPUT); pinMode(13,OUTPUT); pinMode(A0,OUTPUT); pinMode(A1,OUTPUT); pinMode(A2,OUTPUT); pinMode(A3,OUTPUT); pinMode(11,OUTPUT); digitalWrite(A0,1);//PRZEKAZNIK STEROWANY STANEM NISKIM digitalWrite(A1,1);//PRZEKAZNIK STEROWANY STANEM NISKIM digitalWrite(A2,1);//PRZEKAZNIK STEROWANY STANEM NISKIM digitalWrite(A3,1);//PRZEKAZNIK STEROWANY STANEM NISKIM digitalWrite(10,0); digitalWrite(11,0); digitalWrite(13,0); unlock=0; } //-------------------------------------------------------- void loop() { odczyt_EEPROM();delay(30); if(szyfr==0) fnowy_kod(); if(unlock==1) { czas_otwarcia++; if(czas_otwarcia>=max_czas) unlock=0; digitalWrite(13,HIGH); sterowanie(); } else{ czas_otwarcia=0; digitalWrite(13,LOW); dostep(); } } |
dodaję fotki ;)
Tak wygląda panel, trochę brudny.
A elektronika trafiła do takiej oto puszki zewnętrznej.
Przy najbliższych pracach modernizacyjnych planuję pochować przewody, a panel zostanie wymieniony na inną obudowę.
Pozdrawiam :)
Fajny projekt. Popraw tylko “szczytuje” na “sczytuje” bo chyba funkcja nie uprawia seksu ;-)
You made my day!
Już poprawione.
W kontekście artykułu poprawe jest użycie czasownika “odczytać”
W kontekście artykułu poprawne jest użycie czasownika “odczytać”.
A ja bym powiedział “zczytuje” ale jestem tylko głupim Ślązakiem, i głupio mi tak poprawiać polaczków w ich ojczystym języku.
A jakie masz obywatelstwo?
Ty chłopie polaczków to sobie poszukaj na podwórku w tym hanysowie gdzie mieszkasz !!!
No to Andrzyju odpowie Ci Jyndrek z Podhala i pomimo tego, że sam mówię gwarą to jednak wiem takie rzeczy jak to, że pisze/mówi się sczytać. Jeśli zaś nie jesteś pewny a tym bardziej jeśli chcesz kogoś poprawiać to lepiej to wcześniej sprawdzić. Tak więc s piszemy przed spółgłoskami bezdźwięcznymi: p, f, t, k, c, cz, ch tak jak np. sczerstwieć, sczesać, sczernieć.
Przypomniało mi się, jak robiłem to kiedyś z kolegą na zaliczenie na studiach. Tylko kod był w assemblerze :) Dobre dawne czasy.
tak się zastanawiam z tym odczytem epromu w pętli jak szybko szlak trafi kontroler, czy to czasem nie ma ograniczonej liczby cykli?
Nie jestem pewien, lecz z tego co pamiętam to eepromy mają ograniczoną ilość programowania, po której po prostu padają.
Jeśli się mylę to niech mnie ktoś poprawi.
EEPROM nie limitu odczytu, ma tylko limit cykli zapisu.
“Przydatne gdyby ktoś przez przypadek lub celowo prędzej wcisnął np. jeden znak, po wprowadzeniu 4 z pięciu znaków szyfru program wyrzucił by po prostu że szyfr jest błędny. (chyba zrozumiecie o co mi chodzi)”
Staram się, ale nie potrafię zrozumieć o co chodzi.
A tzw. “język Arduino” to po prostu zwykły C++ z automatycznie dołączanymi bibliotekami autorstwa Arduino.
Jeszcze się przyczepię błędów językowych (bo jestem wrednym człowiekiem). A resztę to już można chyba tylko pochwalić ;-)
Dlaczego nie używasz pętli oraz funkcji? np to->
digitalWrite(13,LOW);
delay(400);
digitalWrite(13,HIGH);
delay(400);
digitalWrite(13,LOW);
delay(400);
digitalWrite(13,HIGH);
delay(400);
digitalWrite(13,LOW);
można było śmiało zapisać w pętli…
a to ->
digitalWrite(A0,LOW);delay(3000);digitalWrite(A0,HIGH);
Jako że używasz tego w kilku miejscach można było zmienić w funkcję. Przy większych projektach oszczędność pamięci zwiększy oraz podniesie czytelność kodu.
if A,B,C itd powinno być switch, ale if też może być, chodź switch albo else if było by szybsze;)
const float <- tam na pewno trzeba float? jest tam konieczna liczba zmiennoprzecinkowa? Jeżeli nie to float jest piekielnie wolne, zmien na int albo unsigned int, na AVR (arduino) float jest kilka tysięcy razy wolniejszy od int'a oraz pożera kilka kb flasch'a.
A co do EEPROM to można odczytywać w nieskończoność, ograniczona jest tylko ilość zapisów, jedyne ograniczenie z odczytem to szybkość – SRAM jest o wiele szybszy od EEPROM.
Podczas pisania kodu robiłem wszystko w taki sposób, jaki przyszło mi do głowy, a później gdy już działało to nie analizowalem kodu. Z pewnością zostanie to zmiene przy nastepnej modernizacji, a ta już wkrótce ;)
Świetna sprawa, chociaż osobiście bardziej ogarniam Asemblera ze starych czasów. ;) Dzięki za fajny artykuł i pozdrawiam!
Dzięki! Po prostu idealnie w czas – dzisiaj przyszły do mnie takie klawiaturki(tylko bez linii ABCD), zastanawiam się, jak są podłączone te piny i jak je odczytać, a tu na majsterkowie jak na tacy podane :D
W czym narysowany jest ten schemat? I dlaczego nie ma fot? :-)
Schemat pochodzi z Fritzingu. Fot nie ma z uwagi na to że montaż odbył się w godzinach późno po południowych i w takich też wracam do domu, w związku z czym zdjęcia byłyby kiepskiej jakości. Postaram się je zrobić w weekend.
@edit 13:35 dodałem fotki
Super sprawa, na tym panelu do wprowadzania danych jest tyle miejsca, że fajnie byłoby jeszcze dołożyć możliwość autoryzacji za pomocą RFID.
Opcja z zapalaniem ścieżki po otwarciu furtki też spoko – szczególnie, że nie jest tak skomplikowane jak to co Już zrobiłeś.
Mi też się to mega podoba :)
Patrząc na kod, widzę że kod jest forumowego belfra w głównej mierze. Zapomniałeś dodać że to nie ty jesteś autorem. Jesteś autorem tylko dodatków do kodu zamka.
“Kod programu nie jest w pełni mojego autorstwa, oczywiście autor zezwolił na jego modyfikacje i publikację. Nieco go przerobiłem, i dodałem troszkę smaczków.”
Czytanie nie boli, ale aby zrozumieć co się czyta to niektórzy muszą się troszkę wysilić ;)
Użycie cytatu jest nieuzasadnione !
Czy zmiana kodu dostępu następuje dopiero po dezaktywowaniu systemu?