Spisu treści:

Zmień Arduino w czytnik kart magnetycznych!: 9 kroków (ze zdjęciami)
Zmień Arduino w czytnik kart magnetycznych!: 9 kroków (ze zdjęciami)

Wideo: Zmień Arduino w czytnik kart magnetycznych!: 9 kroków (ze zdjęciami)

Wideo: Zmień Arduino w czytnik kart magnetycznych!: 9 kroków (ze zdjęciami)
Wideo: Bezdotykowe otwieranie furtki? Jak zaprogramować pastylkę do domofonu Orno i innych? RFID 2024, Lipiec
Anonim
Zmień swoje Arduino w czytnik kart magnetycznych!
Zmień swoje Arduino w czytnik kart magnetycznych!
Zmień swoje Arduino w czytnik kart magnetycznych!
Zmień swoje Arduino w czytnik kart magnetycznych!
Zmień swoje Arduino w czytnik kart magnetycznych!
Zmień swoje Arduino w czytnik kart magnetycznych!

Chyba każdy używał czytnika kart magnetycznych. To znaczy, kto w dzisiejszych czasach nosi gotówkę? Nie są też trudne do zdobycia, a podczas wycieczki do mojego ulubionego lokalnego sklepu z elektroniką znalazłem kosz pełen tych facetów. Więc… oczywiście wziąłem jeden i przyniosłem go do domu, żeby zobaczyć, jakie rzeczy mogę z nim zrobić i AVR.

Ta instrukcja pokaże Ci, jak podłączyć czytnik kart magnetycznych Magtek do AVR lub Arduino / klona i odczytać dane z pierwszej ścieżki karty. Zapnij siedzenia; Czytniki kart magnetycznych mają wysoką przepływność!

Krok 1: Lista wyposażenia

Lista wyposażenia
Lista wyposażenia
Lista wyposażenia
Lista wyposażenia

Oto kilka rzeczy, które musisz zacząć.

  • Czytnik kart magnetycznych (Mój to dwugłowicowy czytnik Magetk 90 mm. 5,00 USD)
  • AVR, Arduino lub klon (ATmega328p ~ 4,30 USD z Mouser.com)
  • płytka stykowa bez lutowania
  • trochę drutu
  • może nagłówek, jeśli lubisz takie rzeczy.
  • coś do odczytania twojego portu szeregowego. Używam terminala AVR z BattleDroids.net

To wszystko, czego powinieneś potrzebować, aby zacząć. W zależności od czytnika kart magnetycznych, który otrzymasz, może być konieczne zmodyfikowanie tych instrukcji, a na pewno kodu, aby działały z konkretnym czytnikiem. Mam jednak nadzieję, że kod, który napisałem, zaprowadzi cię dość daleko.

Krok 2: Samoczynne czytniki kart magnetycznych

Samoczynne czytniki kart magnetycznych
Samoczynne czytniki kart magnetycznych
Samoczynne czytniki kart magnetycznych
Samoczynne czytniki kart magnetycznych
Samoczynne czytniki kart magnetycznych
Samoczynne czytniki kart magnetycznych
Samoczynne czytniki kart magnetycznych
Samoczynne czytniki kart magnetycznych

Czytniki kart magnetycznych są „samoczynnie taktujące”, co oznacza, że zapewniają zegar zwany stroboskopem, z którym podłączony mikrokontroler może się synchronizować. To jest dobrodziejstwo. Oznacza to, że nie musisz się martwić o szukanie sygnału taktującego i synchronizowanie sygnału tak, aby był wyśrodkowany bezpośrednio na impulsie zegarowym, i nie musisz przeszkadzać w oscylowaniu w słodkim punkcie sygnału zegarowego. Ma to sens, gdy myślisz o przeciągnięciach kart: wszyscy przesuwają w innym tempie, niektórzy wolniej, inni szybciej niż inni. Self-locking pozwala nawet mojej słodkiej babci na korzystanie z jej karty bez łamania jej nadgarstka. Przypomina mi o konieczności zmiany dla niej ustawienia, które określa, ile czasu między kliknięciami jest ważne, aby zarejestrować dwukrotne kliknięcie….

Dane tego czytnika kart są ważne 1,0 nas przed włączeniem lampy, więc nie musisz się martwić o opóźnienie, aby wejść w „czas bitowy”. W przypadku czytnika dwugłowicowego, takiego jak ten, którego używam, dostępne są do odczytu dwie ścieżki danych. W tym 'ible, pokażę czytanie z pierwszego pierwszego utworu, aby zacząć. Jest pięć połączeń, które musisz wykonać (cztery, jeśli nie masz nic przeciwko rezygnacji z bardziej precyzyjnej kontroli dla mniejszej liczby używanych portów I/O). Sprawdź zdjęcie poniżej. Czerwony przewód przechodzi do +5V, podczas gdy czarny przewód przechodzi do masy. Zielony przewód to /CARD_PRESENT; żółty przewód to /STROBE, a biały przewód to /DATA1. Ukośnik (/) oznacza, że dane są odwrócone. Niski sygnał (tj. 0) jest odczytywany jako jeden lub wysoki. Pozostałe złącza są brązowe dla /STROBE2 i pomarańczowe dla /DATA2. Nie będziemy ich używać. Jeśli chcesz, możesz zapomnieć o /CARD_PRESENT. Ta linia danych obniża się po około 17 obrotach strumienia głowicy, aby wskazać, że karta jest obecna (zamiast, powiedzmy, losowy szum powodujący wysyłanie przez czytnik fałszywych danych) i służy do sprawdzania, czy dane, które otrzymujesz, są danymi karty i nie śmieci. Możesz pominąć to połączenie, jeśli sprawdzisz początek wartownika w strumieniu danych. Więcej o tym później. Jak widać poniżej, użyłem męskiego nagłówka pod kątem prostym podłączonego do płytki chlebowej i podłączyłem do niej mój czytnik. Podłączyłem /STROBE do PIND2 (cyfrowy pin 2 na Arduino), /CARD_PRESENT do PIND3 (w celach ilustracyjnych) i /DATA1 do PIND4. Upewnij się, że włączyłeś podciąganie na tych szpilkach, aby szpilki nie unosiły się. Wymieniłem również moje Arduino na AVR Bare Bones, ponieważ podoba mi się sposób, w jaki pasuje do płytki stykowej.

Krok 3: Podstawy kart magnetycznych

Podstawy kart magnetycznych
Podstawy kart magnetycznych

Podstawowe funkcje, które musisz wykonać, aby odczytać kartę magnetyczną, to: 1. Wykrywanie, kiedy karta została przesunięta 2. Odczytywanie strumienia danych 3. Wykrywanie zniknięcia karty 4. Przetwarzanie danych 5. Wyświetlanie data Najpierw przedstawię Ci podstawowe informacje o kartach magnetycznych, o których będziesz musiał wiedzieć, kiedy zaczniesz pisać własny kod.

Standardy kart magnetycznych

Karty magnetyczne są standaryzowane przez ISO w następujących dokumentach: 7810 Właściwości fizyczne dokumentu wielkości karty kredytowej 7811-1 Tłoczenie 7811-2 Pasek magnetyczny - niska koercja 7811-3 Lokalizacja wytłaczanych znaków 7811-4 Lokalizacja ścieżek 1 i 2 7811- 5 Lokalizacja ścieżki 3 7811-6 Pasek magnetyczny - wysoka koercja 7813 Karty transakcji finansowych Jak widać, karty finansowe są wyszczególnione w osobnym dokumencie i często mają inny format niż, powiedzmy, karta spożywcza lub międzynarodowa karta telefoniczna. Będziesz musiał zaprogramować te różnice. Właśnie miałem pod ręką kartę kredytową i kartę ubezpieczeniową, więc zaprogramowałem dla tych typów (które akurat są w formacie B).

Formaty kart

Istnieje kilka różnych formatów kart magnetycznych. Formaty A i B są wspólne, przy czym B jest najczęstszym, jaki widziałem i który jest obsługiwany w tym kodzie. Formaty od C do M są zarezerwowane przez ISO, jak sądzę, podczas gdy od N do ?? są zarezerwowane do użytku instytucjonalnego. Ścieżka 1 W przypadku kart finansowych pierwsza ścieżka jest zapisywana z szybkością 210 bitów na cal i jest pierwszym 0,110 cala karty od góry. Dane są zakodowane jako „dane karty” jako 7 bitów na znak. znak i bit parzystości. Na ścieżce 1 znajduje się ~ 79 znaków alfanumerycznych. Fizyczna kolejność jest odwrotna. Oznacza to, że dane są, ale są zapisane od tyłu na karcie (a więc będą odczytywane przez oprogramowanie układowe) jako. parzystość jest nieparzysta Format danych karty wygląda tak:

[SS] [FC] [Nr konta podstawowego] [FS] [Nazwa] [FS] [Dane dodatkowe] [FS][ES][LRC]gdzie:

SS Początek wartości wskaźnikowej FC Kod formatu FS Separator pól ES Koniec wartości wskaźnikowej LRC Nadmiarowość wzdłużna Znak kontrolny Śledź jeden SS = '%', FC = jeden z formatów (wiele razy będzie B), FS to często '', ES to '?' a znak LRC to zwykle „<”, chociaż nie jest to określone w normach. Poza tym, że są zapisywane na karcie od tyłu, dane mają nieparzysty bit parzystości i są to 0x20 z ASCII. Zajmiemy się tym podczas przetwarzania danych. Ścieżka 2 Ścieżka druga ma szerokość 0,110 cala i zaczyna się 0,110 od góry karty. Gęstość zapisu wynosi 75 bitów na cal. Dane mają długość 5 bitów na znak i składają się z około 40 tylko symboli numerycznych. litery na tej ścieżce. Format danych karty powinien być zgodny z tą strukturą

[SS] [numer konta podstawowego] [FS] [dane dodatkowe | dane uznaniowe] [ES] [LRC]

SS dla ścieżki drugiej to średnik: ';' a FS to '=' Mając tę świętą wiedzę za pasem, przejdź do następnych kroków, aby zobaczyć kod implementujący procedurę opisaną powyżej.

Krok 4: Wykryj, kiedy karta jest przesuwana

Wykryj, gdy karta jest przesuwana
Wykryj, gdy karta jest przesuwana

1. Wykryj, kiedy karta została przeciągnięta Formalnie, należy sprawdzić pin / CARD_PRESENT, aby sprawdzić, czy spadła nisko. Na szczęście nie jest to konieczne. Sprawdzimy później, czy karta jest ważna. Alternatywnie, możesz odczytać swój pin stroboskopowy, aby zobaczyć, kiedy stroboskop został nałożony na pin, jednak dzięki temu uzyskasz wiele zer taktowania. Czytnik wyśle około 60-70 wiodących zer, aby poinformować, że dane mają zostać zaprezentowane. Jednak zamierzamy wykorzystać naturę danych binarnych, aby określić, kiedy rozpocząć rejestrowanie bitów. Wskaźnikiem początkowym (SS) dla pierwszej ścieżki jest znak procentowy (%). Jego wartość binarna to 0010 0101, co oznacza, że będzie przechowywana (i odczytywana) jako 1010 001 (jest 7 bitów, więc ósmy bit nie jest przesyłany). Teraz wnikliwy czytelnik zauważy, że chociaż dane są odwrócone, nie pasują do binarnej wartości ASCII. To dlatego, że jest to 0x20 poza hexem. Symbol % to 0x25, a 0100 0101 to 0x05. Dane karty mają odjęte 0x20 od wartości. Ten, który kręci się wysoko, jest dziwną parzystością. Umieszczono go tam, aby w wartości znajdowała się nieparzysta liczba „1”. Tak więc, ponieważ wiemy, że ważna karta zawsze zaczyna się tym początkowym sygnałem ostrzegawczym i ponieważ bit parzystości to 1, to kiedy wykryjemy pierwsze przejście z wysokiego na niski na pinie danych, wiemy, że właśnie zaczęliśmy otrzymywać zacznij wartownika z karty. Teraz to nie zawsze będzie prawda, a niezawodnym planem byłoby sprawdzenie karty /CARD_PRESENT, aby sprawdzić, czy dodatkowo spadła na LOW. Najprostszym sposobem wykrycia początku SS jest utworzenie zewnętrznego przerwania wyzwalanego na opadającym zboczu /STROBE. Dane są ważne 1,0 nas przed zboczem opadającym, więc po próbkowaniu zbocza opadającego wiesz, że możesz odczytać pin /DATA1 i uzyskać prawidłową wartość. Oto kod do tworzenia zewnętrznego przerwania wyzwalanego przy opadającym zboczu.

voidInitInterrupt(void){ // Konfiguracja przerwania BSET(EIMSK, INT0); // zewnętrzna maska przerwań BSET(EICRA, ISC01); // opadająca krawędź BCLR(EICRA, ISC00); // opadająca krawędź BSET(SREG, 7); // I-bit w SREG}

W moim common.h, który umieszczam we wszystkich moich programach, można znaleźć definicje BSET i BCLR. Odwołaj się do tego pliku, jeśli masz jakiekolwiek pytania dotyczące ustawiania bitów. Teraz, gdy przerwanie jest wyzwalane, chcemy próbkować /DATA1 (w moim kodzie zdefiniowanym jako CARD_DATA) i ustawić bit w rejestrze IO ogólnego przeznaczenia. Jeśli jesteśmy na siódmym bicie, zapisz rejestr jako znak w naszym globalnym buforze. Używam rejestru GPIOR0, ponieważ jest to spiffy szybki dostęp. Pseudokod wygląda mniej więcej tak:

Zatrzymaj 16-bitowy timer Wyczyść timer Jeśli DATA jest LOW Ustaw BIT=1 w REGISTER Zmniejsz BIT Ustaw flagę, aby nie pomijać więcej zer w przeciwnym razie DATA jest HIGH Ustaw BIT=0 w REGISTER Zmniejsz BIT Jeśli BIT wynosi 0 Dodaj bajt do bufora Indeks przyrostu Reset BIT

Jeśli zadajesz sobie pytanie, dlaczego dekrementacja zamiast inkrementacji, pamiętaj, że dane są odwrócone, więc zamiast rejestrować bity tak, jak dostajemy je z LSB do MSB, zapisujemy je z MSB do LSB, więc nie musimy cofać bitów później podczas przetwarzania danych. Jeśli naprawdę chcesz, możesz również dodać 0x20 hex tutaj, ale ponieważ w tych stroboskopach jest to około 5 us, ograniczam przetwarzanie w tej procedurze obsługi przerwań do minimum.

ISR(INT0_vect){ StopTimer(); ClearTimer(); if (!BCHK(PIND, CARD_DATA1)) // inverse low = 1 { BSET(GPIOR0, bit); --fragment; bDataPresent = 1; } else if (bDataPresent) { BCLR(GPIOR0, bit); --fragment; } if (bit < 0) { buff[idx] = (char)GPIOR0; ++idx; bit = 6; } StartTimer();} Jeśli zastanawiasz się, o co chodzi w biznesie związanym z synchronizacją, jest to omówione w kroku określania, kiedy karta opuściła czytnik.

Krok 5: Przeczytaj strumień danych

Przeczytaj strumień danych

Cóż, już pokazałem, jak odczytywać dane, ponieważ jest to część procedury obsługi przerwań dla naszego zewnętrznego przerwania opadającego zbocza. Alternatywną metodą byłoby ustawienie flagi w ISR, aw głównej pętli odpytywanie flagi i odczytywanie danych w ten sposób, ale uważam, że sposób, w jaki to przedstawiłem, jest czystszy. Bądź swoim własnym sędzią i napisz swoją, jednak MCU na to pozwoli. Mając to na uwadze, przejdźmy do dowiedzenia się, jak wykryć, kiedy karta ciągnie Elvisa i opuszcza budynek.

Krok 6: Wykryj kartę opuszczającą czytnik

Wykryj kartę opuszczającą czytnik
Wykryj kartę opuszczającą czytnik

Wykryj, kiedy karta zniknęła

Formalnie, można by próbkować pin /CARD_PRESENT, aby sprawdzić, czy znowu jest WYSOKI, ale nie potrzebujemy żadnego steenkin' /CARD_PRESENT zajmującego inny port I/O. Tutaj wkraczają te zegary. Za każdym razem, gdy wywoływane jest przerwanie, ponieważ wykryliśmy opadające zbocze na /STROBE, zatrzymujemy zegar, czyścimy jego wartość i zaczynamy czytać. Kiedy skończymy czytać, ponownie uruchamiamy stoper. Powtarzaj do znudzenia lub do momentu, gdy licznik czasu osiągnie określoną wartość. Oznacza to, że ostatnie przerwanie zostało wywołane i nie napłynęło więcej danych, więc zakładamy, że to wszystko i rozpoczynamy przetwarzanie danych, które zebraliśmy. Dla timerów używamy TIMER1, czyli 16-bitowego timera. Używam rezonatora 16 Mhz zewnętrznie do mojego AVR. Jeśli używasz arduino, prawdopodobnie też tak. Wybrałem więc wartość preskalera 1024, co oznacza, że co (16 000 000/1024) licznik będzie się zwiększał. To znaczy, że będzie „tykać” 15 625 razy na sekundę. /CARD_PRESENT zmieni stan na WYSOKI wskazując, że karta opuściła czytnik około 150ms po ostatnim bicie danych. Wiedząc o tym, postanowiłem sprawdzać co 1/4 sekundy. To wyglądałoby mniej więcej tak:

(((F_CPU) / PRESKALER) / 4) co okazuje się być około 3900. Czyli gdy licznik timera TCNT1 osiągnie 3900, to wiem, że minęło około 300ms i mogę całkiem śmiało stwierdzić, że karta opuściła czytnik. Łatwo

#define PRESCALER 1024#define CHECK_TIME ((F_CPU / PRESCALER) / 4) // 250 ms#define StartTimer() BSET(TCCR1B, CS10), BSET(TCCR1B, CS12) // 1024 preskaler#define StopTimer() BCLR(TCCR1B, CS10), BCLR(TCCR1B, CS12)#definiuj ClearTimer() (TCNT1 = 0) Widziałeś w ISR, gdzie timer jest uruchamiany, zatrzymywany i kasowany przy każdym przerwaniu. Teraz w pętli głównej po prostu sprawdzamy, czy licznik timera osiągnął naszą wartość docelową, a jeśli tak, rozpoczynamy przetwarzanie danych

dla (;;) { jeśli (TCNT1 >= CHECK_TIME) {

StopTimer(); ClearTimer(); Przetwarzać dane(); CzytajDane(); idx = 0; bit = 6; bDataPresent = 0; memset(&buff, 0, MAX_BUFF_SZ1); } } Teraz możesz bezpiecznie przetwarzać dane

kod sformatowany przez

Krok 7: Przetwarzaj dane

Przetwarzaj dane
Przetwarzaj dane

Przetwarzaj dane

Faza przetwarzania składa się z:

  • sprawdzanie ważności SS
  • sprawdzanie parzystości
  • konwersja do ASCII
  • sprawdzanie prawidłowego ES
  • sprawdzanie LRC

Tutaj nie zawracam sobie głowy sprawdzaniem parzystości, ponieważ po prostu ustawiam ten bit na zero. Nie obliczam też LRC dla tego małego samouczka. Byłoby to coś, co może chcieć zrobić bardziej w pełni zrealizowane oprogramowanie układowe. Oto kod do przetwarzania danych, wykonując powyższe kroki (poza wcześniej wymienionymi). Znajdź to na obrazku poniżej. Jest to skomentowane i dość oczywiste. Specjalna uwaga na temat parzystości i ASCII: po prostu usuwam bit parzystości (7 bit…tj. 1 z 6 zerami za nim) i aby przekonwertować z „danych karty”, musisz dodać 0x20 do wartości. O to chodzi.

Krok 8: Wyświetl dane

Wyświetl dane
Wyświetl dane
Wyświetl dane
Wyświetl dane

Wyświetl dane

Wyświetlacz przechodzi do programu terminalowego, który napisałem specjalnie do podłączenia do AVR przez RS232 lub USB. Program nazywa się Terminal AVR. Metoda ReadData() jest dość brzydka i zachęcamy do znalezienia czystszego rozwiązania niż to, które wymyśliłem. Istnieje również wyjście funkcji w Terminalu AVR. Wyjście to pierwsza karta ubezpieczenia zdrowotnego, a druga karta VISA. Kliknij w lewym górnym rogu obrazu i wybierz oryginalny lub duży obraz, aby zobaczyć go lepiej.

Krok 9: Pobieranie i zamykanie kodu

W tej instrukcji omówiłem kilka podstaw czytników kart magnetycznych i pokazałem kod, który pomoże ci rozpocząć odczytywanie danych z kart magnetycznych we właściwym kierunku. Jest jeszcze dużo pracy, którą można wykonać, na przykład odczytywanie i dekodowanie drugiej ścieżki, obliczanie LRC i obliczanie nieparzystości każdego bajtu. Pełny kod źródłowy jest dostępny do pobrania poniżej. Został napisany w AVR Studio 4.17. Mam nadzieję, że podobała Ci się ta instrukcja i jak zawsze czekam na wszelkie komentarze lub sugestie, które możesz mieć. Udanego kodowania i AVR'ing!

Zalecana: