Cuprins:

Transformați-vă Arduino într-un cititor de carduri magnetic !: 9 pași (cu imagini)
Transformați-vă Arduino într-un cititor de carduri magnetic !: 9 pași (cu imagini)

Video: Transformați-vă Arduino într-un cititor de carduri magnetic !: 9 pași (cu imagini)

Video: Transformați-vă Arduino într-un cititor de carduri magnetic !: 9 pași (cu imagini)
Video: Transformați-vă Telefonul într-un Terminal POS cu ajutorul Tap On Phone| Încercați Acum! | 30" 2024, Iulie
Anonim
Transformați-vă Arduino într-un cititor de carduri magnetic!
Transformați-vă Arduino într-un cititor de carduri magnetic!
Transformați-vă Arduino într-un cititor de carduri magnetic!
Transformați-vă Arduino într-un cititor de carduri magnetic!
Transformați-vă Arduino într-un cititor de carduri magnetic!
Transformați-vă Arduino într-un cititor de carduri magnetic!

Cred că toată lumea a folosit un cititor de carduri magnetice. Adică, cine poartă numerar în aceste zile? Nici ele nu sunt dificil de pus în mână și, în timpul unei călătorii la magazinul meu local de electronice preferat, am găsit un coș de plin cu acești tipi. Așadar … desigur, am luat unul și l-am adus acasă pentru a vedea ce fel de lucruri aș putea face cu el și un AVR.

Această instrucțiune vă va arăta cum să conectați un cititor de card magnetic Magtek la un AVR sau Arduino / clonă și să citiți datele de pe prima pistă a cardului. Închideți scaunele; cititoarele de carduri magnetice au o rată de biți mare!

Pasul 1: Lista echipamentelor

Lista echipamentelor
Lista echipamentelor
Lista echipamentelor
Lista echipamentelor

Iată câteva lucruri de care va trebui să începeți.

  • Cititor de carduri magnetice (al meu este un cititor cu cap dublu Magetk 90mm. 5,00 USD)
  • AVR, Arduino sau clonă (ATmega328p ~ 4,30 USD de la Mouser.com
  • panou fără sudură
  • ceva sârmă
  • poate un antet dacă îți place chestia asta.
  • ceva de citit portul tău serial. Folosesc terminalul AVR de pe BattleDroids.net

Asta este tot ce ar trebui să aveți pentru a începe. În funcție de cititorul de cărți magice pe care îl veți obține, poate fi necesar să modificați aceste instrucțiuni și, cu siguranță, codul, pentru a lucra cu cititorul dvs. specific. Cu toate acestea, codul pe care l-am scris ar trebui să te ducă destul de departe, sper.

Pasul 2: Cititoare de carduri magnetice cu auto-ceas

Cititoare de carduri magnetice cu auto-ceas
Cititoare de carduri magnetice cu auto-ceas
Cititoare de carduri magnetice cu auto-ceas
Cititoare de carduri magnetice cu auto-ceas
Cititoare de carduri magnetice cu auto-ceas
Cititoare de carduri magnetice cu auto-ceas
Cititoare de carduri magnetice cu auto-ceas
Cititoare de carduri magnetice cu auto-ceas

Cititoarele de carduri magnetice sunt "auto-clocking", ceea ce înseamnă că oferă un ceas numit stroboscop, cu care microcontrolerul conectat se poate sincroniza. Acesta este un avantaj. Înseamnă că nu trebuie să vă faceți griji cu privire la căutarea unui semnal de ceas și la sincronizarea semnalului pentru a se centra direct pe impulsul ceasului și fără a oscila deranjant în punctul dulce al semnalului de ceas. Acest lucru are sens atunci când vă gândiți la glisări de cărți: toată lumea glisează într-un ritm diferit, unele mai încet, altele mai repede decât altele. Auto-ceasul îi permite chiar și dulcei mele bunici să-și folosească cardul fără să-i rupă încheietura mâinii. Îmi amintește că trebuie să schimb setarea pentru ea, care determină cât timp este valabil între clicuri pentru a înregistra un dublu clic ….

Datele acestui cititor de carduri sunt valabile 1.0 noi înainte ca stroboscopul să fie pus pe linie, așa că nu vă faceți griji cu privire la întârziere pentru a ajunge la „timpul de biți”. Pentru un cititor cu cap dublu, cum ar fi cel pe care îl folosesc, există două piste de date disponibile pentru citire. În acest capitol, voi arăta citirea de pe prima piesă principală pentru a vă începe. Există cinci conexiuni pe care va trebui să le faceți (patru dacă nu vă deranjează să renunțați la un control mai bine reglat pentru mai puține porturi I / O folosite). Vezi imaginea de mai jos. Firul roșu merge la + 5V în timp ce firul negru merge la sol. Firul verde este / CARD_PRESENT; firul galben este / STROBE, iar firul alb este / DATA1. Slash înainte (/) înseamnă că datele sunt inversate. Un semnal scăzut (adică 0) este citit ca unul sau ridicat. Ceilalți conectori sunt maro pentru / STROBE2 și portocaliu pentru / DATA2. Nu le vom folosi. Dacă doriți, puteți uita de / CARD_PRESENT. Această linie de date scade după aproximativ 17 rotații ale fluxului de cap pentru a indica prezența unui card (în loc de, să zicem, zgomot aleatoriu care determină cititorul să trimită date false) și este utilizată pentru a valida faptul că datele pe care le primiți sunt date de card și nu junk. Puteți sări peste această conexiune dacă verificați dacă există sentinela de pornire pe fluxul de date. Mai multe despre asta mai târziu. După cum puteți vedea mai jos, am folosit un antet de sex masculin cu unghi drept conectat la o placă de pâine și mi-am conectat cititorul la acesta. M-am conectat / STROBE la PIND2 (pinul digital 2 pe un Arduino), / CARD_PRESENT la PIND3 (în scop ilustrativ) și / DATA1 la PIND4. Asigurați-vă că activați pullup-urile pe acești ace, astfel încât ace să nu plutească. De asemenea, am schimbat Arduino cu un AVR Bare Bones, deoarece îmi place modul în care se potrivește în panoul de testare.

Pasul 3: Bazele cardurilor magnetice

Bazele cardurilor magnetice
Bazele cardurilor magnetice

Funcțiile principale pe care va trebui să le faceți pentru a citi un card magnetic sunt: 1. Detectați când cardul a fost glisat 2. Citiți fluxul de date 3. Detectați când cardul a dispărut 4. Procesați datele 5. Afișați date În primul rând, vă voi prezenta câteva elemente de bază ale cardului magnetic pe care va trebui să le cunoașteți atunci când începeți să scrieți propriul cod.

Standarde pentru carduri magnetice

Cardurile magnetice sunt standardizate de ISO în următoarele documente: 7810 Caracteristicile fizice ale documentului cu dimensiunea cardului de credit 7811-1 Relief 7811-2 Banda magnetică - coercitivitate redusă 7811-3 Locația caracterelor în relief 7811-4 Locația pieselor 1 și 2 7811- 5 Locația pistei 3 7811-6 Banda magnetică - coercitivitate ridicată 7813 Carduri de tranzacții financiare După cum puteți vedea, cardurile financiare sunt specificate într-un document separat și au adesea formate diferite decât, să zicem, cardul dvs. alimentar sau cardul de apel internațional. Va trebui să programați pentru aceste diferențe. Tocmai am avut la îndemână un card de credit și un card de asigurare, așa că am programat pentru aceste tipuri (ambele fiind formatul B).

Formate de card

Există mai multe formate diferite pentru carduri magnetice. Formatele A și B sunt comune, B fiind cel mai comun pe care l-am văzut și care este acceptat în acest cod. Formatele C până la M sunt rezervate de ISO, cred, în timp ce N până ?? sunt rezervate pentru uz personalizat instituțional. Pista 1 Pentru cardurile financiare, prima pistă este înregistrată la 210 biți pe inch și este prima 0.110 "a cardului din partea de sus. Datele sunt codificate ca" date ale cardului "ca 7 biți pe caracter. Aceasta este 6 biți pentru caracterul și un pic pentru paritate. Există ~ 79 de caractere alfanumerice pe pista 1. Ordinea fizică este inversă. Adică datele sunt scrise înapoi pe card (și, prin urmare, vor fi citite de firmware-ul dvs.) ca. paritatea este ciudată. Formatul de date al cardului arată astfel:

[SS] [FC] [Numărul contului principal] [FS] [Nume] [FS] [Date suplimentare] [FS] [ES] [LRC] unde:

SS Start sentinel FC Format format FS Separator de câmp ES End sentinel LRC Caracter longitudinal Verificare redundanță longitudinală Urmăriți un SS = '%', FC = unul dintre formate (va fi B de multe ori), FS este adesea '', ES este '?' iar caracterul LRC este de obicei „<”, deși nu este specificat în standarde. Pe lângă faptul că sunt scrise pe card înapoi, datele au un bit de paritate ciudat și sunt 0x20 de la ASCII. Ne vom ocupa de acest lucru atunci când procesăm datele. Traseul 2 Traseul doi are o lățime de 0.110 "și pornește 0.110 din partea de sus a cardului. Densitatea de înregistrare este de 75 de biți pe inch. Datele sunt de 5 biți pe caracter și constă numai din aproximativ 40 de simboluri numerice. Nu ar trebui să întâlniți niciunul litere pe această pistă. Formatul datelor cardului trebuie să urmeze această structură

[SS] [cont principal #] [FS] [date suplimentare | date discreționare] [ES] [LRC]

SS pentru pista a doua este punctul și virgula: ';' iar FS este '=' Cu această sfântă cunoaștere sub centură, continuați cu pașii următori pentru a vedea codul care implementează procedura descrisă mai sus.

Pasul 4: Detectați când un card este glisat

Detectați când un card este glisat
Detectați când un card este glisat

1. Detectați când un card a fost glisat formal, se va verifica pinul / CARD_PRESENT pentru a vedea dacă a scăzut. Din fericire, acest lucru nu este cu adevărat necesar. Vom verifica ulterior cardul valabil. Alternativ, ați putea citi pinul stroboscopic pentru a vedea când stroboscopii au fost așezați pe pin, cu toate acestea, acest lucru vă va aduce o mulțime de zero. Cititorul va trimite aproximativ 60-70 zero zero pentru a vă informa că datele sunt pe cale să fie prezentate. Cu toate acestea, vom folosi natura datelor binare pentru a determina când să începem înregistrarea biților. Sentinela de start (SS) pentru prima pistă este semnul procentual (%). Valoarea binară este 0010 0101, ceea ce înseamnă că va fi stocat (și citit) ca 1010 001 (are 7 biți, deci cel de-al 8-lea bit nu este transmis). Acum, cititorul inteligent va observa că, deși datele sunt înapoi, nu se potrivește cu valoarea ASCII binară. Asta pentru că are o reducere de 0x20 din hex. Simbolul% este 0x25 și 0100 0101 este 0x05. Datele cardului au scăzut 0x20 din valoare. Cel care atârnă acolo în ciugulitul înalt este bitul de paritate ciudat. Este pus acolo, astfel încât să existe un număr impar de „1” în valoare. Deci, pentru că știm că un card valid va începe întotdeauna cu această sentinelă de pornire și pentru că bitul de paritate este 1, atunci când detectăm prima tranziție HIGH la LOW pe pinul de date, atunci știm că tocmai am început să primim începe santinela de pe un card. Acum, acest lucru nu va fi întotdeauna adevărat și un plan infailibil ar fi să verificați cardul / CARD_PRESENT pentru a vedea dacă a scăzut în plus. Cel mai simplu mod de a detecta începutul SS-ului este de a crea o întrerupere externă declanșată pe marginea de cădere a / STROBE. Datele sunt valabile 1.0 noi înainte de marginea descendentă, deci atunci când ați eșantionat marginea descendentă, atunci știți că puteți citi pinul / DATA1 și puteți obține o valoare validă. Iată codul pentru a crea întreruperea externă declanșată pe o margine descendentă.

voidInitInterrupt (void) {// Setup interrupt BSET (EIMSK, INT0); // mască de întrerupere externă BSET (EICRA, ISC01); // marginea descendentă BCLR (EICRA, ISC00); // marginea descendentă BSET (SREG, 7); // I-bit în SREG}

În programul meu common.h pe care îl includ în toate programele mele, pot fi găsite definițiile BSET și BCLR. Consultați acel fișier dacă aveți întrebări despre cum să setați biții. Acum, când se declanșează întreruperea, vrem să prelevăm / DATA1 (în codul meu definit ca CARD_DATA) și să setăm un bit într-un registru IO de uz general. Dacă suntem pe cel de-al 7-lea bit, salvați din registru ca un caracter în buffer-ul nostru global. Folosesc un registru GPIOR0, deoarece are acces rapid. Pseudo codul este ceva de genul acesta:

Opriți temporizatorul de 16 biți Ștergeți temporizatorul Dacă DATA este LOW Set BIT = 1 în REGISTR Decrement BIT Setați semnalizatorul, astfel încât să nu mai omitem 0 altele DATA este HIGH Set BIT = 0 în REGISTR Decrement BIT Dacă BIT este 0 Adăugați octeți în buffer Indice de incrementare Resetați BIT

Dacă vă întrebați de ce diminuați în loc de creștere, amintiți-vă că datele sunt înapoi, așa că, în loc să înregistrați biții pe măsură ce îi obținem de la LSB la MSB, îi salvăm de la MSB la LSB, astfel încât nu trebuie să inversăm biții ulterior la prelucrarea datelor. Dacă ați dorit cu adevărat, ați putea adăuga aici și 0x20 hex, dar din moment ce sunt aproximativ 5us pe aceste stroboscopi, mențin procesarea în această rutină de servicii de întrerupere la minimum.

ISR (INT0_vect) {StopTimer (); ClearTimer (); if (! BCHK (PIND, CARD_DATA1)) // invers invers = 1 {BSET (GPIOR0, bit); --pic; bDataPresent = 1; } else if (bDataPresent) {BCLR (GPIOR0, bit); --pic; } if (bit <0) {buff [idx] = (char) GPIOR0; ++ idx; bit = 6; } StartTimer ();} Dacă vă întrebați despre ce este afacerea de sincronizare, aceasta este acoperită în etapa de stabilire a momentului în care cardul a părăsit cititorul.

Pasul 5: Citiți fluxul de date

Citiți fluxul de date

Ei bine, v-am arătat deja cum să citiți datele, deoarece face parte din rutina de servicii de întrerupere pentru întreruperea externă de la marginea de cădere. O metodă alternativă ar fi setarea unui steag în ISR, iar în bucla principală sondează steagul și citește datele în acest fel, dar cred că modul în care l-am prezentat este mai curat. Fii propriul tău judecător și scrie-l pe al tău, oricum MCU-ul tău o va permite. Acestea fiind spuse, să trecem la aflarea modului de detectare a când cardul trage un Elvis și a părăsit clădirea.

Pasul 6: Detectați cardul părăsind cititorul

Detectați cardul părăsind cititorul
Detectați cardul părăsind cititorul

Detectați când un card a dispărut

În mod formal, s-ar preleva pinul / CARD_PRESENT pentru a vedea dacă a trecut din nou la HIGH, dar nu avem nevoie de un steenkin '/ CARD_PRESENT care să ia un alt port I / O. Aici intervin acele temporizatoare. De fiecare dată când este apelată întreruperea deoarece am detectat o margine de cădere pe / STROBE, oprim un temporizator, ștergem valoarea temporizatorului și începem să citim. Când am terminat de citit, pornim din nou cronometrul. Repetați ad nauseum sau până când temporizatorul atinge o anumită valoare. Asta înseamnă că ultima întrerupere a fost apelată și nu au mai intrat date, așa că presupunem că asta este și începem să procesăm datele pe care le-am colectat. Pentru temporizatoare, folosim TIMER1, adică temporizatorul pe 16 biți. Folosesc un rezonator de 16 Mhz extern la AVR-ul meu. Dacă folosești un arduino, atunci probabil că și tu. Deci, am ales o valoare de prescalare de 1024, ceea ce înseamnă de fiecare dată (16, 000, 000/1024) ori crește cronometrul. Adică va „bifa” de 15, 625 de ori pe secundă. / CARD_PRESENT va deveni HIGH indicând faptul că cardul a părăsit cititorul la aproximativ 150 ms după ultimul bit de date. Știind acest lucru, am decis doar să verific aproximativ la fiecare 1/4 de secundă. Ar arăta cam așa:

((((F_CPU) / PRESCALER) / 4) ceea ce se dovedește a fi în jurul valorii de 3900. Deci, când contorul de temporizator TCNT1 ajunge la 3900, atunci știu că au trecut aproximativ 300 ms și pot concluziona destul de sigur că cardul a părăsit cititorul. Uşor

#define PRESCALER 1024 # define CHECK_TIME ((F_CPU / PRESCALER) / 4) // 250 ms # define StartTimer () BSET (TCCR1B, CS10), BSET (TCCR1B, CS12) // 1024 prescaler # define StopTimer () BCLR (TCCR1B, CS10), BCLR (TCCR1B, CS12) #define ClearTimer () (TCNT1 = 0) Ați văzut în ISR unde temporizatorul este pornit, oprit și eliminat la fiecare întrerupere. Acum, în bucla principală, verificăm doar dacă contorul temporizatorului a atins valoarea țintă și, dacă da, începem procesarea datelor

pentru (;;) {if (TCNT1> = CHECK_TIME) {

StopTimer (); ClearTimer (); Procesarea datelor(); ReadData (); idx = 0; bit = 6; bDataPresent = 0; memset (& buff, 0, MAX_BUFF_SZ1); }} Acum este sigur să procesați datele

cod formatat de

Pasul 7: Procesați datele

Procesați datele
Procesați datele

Procesați datele

Faza de procesare constă din:

  • verificarea unui SS valid
  • verificarea parității
  • convertirea la ASCII
  • verificarea unui ES valid
  • verificarea LRC

Aici, nu mă deranjez să verific paritatea, deoarece am setat acel bit la zero. De asemenea, nu calculez LRC pentru acest mic tutorial. Ar fi ceva ce ar putea dori să facă un firmware mai complet realizat. Iată codul pentru a procesa datele făcând pașii de mai sus (fără cele menționate anterior). Găsește-l în imaginea de mai jos. Este comentat și destul de auto-explicativ. O notă specială despre paritate și ASCII: pur și simplu șterg bitul de paritate (al 7-lea bit … adică un 1 cu 6 zerouri în spate) și pentru a converti din „datele cardului” trebuie să adăugați 0x20 la valoare. Cam atât.

Pasul 8: Afișați datele

Afișați datele
Afișați datele
Afișați datele
Afișați datele

Afișați datele

Afișajul merge la un program terminal pe care l-am scris special pentru conectarea la un AVR prin RS232 sau USB. Programul se numește Terminal AVR. Metoda ReadData () este destul de urâtă și sunteți încurajați să găsiți o soluție mai curată decât cea cu care am venit. Există, de asemenea, o ieșire a funcției în terminalul AVR. Rezultatul este primul al unui card de asigurări de sănătate, iar al doilea este al unui card VISA. Faceți clic pe în colțul din stânga sus al imaginii și alegeți imaginea originală sau mare pentru a o vedea mai bine.

Pasul 9: Descărcare cod și încheiere

În acest instructable am discutat câteva elemente de bază ale cititoarelor de carduri magnetice și v-am arătat câteva coduri pentru a vă ajuta să începeți în direcția corectă în citirea datelor de pe cardurile magnetice. Se poate face mult mai multă muncă, cum ar fi citirea și decodarea celei de-a doua piste, calcularea LRC și calcularea parității impare pe fiecare octet. Codul sursă complet este disponibil pentru descărcare mai jos. A fost scris în AVR Studio 4.17. Sper că v-a plăcut acest lucru instructiv și, ca întotdeauna, aștept cu nerăbdare orice comentarii sau sugestii pe care le aveți. Codificare fericită și AVR!

Recomandat: