Mikrokontrolery - Jak zacząć?

... czyli zbiór praktycznej wiedzy dot. mikrokontrolerów.

niedziela, 20 marca 2011

DIY: Zamek szyfrowy. Przykład zabezpieczenia komputera PC. ATmega8 + Arduino


Autor: Konrad197
Redakcja: Dondu

Zobacz inne artykułu z cyklu: Arduiono ... czyli prościej się nie da :-)

Zapewne wiele razy widziałeś drzwi zabezpieczone zamkiem szyfrowym. Zwykle jest to klawiatura numeryczna z kilkoma znakami specjalnymi.

Zabezpieczenie zamka kodem PIN jest skuteczną i nowoczesną metodą radzenia sobie z niechcianymi gośćmi. Pewnego zimowego popołudnia pomyślałem, że fajnie byłoby poszpanować czymś przed znajomymi.

Jako, że zawsze podobały mi się elektroniczne zabezpieczenia dostępu do pomieszczeń, postanowiłem zbudować coś podobnego, lecz do zabezpieczenia mojego PC.


Urządzenie wykonane w sposób pokazany w artykule nie gwarantuje praktycznie żadnego zabezpieczenia, ponieważ wystarczy w odpowiednim miejscu na płytce zrobić zwarcie.

Projekt ten służy jedynie jako przykład realizacji zamka szyfrowego do ewentualnej rozbudowy lub modyfikacji.

Jeżeli natomiast zadbasz by dostęp do elektroniki zamka i komputera był niemożliwy, to jak każdy inny profesjonalny zamek, także i ten spełni swoją rolę :-)

Urządzeniem steruje popularny mikrokontroler ATmega8, o taktowaniu zegara 16[MHz] oraz zasilaniu z wykorzystaniem portu USB. Dane wyświetlane są na wyświetlaczu LCD o rozdzielczości 16x2, do ich wprowadzania służy mała klawiatura 4x4.

Za sterowanie komputerem odpowiada przekaźnik JRC23F, który po otrzymaniu sygnału z mikrokontrolera zwiera odpowiednie styki na płycie głównej, co powoduje włączenie się komputera.






Schemat urządzenia jest bardzo prosty:


Schemat zamka szyfrowego (ATmega8).
Schemat zamka szyfrowego.


Jak widać, w układzie znajduje się rejestr przesuwny – 74HC595, który zastosowałem w celu zaoszczędzenia kilku ponów mikrokontrolera, pozwala on sterować wyświetlaczem LCD za pomocą jedynie trzech pinów procesora.

Całość wykonałem na płytce uniwersalnej, wszystkie połączenia poprowadziłem po stronie druku, by ukryć je z wierzchu płytki. Urządzenie tak się prezentuje:


Zamek szyfrowy w wersji testowej.
Zamek szyfrowy w wersji testowej.

Program został zrealizowany w środowisku Arduino. Nie jest to w całości mój autorski projekt, skorzystałem bowiem z tego rozwiązania i je przerobiłem.

Aby zaprogramować mikrokontroler z użyciem programatora wystarczy wybrać z listy płytkę zawierającą ten procesor (dla ATmega8 jest to Arduino NG z tą kostką) i z wciśniętym klawiszem „Shift” nacisnąć przycisk ZAŁADUJ.

Należy tutaj pamiętać o podłączeniu do procesora kwarcu 16[MHz] i wcześniejszej zmianie bitów konfiguracyjnych dla tej częstotliwości.

Gotowy program (należy skopiować do środowiska Arduino):

kod.c

#include <LiquidCrystal595.h>    // wczytuję bibliotekę dla LCD
LiquidCrystal595 lcd(10, 9, 8);  // podłączenie 74HC595 (datapin, latchpin, clockpin)
#include <Keypad.h>              // wczytuję bibliotekę dla klawiatury
#include<EEPROM.h>               // wczytuję bibliotekę dla EEPROM 

// --- zmiennie ------------------------------------------
  const byte wiersze= 4; //ilość wierszy
  const byte kolumny= 4; //ilość kolumn

  //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] = {7,6,5,4}; // wiersze 0-3
  byte kolumny_piny[kolumny]= {3,2,1,0}; // kolumny 0-3
  int pamiec[6]; // pamięc wciśniętych klawiszy - 6 znaków
  
  volatile int PIN=0; // PIN=0 -> brak | PIN=1 jest aktywny
  volatile int l=0; // zmienna pomocnicza, licznik znaków
  volatile int result=0; // rezultat porównania ciągu 6-ciu znaków
  
  int mykey[6]; // taklica wciśniętych klawiszy
  
  Keypad myKeypad= Keypad(makeKeymap(mapaklawiszy), wiersze_piny, kolumny_piny, wiersze, kolumny); // definicja obiektu klasy Keypad


// --- funkcje programu: --------------------------------- 
  
  void warning_0() //Buzzer dla OK
{
    digitalWrite(11, HIGH);    
    delay(600);
    digitalWrite(11, LOW);
    delay(30);
    warning_1();
} 

  void warning_1() //Buzzer dla błąd
{
    digitalWrite(11, HIGH);
    delay(35);
    digitalWrite(11, LOW);
    delay(35);
} 


  void odczyt_EEPROM() // funkcja sprawdza obecnośc szyfru w pamięci EEPROM
{
   for (int i=0;i<6;i++) 
  {
  pamiec[i]=EEPROM.read(i);} 
   if(pamiec[0]!=255 && pamiec[1]!=255 && pamiec[2]!=255 && pamiec[3]!=255 && pamiec[4]!=255 && pamiec[5]!=255)
       PIN=1;
   
   else
       PIN=0; 
}
  
  void fnowy_kod() // funkcja ustawia nową kombinację dla kodu PIN
{
   for(int i=0;i<6;i++)
   EEPROM.write(i,255); // kasowanie EEPROM
    lcd.clear();        // wyświetlanie danych na LCD
    lcd.setCursor(0, 0);// ustawienie kursora w odpowiedznim miejscu na LCD 
    lcd.print("Skasowano stary");
    lcd.setCursor(0, 1);// przejście do drugiej linijki 
    lcd.print("kod PIN!");
    delay(1500);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Podaj nowy kod");
    lcd.setCursor(0, 1);
    lcd.print("PIN: ");
   
   while(l<6)
     {
     char keypressed = myKeypad.getKey();
     if (keypressed != NO_KEY)
       {
       EEPROM.write(l, keypressed); //zapis znaku do eeprom
       
                                         
        for(int a = 0 ; a<6 ; a++)
        lcd.setCursor(l+5, 1);
        lcd.print('*'); // wyświetlanie gwiazdek zamiast znaków na LCD
        
        l++;
        
        warning_1(); 
                         
       } 
     }
   for(int k=0;k<3;k++){
   warning_1();
   warning_1();
   warning_1();
   warning_1();
   warning_1();
   warning_1();
   delay(300);}
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("---> Zapisano!");
   l=0; 
   delay(1500);
}

  
  void dostep() // funkcja sterująca PCtem
{
  lcd.clear();
  lcd.setCursor(0, 0); 
  lcd.print("Podaj kod PIN: "); 
   while(l<6)
     {
     char keypressed = myKeypad.getKey();
     if (keypressed != NO_KEY)
       {
       mykey[l]=keypressed;
   
       for(int a = 0 ; a<6 ; a++)
       lcd.setCursor(l, 1);
       
       lcd.print('*');  // wyświetlanie gwiazdek w miejscu znaków na LCD
      
       l++;
       warning_1();
       } 
     }
   
   if(mykey[0]==pamiec[0] && mykey[1]==pamiec[1] && mykey[2]==pamiec[2] 
   && mykey[3]==pamiec[3] && mykey[4]==pamiec[4] && mykey[5]==pamiec[5]) // sprawdzanie, czy kod jest zgodny z podanym...
     {
     warning_1();
     warning_1();
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("OK, odpalam PC");
     digitalWrite(13, HIGH); // Sygnał do przekaźnika
     digitalWrite(12, LOW);
     delay(1000);
     digitalWrite(13, LOW); 
     digitalWrite(12, HIGH);
     // Włączam PC
     } 
   else 
     {
       result++;
       if(mykey[0]=='*' && mykey[1]=='1' && mykey[2]=='#' && mykey[3]=='B' // sprawdzanie, czy wybrano kod zmiany PIN'u (*1#B7#)
       && mykey[4]=='7' && mykey[5]=='#' ) 
         {
         for(int k=0;k<3;k++){
         warning_1();
         warning_1();
         warning_1();
         warning_1();
         warning_1();
         delay(300);}
         lcd.clear();
         lcd.setCursor(0, 0);
         lcd.print("Wykryto rozkaz");
         lcd.setCursor(0, 1);
         lcd.print("zmiany kodu PIN!");
         delay(1500);
         l=0;
         fnowy_kod();         
       } 
       else result++;
     }
   
   if(result>1) // jeżeli podano zły kod PIN, nie włączaj PC
   { 
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print("Zly kod PIN!");
     warning_0();
     delay(500);
     result=0;}
     l=0; 
   }

  void setup() // konfiguracja procesora 
{
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(13, LOW);
  lcd.begin(16,2); // deklaracja wyświetlacza
}

  void loop()
{   
  odczyt_EEPROM();
  delay(30);
  if(PIN==0)fnowy_kod();
  else dostep();
}

Do pobrania: kod.c (kopia)


Działa to na takiej zasadzie:
  • Wprowadzam PIN urządzenia
  • Mikrokontroler porównuje wpisany kod z zapisanym w EEPROM
  • Gdy kod się zgadza, procesor wysyła sygnał do przekaźnika, ten natomiast włącza komputer
  • Gdy kod się nie zgadza, wyświetlany jest odpowiedni komunikat
  • Gdy podam specjalny kod, zostaje skasowany stary PIN i można wprowadzić nowy


Podłączenie do komputera

Aby urządzenie mogło działać, należy podłączyć je do płyty głównej w miejscu przycisku Power. Zastąpi go w tym momencie przekaźnik. Zasilanie można zrealizować z portu USB, bądź dowolnego zasilacza wtyczkowego, po wcześniejszym zastosowaniu stabilizatora.


Zobacz inne artykułu z cyklu: Arduiono ... czyli prościej się nie da :-)




Biblioteki:


Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

16 komentarzy:

  1. Mam problem z czytanie bibliotek do tego programu
    Po dołączeniu biblioteki wyskakuje komunikat, że nie może znaleźć biblioteki w tej bibliotece
    nie wiem jak to rozwiązać

    OdpowiedzUsuń
    Odpowiedzi
    1. Pokaż komunikaty z kompilacji.

      Usuń
    2. Error 1 LiquidCrystal595.h: No such file or directory

      Usuń
    3. Jeśli kod programu jest taki jak w artykule powyżej, to pliki biblioteki powinny być w tym samym katalogu. Jeśli tak masz, to problemem zapewne jest to, że inkludowany jest nieprawidłowo:

      Zmień: #include <LiquidCrystal595.h>
      na: #include "LiquidCrystal595.h"

      i daj proszę znać, czy pomogło.

      Usuń
    4. Ten komentarz został usunięty przez autora.

      Usuń
  2. Generalnie wyrzuca błędy z Print.h i EEPROM jeszcze

    OdpowiedzUsuń
  3. Po zmianie #include
    na: #include "LiquidCrystal595.h"
    wyrzuca Print.h No such file or directory

    OdpowiedzUsuń
  4. Mi przy kompilacji wywala takie błędy:

    LiquidCrystal595.h:98: error: conflicting return type specified for 'virtual void LiquidCrystal595::write(uint8_t)'

    virtual void write(uint8_t);

    ^

    In file included from C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/Stream.h:26:0,

    from C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial.h:29,

    from C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:224,

    from sketch\zamek_szyfrowy.ino.cpp:1:

    C:\Program Files\Arduino\hardware\arduino\avr\cores\arduino/Print.h:48:20: error: overriding 'virtual size_t Print::write(uint8_t)'

    virtual size_t write(uint8_t) = 0;

    ^

    exit status 1
    conflicting return type specified for 'virtual void LiquidCrystal595::write(uint8_t)'

    OdpowiedzUsuń
    Odpowiedzi
    1. Wynika to ze zmian w interfejsie klasy LiquidCrystal w nowym Arduino. Trzeba nieco przerobić kod.

      Usuń
    2. A co dokładnie trzeba by było zmienić?

      Usuń
  5. Pomożecie ? O co może chodzić ?
    sketch\Keypad.cpp:32:20: fatal error: Keypad.h: No such file or directory

    #include

    ^

    compilation terminated.

    exit status 1
    Błąd kompilacji.

    OdpowiedzUsuń
    Odpowiedzi
    1. Nie dodałeś biblioteki Keypad - link jest na końcu artykułu.

      Usuń
  6. Biblioteki ogarnięte - nowe arduino i ch nie czytało
    teraz problem polega na tym że po podłączeniu układu wyświetlacz nie reaguje

    OdpowiedzUsuń
    Odpowiedzi
    1. Opisz proszę dokładniej.

      Usuń
    2. Na wyświetlaczu pojawiają się kwadraty tylko w górnym rzędzie
      jak reguluje kontrast to reaguje tylko górny rząd.
      poza tym buzzer wydaje dzwine dzwieki

      Usuń

Działy
Działy dodatkowe
Inne
O blogu




Dzisiaj
--> za darmo!!! <--
1. USBasp
2. microBOARD M8


Napisz artykuł
--> i wygraj nagrodę. <--


Co nowego na blogu?
Śledź naszego Facebook-a



Co nowego na blogu?
Śledź nas na Google+

/* 20140911 Wyłączona prawa kolumna */
  • 00

    dni

  • 00

    godzin

  • :
  • 00

    minut

  • :
  • 00

    sekund

Nie czekaj do ostatniego dnia!
Jakość opisu projektu także jest istotna (pkt 9.2 regulaminu).

Sponsorzy:

Zapamiętaj ten artykuł w moim prywatnym spisie treści.