Sommario:

Trasforma il tuo Arduino in un lettore di schede magnetiche!: 9 passaggi (con immagini)
Trasforma il tuo Arduino in un lettore di schede magnetiche!: 9 passaggi (con immagini)

Video: Trasforma il tuo Arduino in un lettore di schede magnetiche!: 9 passaggi (con immagini)

Video: Trasforma il tuo Arduino in un lettore di schede magnetiche!: 9 passaggi (con immagini)
Video: L’unico video delle medie che abbiamo insieme🤣💕 #miglioriamici #miglioreamica #miglioreamico 2024, Dicembre
Anonim
Trasforma il tuo Arduino in un lettore di schede magnetiche!
Trasforma il tuo Arduino in un lettore di schede magnetiche!
Trasforma il tuo Arduino in un lettore di schede magnetiche!
Trasforma il tuo Arduino in un lettore di schede magnetiche!
Trasforma il tuo Arduino in un lettore di schede magnetiche!
Trasforma il tuo Arduino in un lettore di schede magnetiche!

Tutti hanno usato un lettore di carte magnetiche, credo. Voglio dire, chi porta contanti in questi giorni? Non è nemmeno difficile metterci le mani sopra, e durante un viaggio nel mio negozio di elettronica preferito, ho trovato un cestino pieno di questi ragazzi. Quindi….ovviamente, ne ho preso uno e l'ho portato a casa per vedere che tipo di cose potevo fare con esso e un AVR.

Questa istruzione ti mostrerà come collegare un lettore di carte magnetiche Magtek a un AVR o Arduino/clone e leggere i dati dalla prima traccia della carta. Allacciate i sedili; i lettori di carte magnetiche hanno un bit rate elevato!

Passaggio 1: l'elenco delle attrezzature

L'elenco delle attrezzature
L'elenco delle attrezzature
L'elenco delle attrezzature
L'elenco delle attrezzature

Ecco alcune cose di cui avrai bisogno per iniziare.

  • Lettore di carte magnetiche (il mio è un lettore a doppia testina Magetk da 90 mm. $ 5,00)
  • AVR, Arduino o clone (ATmega328p ~ $ 4,30 da Mouser.com
  • breadboard senza saldatura
  • un po' di filo
  • forse un'intestazione se ti piace quella cosa del genere.
  • qualcosa per leggere la tua porta seriale. Uso il terminale AVR di BattleDroids.net

Questo è tutto ciò di cui hai bisogno per iniziare. A seconda del lettore di schede magnetiche che otterrai, potresti dover modificare queste istruzioni, e sicuramente il codice, per funzionare con il tuo lettore specifico. Tuttavia, il codice che ho scritto dovrebbe portarti abbastanza lontano, spero.

Passaggio 2: lettori di schede magnetiche con sincronizzazione automatica

Lettori di carte magnetiche con autoclocking
Lettori di carte magnetiche con autoclocking
Lettori di carte magnetiche con autoclocking
Lettori di carte magnetiche con autoclocking
Lettori di carte magnetiche con autoclocking
Lettori di carte magnetiche con autoclocking
Lettori di carte magnetiche con autoclocking
Lettori di carte magnetiche con autoclocking

I lettori di carte magnetiche sono "auto-clocking", nel senso che forniscono un orologio chiamato strobo, contro il quale il microcontrollore collegato può sincronizzarsi. Questo è un vantaggio. Significa che non devi preoccuparti di cercare un segnale di clock e di cronometrare il segnale per centrarlo direttamente sull'impulso di clock e nessuna fastidiosa oscillazione nel punto debole del segnale di clock. Questo ha senso quando si pensa allo scorrimento delle carte: tutti passano a un ritmo diverso, alcuni più lenti, altri più veloci di altri. L'autoscatto consente anche alla mia dolce nonna di usare la sua carta senza rompersi il polso. Mi ricorda di dover modificare per lei l'impostazione che determina quanto tempo è valido tra i clic per registrare un doppio clic….

I dati di questo lettore di schede sono validi 1.0 us prima che lo strobo sia messo sulla linea, quindi non c'è da preoccuparsi di ritardare per entrare nel "tempo di bit". Per un lettore a doppia testa come quello che sto usando, sono disponibili due tracce di dati da leggere. In questo 'ble, mostrerò la lettura della prima traccia primaria per iniziare. Ci sono cinque connessioni che dovrai effettuare (quattro se non ti dispiace rinunciare a un controllo più preciso per un minor numero di porte I/O utilizzate). Dai un'occhiata alla figura sotto. Il filo rosso va a +5V mentre il filo nero va a massa. Il filo verde è /CARD_PRESENT; il filo giallo è /STROBE e il filo bianco è /DATA1. La barra (/) indica che i dati sono invertiti. Un segnale basso (cioè 0) viene letto come uno, o alto. Gli altri connettori sono marroni per /STROBE2 e arancioni per /DATA2. Non li useremo. Se vuoi, puoi dimenticare /CARD_PRESENT. Questa linea dati si abbassa dopo circa 17 rotazioni del flusso della testina per indicare che è presente una carta (invece, ad esempio, di un rumore casuale che fa sì che il lettore invii dati fasulli) e viene utilizzata per convalidare che i dati che stai ricevendo sono dati della carta e non spazzatura. Puoi saltare questa connessione se controlli la sentinella di avvio sul flusso di dati. Più su quello più tardi. Come puoi vedere di seguito, ho usato un'intestazione maschio ad angolo retto collegata a una breadboard e ho collegato il mio lettore a quella. Ho collegato /STROBE a PIND2 (pin digitale 2 su un Arduino), /CARD_PRESENT a PIND3 (a scopo illustrativo) e /DATA1 a PIND4. Assicurati di abilitare i pullup su questi pin in modo che i tuoi pin non galleggino. Ho anche scambiato il mio Arduino con un AVR Bare Bones perché mi piace il modo in cui si inserisce nella breadboard.

Passaggio 3: nozioni di base sulle carte magnetiche

Nozioni di base sulle carte magnetiche
Nozioni di base sulle carte magnetiche

Le funzioni principali che dovrai svolgere per leggere una carta magnetica sono: 1. Rileva quando la carta è stata strisciata 2. Leggi il flusso di dati 3. Rileva quando la carta è andata 4. Elabora i dati 5. Visualizza il dati Per prima cosa, ti presenterò alcune nozioni di base sulle carte magnetiche che dovrai conoscere quando inizi a scrivere il tuo codice.

Standard per carte magnetiche

Le carte magnetiche sono standardizzate dall'ISO nei seguenti documenti: 7810 Caratteristiche fisiche del documento formato carta di credito 7811-1 Goffratura 7811-2 Banda magnetica - bassa coercitività 7811-3 Posizione dei caratteri in rilievo 7811-4 Posizione delle tracce 1 e 2 7811- 5 Posizione del binario 3 7811-6 Banda magnetica - alta coercitività 7813 Carte per transazioni finanziarie Come puoi vedere, le carte finanziarie sono specificate in un documento separato e spesso hanno formati diversi rispetto, ad esempio, alla tua carta della spesa o alla carta telefonica internazionale. Dovrai programmare per queste differenze. Avevo solo una carta di credito e una tessera assicurativa a portata di mano, quindi ho programmato per questi tipi (che sono entrambi di formato B).

Formati delle carte

Esistono diversi formati per le carte magnetiche. I formati A e B sono comuni, con B che è il più comune che ho visto e che è supportato in questo codice. I formati da C a M sono riservati dall'ISO, credo, mentre da N a ?? sono riservati all'uso consuetudinario istituzionale. Traccia 1 Per le carte finanziarie, la prima traccia viene registrata a 210 bit per pollice ed è il primo 0,110" della carta dall'alto. I dati sono codificati come "dati della carta" a 7 bit per carattere. Sono 6 bit per il carattere e un bit per la parità. Ci sono ~ 79 caratteri alfanumerici sulla traccia 1. L'ordine fisico è all'indietro. Cioè, i dati sono ma sono scritti all'indietro sulla scheda (e quindi verranno letti dal firmware) come. Il la parità è dispari. Il formato dei dati della carta è simile a questo:

[SS] [FC] [Conto principale n.] [FS] [Nome] [FS] [Dati aggiuntivi] [FS][ES][LRC]dove:

SS Start sentinel FC Codice formato FS Separatore di campo ES End sentinel LRC Longitudinal Redundancy Check character Traccia uno SS = '%', FC = uno dei formati (sarà B molte volte), FS è spesso '', ES è '?' e il carattere LRC è comunemente '<' sebbene non sia specificato negli standard. Oltre ad essere scritti sulla scheda a ritroso, i dati hanno un bit di parità dispari ed è 0x20 da ASCII. Ce ne occuperemo quando elaboreremo i dati. Traccia 2 La traccia due è larga 0,110" e inizia a 0,110 dalla parte superiore della scheda. La densità di registrazione è di 75 bit per pollice. I dati sono 5 bit per carattere e consistono solo di circa 40 simboli numerici. Non dovresti incontrarne nessuno lettere su questa traccia. Il formato dei dati della carta dovrebbe seguire questa struttura

[SS] [conto primario n.] [FS] [dati aggiuntivi | dati discrezionali] [ES] [LRC]

La SS per la traccia due è il punto e virgola: ';' e il FS è '=' Con questa sacra conoscenza alle spalle, continua con i passaggi successivi per vedere il codice che implementa la procedura sopra descritta.

Passaggio 4: rilevare quando viene strisciata una carta

Rileva quando una carta viene strisciata
Rileva quando una carta viene strisciata

1. Rileva quando una carta è stata strisciata Formalmente, si dovrebbe controllare il pin /CARD_PRESENT per vedere se è sceso in basso. Fortunatamente, questo non è davvero necessario. Controlleremo la carta valida più tardi. In alternativa, puoi leggere il tuo pin stroboscopico per vedere quando i flash sono stati inseriti sul pin, tuttavia, questo ti farà guadagnare molti zeri di clock. Il lettore invierà circa 60-70 zeri iniziali per farti sapere che i dati stanno per essere presentati. Tuttavia, useremo la natura dei dati binari per determinare quando iniziare a registrare i bit. La sentinella di partenza (SS) per la pista uno è il segno di percentuale (%). Il suo valore binario è 0010 0101, il che significa che verrà memorizzato (e letto) come 1010 001 (è a 7 bit, quindi l'ottavo bit non viene trasmesso). Ora, il lettore attento noterà che anche se i dati sono al contrario, non corrispondono al valore ASCII binario. Questo perché è 0x20 fuori dall'esagono. Il simbolo % è 0x25 e 0100 0101 è 0x05. I dati della carta hanno 0x20 sottratto dal valore. Quello appeso là fuori nel bocconcino alto è lo strano bit di parità. È messo lì in modo che ci sia un numero dispari di "1" nel valore. Quindi, poiché sappiamo che una carta valida inizierà sempre con questa sentinella di avvio e poiché il bit di parità è un 1, quando rileviamo la prima transizione da HIGH a LOW sul pin dei dati, allora sappiamo che abbiamo appena iniziato a ricevere il avviare sentinella da una carta. Ora, questo non sarà sempre vero, e un piano infallibile sarebbe quello di controllare la scheda /CARD_PRESENT per vedere se è anche LOW. Il modo più semplice per rilevare l'inizio di SS è creare un interrupt esterno attivato sul fronte di discesa di /STROBE. I dati sono validi 1.0 us prima del fronte di discesa, quindi quando hai campionato il fronte di discesa, allora sai che puoi leggere il pin /DATA1 e ottenere un valore valido. Ecco il codice per creare il tuo interrupt esterno attivato su un fronte di discesa.

voidInitInterrupt(void){ // Setup interrupt BSET(EIMSK, INT0); // maschera di interruzione esterna BSET(EICRA, ISC01); // fronte di discesa BCLR(EICRA, ISC00); // fronte di discesa BSET(SREG, 7); // I-bit in SREG}

Nel mio common.h che includo in tutti i miei programmi, si possono trovare le definizioni di BSET e BCLR. Fare riferimento a quel file in caso di domande su come impostare i bit. Ora, quando viene attivato l'interrupt, vogliamo campionare /DATA1 (nel mio codice definito come CARD_DATA) e impostare un bit in un registro IO generico. Se siamo al settimo bit, salva il registro come carattere nel nostro buffer globale. Uso un registro GPIOR0 perché è un accesso veloce e spiffy. Lo pseudo codice è qualcosa del genere:

Arresta il timer a 16 bit Azzera il timer Se DATA è BASSO Imposta BIT=1 in REGISTER Decrementa BIT Imposta flag in modo da non saltare più 0 altrimenti DATA è ALTO Imposta BIT=0 in REGISTER Decrementa BIT Se BIT è 0 Aggiungi byte al buffer Incrementa indice Reset BIT

Se ti stai chiedendo perché decrementa invece di incrementare, ricorda che i dati sono all'indietro, quindi invece di registrare i bit man mano che li otteniamo da LSB a MSB, li salviamo da MSB a LSB in modo da non dover invertire i bit successivamente durante il trattamento dei dati. Se lo volessi davvero, potresti anche aggiungere 0x20 esadecimale qui, ma poiché sono circa 5us su questi flash, sto mantenendo l'elaborazione in questa routine di servizio di interruzione al minimo.

ISR(INT0_vect){ StopTimer(); ClearTimer(); if (!BCHK(PIND, CARD_DATA1)) // inverso basso = 1 { BSET(GPIOR0, bit); --po; bDataPresent = 1; } else if (bDataPresent) { BCLR(GPIOR0, bit); --po; } if (bit < 0) { buff[idx] = (char)GPIOR0; ++idx; bit = 6; } StartTimer();} Se ti stai chiedendo di cosa tratta l'attività di cronometraggio, questo è trattato nel passaggio per determinare quando la carta ha lasciato il lettore.

Passaggio 5: leggere il flusso di dati

Leggi il flusso di dati

Bene, ti ho già mostrato come leggere i dati, poiché fa parte della routine del servizio di interrupt per il nostro interrupt esterno sul fronte di discesa. Un metodo alternativo sarebbe quello di impostare un flag nell'ISR e nel ciclo principale interrogare il flag e leggere i dati in questo modo, ma credo che il modo in cui l'ho presentato sia più pulito. Sii il giudice di te stesso e scrivi il tuo comunque il tuo MCU lo consentirà. Detto questo, passiamo a scoprire come rilevare quando la carta prende un Elvis e ha lasciato l'edificio.

Passaggio 6: rilevare la carta che lascia il lettore

Rileva la carta che lascia il lettore
Rileva la carta che lascia il lettore

Rileva quando una carta è andata

Formalmente, si dovrebbe campionare il pin /CARD_PRESENT per vedere se è diventato di nuovo HIGH, ma non è necessario che /CARD_PRESENT occupi un'altra porta I/O. È qui che entrano in gioco quei timer. Ogni volta che viene chiamato l'interrupt perché abbiamo rilevato un fronte di discesa su /STROBE, fermiamo un timer, cancelliamo il valore del timer e iniziamo a leggere. Quando abbiamo finito di leggere, avviamo di nuovo il timer. Ripeti fino alla nausea o finché il timer non raggiunge un certo valore. Ciò significa che è stato chiamato l'ultimo interrupt e non sono stati ricevuti altri dati, quindi supponiamo che sia così e iniziamo a elaborare i dati che abbiamo raccolto. Per i timer utilizziamo TIMER1, ovvero il timer a 16 bit. Sto usando un risonatore da 16 Mhz esternamente al mio AVR. Se stai usando un arduino, probabilmente lo sei anche tu. Quindi, ho scelto un valore di prescaler di 1024 che significa che ogni (16, 000, 000 / 1024) volte il timer aumenterà. Vale a dire, "ticcherà" 15, 625 volte al secondo. Il /CARD_PRESENT diventerà HIGH indicando che la carta ha lasciato il lettore circa 150 ms dopo l'ultimo bit di dati. Sapendo questo, ho deciso di controllare circa ogni 1/4 di secondo. Sarebbe simile a questo:

(((F_CPU) / PRESCALER) / 4) che risulta essere circa 3900. Quindi, quando il contatore del timer TCNT1 raggiunge 3900, allora so che sono passati circa 300 ms e posso tranquillamente concludere che la carta ha lasciato il lettore. Facile

#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) Hai visto nell'ISR dove il timer viene avviato, fermato e cancellato ad ogni interruzione. Ora, nel ciclo principale, controlliamo solo se il contatore del timer ha raggiunto il nostro valore target e, in tal caso, avviamo l'elaborazione dei dati

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

StopTimer(); ClearTimer(); Dati di processo(); LeggiDati(); idx = 0; bit = 6; bDataPresent = 0; memset(&buff, 0, MAX_BUFF_SZ1); } } Ora è sicuro elaborare i dati

codice formattato da

Passaggio 7: elaborare i dati

Elaborare i dati
Elaborare i dati

Elabora i dati

La fase di lavorazione consiste in:

  • verifica di un SS. valido
  • controllo della parità
  • conversione in ASCII
  • verifica di un ES valid valido
  • controllando LRC

Qui, non mi preoccupo di controllare la parità, poiché ho appena impostato quel bit su zero. Inoltre non calcolo l'LRC per questo piccolo tutorial. Sarebbe qualcosa che un firmware più completo potrebbe voler fare. Ecco il codice per elaborare i dati facendo i passaggi precedenti (senza quelli menzionati in precedenza). Lo trovi nell'immagine qui sotto. È commentato e abbastanza autoesplicativo. Una nota speciale su parità e ASCII: ho semplicemente azzerato il bit di parità (7° bit…cioè un 1 con 6 zeri dietro) e per convertire da "dati della carta" devi aggiungere 0x20 al valore. Questo è tutto.

Passaggio 8: visualizzare i dati

Visualizza i dati
Visualizza i dati
Visualizza i dati
Visualizza i dati

Visualizza i dati

Il display va a un programma terminale che ho scritto appositamente per il collegamento a un AVR tramite RS232 o USB. Il programma si chiama AVR Terminal. Il metodo ReadData() è piuttosto brutto e sei incoraggiato a trovare una soluzione più pulita di quella che ho trovato. C'è anche un output della funzione in AVR Terminal. L'uscita è la prima di una tessera sanitaria e la seconda di una carta VISA. Fare clic su nell'angolo in alto a sinistra dell'immagine e scegliere l'immagine originale o grande per vederla meglio.

Passaggio 9: download del codice e riepilogo

In questo tutorial ho discusso alcune nozioni di base sui lettori di carte magnetiche e ti ho mostrato del codice per iniziare nella giusta direzione nella lettura dei dati dalle carte magnetiche. C'è molto altro lavoro che potrebbe essere fatto, come leggere e decodificare la seconda traccia, calcolare l'LRC e calcolare la parità dispari su ciascun byte. Il codice sorgente completo è disponibile per il download di seguito. È stato scritto in AVR Studio 4.17. Spero che questo tutorial ti sia piaciuto e, come sempre, non vedo l'ora di ricevere commenti o suggerimenti. Buon codice e AVR'ing!

Consigliato: