Indholdsfortegnelse:

Gør din Arduino til en magnetisk kortlæser !: 9 trin (med billeder)
Gør din Arduino til en magnetisk kortlæser !: 9 trin (med billeder)

Video: Gør din Arduino til en magnetisk kortlæser !: 9 trin (med billeder)

Video: Gør din Arduino til en magnetisk kortlæser !: 9 trin (med billeder)
Video: Amazon Dimser November 2023 - Nice to have & Need to have :-) 2024, Juli
Anonim
Gør din Arduino til en magnetisk kortlæser!
Gør din Arduino til en magnetisk kortlæser!
Gør din Arduino til en magnetisk kortlæser!
Gør din Arduino til en magnetisk kortlæser!
Gør din Arduino til en magnetisk kortlæser!
Gør din Arduino til en magnetisk kortlæser!

Alle har brugt en magnetisk kortlæser, tror jeg. Jeg mener, hvem bærer kontanter i disse dage? De er heller ikke svære at få fat i, og under en tur til min foretrukne lokale elektronikbutik fandt jeg en skraldespand fuld af disse fyre. Så…. Selvfølgelig hentede jeg en og tog den med hjem for at se, hvad jeg kunne gøre med den og en AVR.

Denne instruktør viser dig, hvordan du tilslutter en Magtek magnetisk kortlæser til en AVR eller Arduino/klon og læser data fra det første kortspor. Spænde dine sæder; magnetiske kortlæsere har en høj bithastighed!

Trin 1: Udstyrslisten

Udstyrslisten
Udstyrslisten
Udstyrslisten
Udstyrslisten

Her er et par ting, du skal bruge for at komme i gang.

  • Magnetisk kortlæser (Mine er en Magetk 90 mm dual-head læser. $ 5,00)
  • AVR, Arduino eller klon (ATmega328p ~ $ 4,30 fra Mouser.com
  • loddet brødbræt
  • noget ledning
  • måske en header, hvis du kan lide sådan noget.
  • noget at læse din serielle port. Jeg bruger AVR Terminal fra BattleDroids.net

Det er alt, hvad du skal bruge for at komme i gang. Afhængigt af den magcard -læser, du ender med at få, skal du muligvis ændre disse instruktioner og mest sikkert koden for at arbejde med din specifikke læser. Men den kode, jeg har skrevet, skulle komme dig ret langt, håber jeg.

Trin 2: Selvklokkende magnetiske kortlæsere

Selvklokkende magnetiske kortlæsere
Selvklokkende magnetiske kortlæsere
Selvklokkende magnetiske kortlæsere
Selvklokkende magnetiske kortlæsere
Selvklokkende magnetiske kortlæsere
Selvklokkende magnetiske kortlæsere
Selvklokkende magnetiske kortlæsere
Selvklokkende magnetiske kortlæsere

Magnetiske kortlæsere er "selv-clocking", hvilket betyder, at de leverer et ur kaldet en strobe, mod hvilken den tilsluttede mikrokontroller kan synkronisere. Dette er en velsignelse. Det betyder, at du ikke behøver at bekymre dig om at lede efter et uresignal og timing af signalet til at centrere direkte på urpulsen, og ingen generende oscillerende ind i urets signalets søde plet. Dette giver mening, når du tænker på kortstrygninger: alle stryger i et andet tempo, nogle langsommere, nogle hurtigere end andre. Selvklokning giver selv min søde mormor mulighed for at bruge sit kort uden at bryde hendes håndled. Minder mig om at skulle ændre den indstilling for hende, der bestemmer, hvor lang tid der er gyldig mellem klik for at registrere et dobbeltklik….

Denne kortlæsers data er gyldige 1,0 os, før stroben sættes på linjen, så der er ingen bekymring om at forsinke at komme ind i "bit -tiden". For en dual head -læser som den, jeg bruger, er der to dataspor tilgængelige til læsning. I denne artikel vil jeg vise læsning fra det primære første nummer for at komme i gang. Der er fem forbindelser, du skal lave (fire hvis du ikke har noget imod at opgive mere finjusteret kontrol for færre I/O -porte, der bruges). Tjek billedet herunder. Den røde ledning går til +5V, mens den sorte ledning går til jorden. Den grønne ledning er /CARD_PRESENT; den gule ledning er /STROBE, og den hvide ledning er /DATA1. Fremad skråstreg (/) betyder, at dataene er omvendt. Et lavt signal (dvs. 0) læses som et eller højt. De andre stik er brune til /STROBE2 og orange til /DATA2. Vi vil ikke bruge disse. Hvis du vil, kan du glemme alt om /CARD_PRESENT. Denne datalinje går lavt efter ca. 17 hovedfluxrotationer for at indikere, at der er et kort (i stedet for f.eks. Tilfældig støj, der får din læser til at sende falske data) og bruges til at validere, at de data, du får, er kortdata og ikke uønsket. Du kan springe denne forbindelse over, hvis du søger efter startvagten i datastrømmen. Mere om det senere. Som du kan se nedenfor, brugte jeg en retvinklet mandlig header forbundet til et brødbræt og sluttede min læser til det. Jeg tilsluttede /STROBE til PIND2 (digital pin 2 på en Arduino), /CARD_PRESENT til PIND3 (til illustration) og /DATA1 til PIND4. Sørg for at aktivere pullups på disse pins, så dine pins ikke flyder. Jeg byttede også min Arduino ud for en Bare Bones AVR, fordi jeg kan lide den måde, den passer ind i brødbrættet.

Trin 3: Grundlæggende om magnetisk kort

Grundlæggende om magnetisk kort
Grundlæggende om magnetisk kort

De primære funktioner, du skal gøre for at læse et magnetisk kort, er: 1. Registrer, hvornår kortet er blevet skubbet 2. Læs datastrømmen 3. Opdag, når kortet er gået 4. Behandl dataene 5. Vis data Først vil jeg introducere dig til nogle grundlæggende magnetiske kort, som du skal vide, når du begynder at skrive din egen kode.

Magnetiske kortstandarder

Magnetkort er standardiseret af ISO i følgende dokumenter: 7810 Fysiske egenskaber ved kreditkortstørrelsesdokument 7811-1 Prægning 7811-2 Magnetstribe-lav koercivitet 7811-3 Placering af prægede tegn 7811-4 Placering af spor 1 & 2 7811- 5 Placering af spor 3 7811-6 Magnetstribe - høj coercivity 7813 Finansielle transaktionskort Som du kan se, er finansielle kort angivet i et separat dokument og har ofte andre formater end f.eks. Dit købmandskort eller internationale telefonkort. Du bliver nødt til at programmere for disse forskelle. Jeg havde lige et kreditkort og forsikringskort ved hånden, så jeg programmerede til disse typer (som begge tilfældigvis er format B).

Kortformater

Der er flere forskellige formater til magnetkort. Format A og B er almindelige, idet B er det mest almindelige, jeg har set, og som understøttes i denne kode. Formaterne C til og med M er forbeholdt ISO, tror jeg, mens N til ?? er forbeholdt institutionel brug. Spor 1 For finansielle kort registreres det første spor med 210 bits pr. Tomme og er det første 0.110 "af kortet fra toppen. Dataene er kodet som" kortdata "som 7-bit pr. Tegn. Det er 6-bits for karakteren og lidt for paritet. Der er ~ 79 alfanumeriske tegn på spor 1. Den fysiske rækkefølge er baglæns. Det vil sige, at data er, men det er skrevet baglæns på kortet (og derfor vil blive læst af din firmware) som. paritet er ulige. Kortdataformatet ser sådan ud:

[SS] [FC] [Primær konto #] [FS] [Navn] [FS] [Yderligere data] [FS] [ES] [LRC] hvor:

SS Startvagtpost FC Formatkode FS Feltudskiller ES Slutvagtpost LRC Langsgående redundans Kontroller tegn Spor en SS = '%', FC = et af formaterne (vil være B mange gange), FS er ofte '', ES er '?' og LRC -tegnet er normalt '<', selvom det ikke er specificeret i standarderne. Udover at blive skrevet på kortet bagud, har dataene en ulige paritetsbit og er 0x20 fra ASCII. Vi håndterer dette, når vi behandler dataene. Spor 2 Spor to er 0.110 "bred og starter 0.110 fra toppen af kortet. Dens optagelsestæthed er 75 bit pr. Tomme. Dataene er 5-bit pr. Tegn og består kun af omkring 40 numeriske symboler. Du bør ikke støde på nogen bogstaver på dette spor. Kortdataformatet skal følge denne struktur

[SS] [primær konto #] [FS] [yderligere data | skønsmæssige data] [ES] [LRC]

SS for spor to er semikolon: ';' og FS er '=' Med denne hellige viden under dit bælte, skal du fortsætte til de næste trin for at se kode, der implementerer proceduren beskrevet ovenfor.

Trin 4: Find, når et kort er skubbet

Find, når et kort er skubbet
Find, når et kort er skubbet

1. Find, når et kort er blevet skubbet Formelt ville man kontrollere /CARD_PRESENT -stiften for at se, om det er faldet lavt. Heldigvis er dette ikke virkelig nødvendigt. Vi kontrollerer senere, om det er gyldigt kort. Alternativt kan du læse din strobe -pin for at se, når der er sat strober på stiften, men dette vil give dig masser af clock -zero'er. Læseren sender omkring 60-70 førende nuller for at fortælle dig, at data er ved at blive præsenteret. Imidlertid vil vi bruge arten af binære data til at bestemme, hvornår vi skal begynde at optage bits. Startvagten (SS) for spor et er procenttegnet (%). Den binære værdi er 0010 0101, hvilket betyder, at den vil blive gemt (og læst) som 1010 001 (den er 7-bit, så den 8. bit bliver ikke transmitteret). Nu vil den kloge læser bemærke, at selvom dataene er baglæns, matcher de ikke den binære ASCII -værdi. Det er fordi det er 0x20 fra hex. % -Symbolet er 0x25 og 0100 0101 er 0x05. Kortdata er 0x20 trukket fra værdien. Den der hænger derude i den høje nibble er den ulige paritetsbit. Det sættes der, så der er et ulige antal "1" i værdien. Så fordi vi ved, at et gyldigt kort altid vil starte med denne startvagt, og fordi paritetsbiten er en 1, når vi registrerer den første HIGH til LOW -overgang på datapinden, så ved vi, at vi lige er begyndt at modtage start vagtpost fra et kort. Nu vil dette ikke altid være sandt, og en idiotsikker plan ville være at kontrollere /CARD_PRESENT -kortet for at se, om det er gået LAVT derudover. Den enkleste måde at registrere starten på SS er ved at oprette en ekstern afbrydelse udløst på den faldende kant af /STROBE. Dataene er gyldige 1,0 os før den faldende kant, så når du har samplet den faldende kant, ved du, at du kan læse /DATA1 -stiften og få en gyldig værdi. Her er koden til at oprette din eksterne afbrydelse udløst på en faldende kant.

voidInitInterrupt (void) {// Setup interrupt BSET (EIMSK, INT0); // ekstern afbrydelsesmaske BSET (EICRA, ISC01); // faldende kant BCLR (EICRA, ISC00); // faldende kant BSET (SREG, 7); // I-bit i SREG}

I min common.h, som jeg inkluderer i alle mine programmer, kan definitionerne af BSET og BCLR findes. Se den fil, hvis du har spørgsmål om, hvordan du sætter bits. Nu, når afbrydelsen udløses, vil vi prøve /DATA1 (i min kode defineret som CARD_DATA) og sætte en smule i et IO -register til generelle formål. Hvis vi er på den 7. bit, skal du gemme registret som et tegn i vores globale buffer. Jeg bruger et GPIOR0 -register, fordi det er en hurtig adgang. Pseudokoden er sådan noget:

Stop 16-bit timer Ryd timer Hvis DATA er LAV Indstil BIT = 1 i REGISTER Dekrement BIT Indstil flag, så vi ikke springer flere 0'er over ellers DATA er HØJ Indstil BIT = 0 i REGISTER Sænker BIT Hvis BIT er 0 Tilføj byte til buffer Forøgelsesindeks Nulstil BIT

Hvis du spørger dig selv, hvorfor dekrement i stedet for inkrement, skal du huske, at dataene er baglæns, så i stedet for at registrere bitene, når vi får dem fra LSB til MSB, gemmer vi dem fra MSB til LSB, så vi ikke behøver at vende bitene senere ved behandling af data. Hvis du virkelig ville, kunne du også tilføje 0x20 hex her, men da det er omkring 5us på disse strober, holder jeg behandlingen i denne afbrydelsesrutine til et minimum.

ISR (INT0_vect) {StopTimer (); ClearTimer (); hvis (! BCHK (PIND, CARD_DATA1)) // invers lav = 1 {BSET (GPIOR0, bit); --bit; bDataPresent = 1; } ellers hvis (bDataPresent) {BCLR (GPIOR0, bit); --bit; } hvis (bit <0) {buff [idx] = (char) GPIOR0; ++ idx; bit = 6; } StartTimer ();} Hvis du undrer dig over, hvad timingsforretningen handler om, er det dækket i trin til bestemmelse af, hvornår kortet har forladt læseren.

Trin 5: Læs datastrømmen

Læs datastrømmen

Nå, jeg har allerede vist dig, hvordan du læser dataene, da det er en del af Interrupt Service Routine for vores faldende eksterne afbrydelse. En alternativ metode ville være at sætte et flag i ISR, og i hovedsløjfen afstemme flaget og læse dataene på den måde, men jeg tror, at den måde, jeg har præsenteret det på, er renere. Vær din egen dommer og skriv din, men din MCU tillader det. Når det er sagt, lad os gå videre til at finde ud af, hvordan man opdager, når kortet trækker en Elvis og har forladt bygningen.

Trin 6: Find kortet, der forlader læseren

Find kortet, der forlader læseren
Find kortet, der forlader læseren

Find ud af, hvornår et kort er gået

Formelt ville man prøve /CARD_PRESENT -stiften for at se, om den er gået HIGH igen, men vi har ikke brug for, at ingen steenkin /CARD_PRESENT tager en anden I /O -port. Det er her, disse timere kommer ind. Hver gang afbrydelsen kaldes, fordi vi har registreret en faldende kant på /STROBE, stopper vi en timer, rydder timerværdien og begynder at læse. Når vi er færdige med at læse, starter vi timeren igen. Gentag ad nauseum, eller indtil timeren når en bestemt værdi. Det betyder, at den sidste afbrydelse er blevet kaldt, og der ikke er kommet flere data ind, så vi går ud fra, at det er det og begynder at behandle de data, vi har indsamlet. Til timere bruger vi TIMER1, altså 16-bit timeren. Jeg bruger en 16 Mhz resonator eksternt til min AVR. Hvis du bruger en arduino, er du sandsynligvis også det. Så jeg har valgt en forkalkningsværdi på 1024, hvilket betyder, at hver (16.000, 000 /1024) gange timeren øges. Det vil sige, det vil 'krydse' 15, 625 gange i sekundet. /CARD_PRESENT går HØJ, hvilket angiver, at kortet har forladt læseren cirka 150 ms efter den sidste databit. Da jeg vidste dette, besluttede jeg bare at tjekke hvert 1/4 sekund. Det ville se sådan ud:

((((F_CPU) / PRESCALER) / 4) hvilket viser sig at være omkring 3900. Så når timertælleren TCNT1 når 3900, så ved jeg, at det har været omkring 300 ms, og jeg kan ret sikkert konkludere, at kortet har forladt læseren. Let

#define PRESCALER 1024#definere CHECK_TIME ((F_CPU / PRESCALER) / 4) // 250 ms#definere StartTimer () BSET (TCCR1B, CS10), BSET (TCCR1B, CS12) // 1024 prescaler#definere StopTimer () BCLR (TCCR1B, CS10), BCLR (TCCR1B, CS12) #define ClearTimer () (TCNT1 = 0) Du har set i ISR, hvor timeren startes, stoppes og slettes ved hver afbrydelse. Nu i hovedsløjfen tjekker vi bare for at se, om timertælleren har nået vores målværdi, og start i så fald databehandlingen

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

StopTimer (); ClearTimer (); ProcessData (); ReadData (); idx = 0; bit = 6; bDataPresent = 0; memset (& buff, 0, MAX_BUFF_SZ1); }} Nu er det sikkert at behandle dataene

kode formateret af

Trin 7: Behandl dataene

Behandl dataene
Behandl dataene

Behandl dataene

Behandlingsfasen består af:

  • søger efter en gyldig SS
  • kontrollere paritet
  • konvertering til ASCII
  • søger efter et gyldigt ES
  • kontrol af LRC

Her gider jeg ikke tjekke paritet, da jeg lige satte den bit til nul. Jeg beregner heller ikke LRC for denne lille tutorial. Det ville være noget, som en mere fuldt realiseret firmware måske vil gøre. Her er koden til at behandle dataene ved at udføre ovenstående trin (sans de tidligere nævnte). Find det på billedet herunder. Det er kommenteret og ret selvforklarende. En særlig note om paritet og ASCII: Jeg rydder simpelthen paritetsbitten (7. bit … dvs. en 1 med 6 nuller bagved) og for at konvertere fra "kortdata" skal du tilføje 0x20 til værdien. Det handler om det.

Trin 8: Vis dataene

Vis dataene
Vis dataene
Vis dataene
Vis dataene

Vis dataene

Displayet går til et terminalprogram, jeg skrev specielt til tilslutning til en AVR via RS232 eller USB. Programmet kaldes AVR Terminal. ReadData () -metoden er temmelig grim, og du opfordres til at finde en renere løsning end den, jeg fandt på. Der er også et output af funktionen i AVR Terminal. Output er først af et sygesikringskort, og det andet er af et VISA -kort. Klik på i øverste venstre hjørne af billedet, og vælg det originale eller store billede for at se det bedre.

Trin 9: Download og pakning af kode

I denne instruktive har jeg diskuteret nogle grundlæggende principper for magnetkortlæsere og vist dig en kode for at komme i gang i den rigtige retning med at læse data fra magnetkort. Der er meget mere arbejde, der kan udføres, såsom at læse og afkode 2. spor, beregne LRC og beregne ulige paritet på hver byte. Den fulde kildekode kan downloades herunder. Det blev skrevet i AVR Studio 4.17. Jeg håber, at du har nydt dette instruerbare, og som altid glæder jeg mig til eventuelle kommentarer eller forslag, du måtte have. Glædelig kodning og AVR'ing!

Anbefalede: