Tabla de contenido:

¡Convierta su Arduino en un lector de tarjetas magnéticas !: 9 pasos (con imágenes)
¡Convierta su Arduino en un lector de tarjetas magnéticas !: 9 pasos (con imágenes)

Video: ¡Convierta su Arduino en un lector de tarjetas magnéticas !: 9 pasos (con imágenes)

Video: ¡Convierta su Arduino en un lector de tarjetas magnéticas !: 9 pasos (con imágenes)
Video: 34 Curso Arduino - RFID RC522 - 1/2 - Introducción y Verificación 2024, Mes de julio
Anonim
¡Convierta su Arduino en un lector de tarjetas magnéticas!
¡Convierta su Arduino en un lector de tarjetas magnéticas!
¡Convierta su Arduino en un lector de tarjetas magnéticas!
¡Convierta su Arduino en un lector de tarjetas magnéticas!
¡Convierta su Arduino en un lector de tarjetas magnéticas!
¡Convierta su Arduino en un lector de tarjetas magnéticas!

Todo el mundo ha utilizado un lector de tarjetas magnéticas, creo. Quiero decir, ¿quién lleva dinero en efectivo estos días? Tampoco es difícil conseguirlos, y durante un viaje a mi tienda de electrónica local favorita, encontré una papelera llena de estos tipos. Así que … por supuesto, tomé uno y lo traje a casa para ver qué tipo de cosas podía hacer con él y un AVR.

Este instructivo le mostrará cómo conectar un lector de tarjetas magnéticas Magtek a un AVR o Arduino / clon y leer los datos de la primera pista de la tarjeta. Abroche sus asientos; ¡Los lectores de tarjetas magnéticas tienen una alta tasa de bits!

Paso 1: la lista de equipos

La lista de equipos
La lista de equipos
La lista de equipos
La lista de equipos

Aquí hay algunas cosas que necesitará para comenzar.

  • Lector de tarjetas magnéticas (el mío es un lector de doble cabezal Magetk de 90 mm. $ 5.00)
  • AVR, Arduino o clon (ATmega328p ~ $ 4.30 de Mouser.com
  • tablero sin soldadura
  • algo de alambre
  • tal vez un encabezado si te gusta esa cosa.
  • algo para leer su puerto serie. Utilizo AVR Terminal de BattleDroids.net

Eso es todo lo que necesita para empezar. Dependiendo del lector de tarjetas magnéticas que obtenga, es posible que deba modificar estas instrucciones, y seguramente el código, para trabajar con su lector específico. Sin embargo, espero que el código que he escrito te lleve bastante lejos.

Paso 2: Lectores de tarjetas magnéticas con reloj automático

Lectores de tarjetas magnéticas con reloj automático
Lectores de tarjetas magnéticas con reloj automático
Lectores de tarjetas magnéticas con reloj automático
Lectores de tarjetas magnéticas con reloj automático
Lectores de tarjetas magnéticas con reloj automático
Lectores de tarjetas magnéticas con reloj automático
Lectores de tarjetas magnéticas con reloj automático
Lectores de tarjetas magnéticas con reloj automático

Los lectores de tarjetas magnéticas tienen "reloj automático", lo que significa que proporcionan un reloj llamado estroboscópico, contra el cual el microcontrolador conectado puede sincronizarse. Esto es una bendición. Significa que no tiene que preocuparse por buscar una señal de reloj y sincronizar la señal para centrarse directamente en el pulso del reloj, y sin molestos oscilaciones en el punto óptimo de la señal del reloj. Esto tiene sentido cuando piensa en deslizamientos de tarjetas: todos deslizan a un ritmo diferente, algunos más lento, algunos más rápido que otros. El reloj automático permite que incluso mi dulce abuela pueda usar su tarjeta sin romperse la muñeca. Me recuerda que tengo que cambiarle la configuración que determina cuánto tiempo es válido entre clics para registrar un doble clic….

Los datos de este lector de tarjetas son válidos 1.0 us antes de que se ponga la luz estroboscópica en la línea, por lo que no hay que preocuparse por demorarse para entrar en el "tiempo de bits". Para un lector de doble cabezal como el que estoy usando, hay dos pistas de datos disponibles para leer. En esta 'ible, voy a mostrar la lectura de la primera pista principal para que pueda comenzar. Hay cinco conexiones que deberá realizar (cuatro si no le importa renunciar a un control más preciso para que se utilicen menos puertos de E / S). Echa un vistazo a la siguiente imagen. El cable rojo va a + 5V mientras que el cable negro va a tierra. El cable verde es / CARD_PRESENT; el cable amarillo es / STROBE y el cable blanco es / DATA1. La barra inclinada (/) significa que los datos están invertidos. Una señal baja (es decir, 0) se lee como uno o alta. Los otros conectores son de color marrón para / STROBE2 y naranja para / DATA2. No los usaremos. Si lo desea, puede olvidarse de / CARD_PRESENT. Esta línea de datos baja después de aproximadamente 17 rotaciones de flujo de cabeza para indicar que hay una tarjeta presente (en lugar de, digamos, ruido aleatorio que hace que su lector envíe datos falsos) y se usa para validar que los datos que está obteniendo son datos de tarjeta y no basura. Puede omitir esta conexión si busca el centinela de inicio en el flujo de datos. Más sobre eso más tarde. Como puede ver a continuación, utilicé un encabezado macho en ángulo recto conectado a una placa de pruebas y conecté mi lector a eso. Conecté / STROBE a PIND2 (pin digital 2 en un Arduino), / CARD_PRESENT a PIND3 (con fines ilustrativos) y / DATA1 a PIND4. Asegúrate de habilitar las dominadas en estos pines para que tus pines no floten. También cambié mi Arduino por un AVR Bare Bones porque me gusta la forma en que encaja en la placa de pruebas.

Paso 3: Conceptos básicos de la tarjeta magnética

Conceptos básicos de la tarjeta magnética
Conceptos básicos de la tarjeta magnética

Las funciones principales que deberá realizar para leer una tarjeta magnética son: 1. Detectar cuándo se ha deslizado la tarjeta 2. Leer el flujo de datos 3. Detectar cuándo se ha agotado la tarjeta 4. Procesar los datos 5. Mostrar el data Primero, le presentaré algunos conceptos básicos de las tarjetas magnéticas que necesitará saber cuando comience a escribir su propio código.

Estándares de tarjetas magnéticas

Las tarjetas magnéticas están estandarizadas por la ISO en los siguientes documentos: 7810 Características físicas del documento del tamaño de una tarjeta de crédito 7811-1 Gofrado 7811-2 Banda magnética - baja coercitividad 7811-3 Ubicación de los caracteres en relieve 7811-4 Ubicación de las pistas 1 y 2 7811- 5 Ubicación de la vía 3 7811-6 Banda magnética: alta coercitividad 7813 Tarjetas de transacciones financieras Como puede ver, las tarjetas financieras se especifican en un documento separado y, a menudo, tienen formatos diferentes a, por ejemplo, su tarjeta de supermercado o su tarjeta de llamadas internacionales. Tendrá que programar para estas diferencias. Acabo de tener una tarjeta de crédito y una tarjeta de seguro a la mano, así que programé para estos tipos (que resultan ser ambos en formato B).

Formatos de tarjeta

Existen varios formatos diferentes para tarjetas magnéticas. Los formatos A y B son comunes, siendo B el más común que he visto y que es compatible con este código. Los formatos C a M están reservados por ISO, creo, mientras que N a ?? están reservados para uso institucional personalizado. Pista 1 Para las tarjetas financieras, la primera pista se graba a 210 bits por pulgada y es el primer 0,110 "de la tarjeta desde la parte superior. Los datos se codifican como" datos de la tarjeta "como 7 bits por carácter. Eso es 6 bits para el carácter y un poco para la paridad. Hay ~ 79 caracteres alfanuméricos en la pista 1. El orden físico está al revés. Es decir, los datos están escritos al revés en la tarjeta (y, por lo tanto, el firmware los leerá) como. la paridad es impar. El formato de datos de la tarjeta se ve así:

[SS] [FC] [N.º de cuenta principal] [FS] [Nombre] [FS] [Datos adicionales] [FS] [ES] [LRC] donde:

SS Centinela inicial FC Código de formato FS Separador de campo ES Centinela final LRC Carácter de verificación de redundancia longitudinal Track one SS = '%', FC = uno de los formatos (va a ser B muchas veces), FS es a menudo '', ES es '?' y el carácter LRC es comúnmente '<' aunque no está especificado en los estándares. Además de escribirse en la tarjeta al revés, los datos tienen un bit de paridad impar y son 0x20 de ASCII. Manejaremos esto cuando procesemos los datos. Pista 2 La pista dos tiene 0,110 "de ancho y comienza a 0,110 desde la parte superior de la tarjeta. Su densidad de grabación es de 75 bits por pulgada. Los datos son de 5 bits por carácter y constan de alrededor de 40 símbolos numéricos solamente. No debería encontrar ninguno. letras en esta pista. El formato de datos de la tarjeta debe seguir esta estructura

[SS] [cuenta principal n.º] [FS] [datos adicionales | datos discrecionales] [ES] [LRC]

La SS para la pista dos es el punto y coma: ';' y el FS es '=' Con este conocimiento sagrado en su haber, continúe con los siguientes pasos para ver el código que implementa el procedimiento descrito anteriormente.

Paso 4: Detecta cuando se pasa una tarjeta

Detectar cuando se pasa una tarjeta
Detectar cuando se pasa una tarjeta

1. Detecta cuando una tarjeta ha sido deslizada Formalmente, uno verificaría el pin / CARD_PRESENT para ver si está baja. Afortunadamente, esto no es realmente necesario. Comprobaremos la tarjeta válida más tarde. Alternativamente, puede leer su pin de luz estroboscópica para ver cuándo se han colocado las luces estroboscópicas en el pin, sin embargo, esto le proporcionará muchos ceros de reloj. El lector enviará alrededor de 60-70 ceros a la izquierda para hacerle saber que los datos están a punto de presentarse. Sin embargo, usaremos la naturaleza de los datos binarios para determinar cuándo comenzar a grabar bits. El centinela de inicio (SS) para la pista uno es el signo de porcentaje (%). Su valor binario es 0010 0101, lo que significa que se almacenará (y leerá) como 1010 001 (son 7 bits, por lo que el octavo bit no se transmite). Ahora, el lector astuto notará que aunque los datos están al revés, no coinciden con el valor ASCII binario. Eso es porque es 0x20 fuera de hexadecimal. El símbolo% es 0x25 y 0100 0101 es 0x05. Los datos de la tarjeta se han restado 0x20 del valor. Ese que cuelga en el nibble alto es el bit de paridad extraño. Se coloca allí para que haya un número impar de "1" en el valor. Entonces, porque sabemos que una tarjeta válida siempre comenzará con este centinela de inicio, y debido a que el bit de paridad es un 1, cuando detectamos la primera transición de ALTO a BAJO en el pin de datos, entonces sabemos que acabamos de comenzar a recibir el empezar centinela desde una tarjeta. Ahora, esto no siempre va a ser cierto, y un plan infalible sería verificar la tarjeta / CARD_PRESENT para ver si además está BAJA. La forma más sencilla de detectar el inicio de la SS es crear una interrupción externa disparada en el flanco descendente de / STROBE. Los datos son válidos 1.0 us antes del borde descendente, por lo que cuando haya muestreado el borde descendente, entonces sabrá que puede leer el pin / DATA1 y obtener un valor válido. Aquí está el código para crear su interrupción externa activada en un flanco descendente.

voidInitInterrupt (void) {// Interrupción de instalación BSET (EIMSK, INT0); // máscara de interrupción externa BSET (EICRA, ISC01); // flanco descendente BCLR (EICRA, ISC00); // flanco descendente BSET (SREG, 7); // I-bit en SREG}

En mi common.h que incluyo en todos mis programas, se pueden encontrar las definiciones de BSET y BCLR. Consulte ese archivo si tiene alguna pregunta sobre cómo configurar bits. Ahora, cuando se activa la interrupción, queremos probar el / DATA1 (en mi código definido como CARD_DATA) y establecer un bit en un registro IO de propósito general. Si estamos en el séptimo bit, guarde el registro como un carácter en nuestro búfer global. Utilizo un registro GPIOR0 porque es un acceso rápido y espectacular. El pseudocódigo es algo como esto:

Detener el temporizador de 16 bits Borrar el temporizador Si los DATOS son BAJOS Establecer BIT = 1 en REGISTRO Disminuir BIT Establecer la bandera para que no saltemos más 0, de lo contrario DATOS es ALTO Establecer BIT = 0 en REGISTRO Disminuir BIT Si BIT es 0 Agregar byte al búfer Incremento del índice Reset BIT

Si se pregunta por qué disminuir en lugar de incrementar, recuerde que los datos están al revés, por lo que en lugar de registrar los bits a medida que los obtenemos de LSB a MSB, los guardamos de MSB a LSB para que no tengamos que invertir los bits. posteriormente al procesar los datos. Si realmente quisiera, también podría agregar 0x20 hexadecimal aquí, pero como son aproximadamente 5us en estas luces estroboscópicas, estoy manteniendo el procesamiento en esta rutina de servicio de interrupción al mínimo.

ISR (INT0_vect) {StopTimer (); ClearTimer (); if (! BCHK (PIND, CARD_DATA1)) // inverso bajo = 1 {BSET (GPIOR0, bit); --poco; bDataPresent = 1; } else if (bDataPresent) {BCLR (GPIOR0, bit); --poco; } if (bit <0) {buff [idx] = (char) GPIOR0; ++ idx; bit = 6; } StartTimer ();} Si se pregunta de qué se trata el negocio de la sincronización, eso se trata en el paso para determinar cuándo la tarjeta ha salido del lector.

Paso 5: lea el flujo de datos

Leer el flujo de datos

Bueno, ya le he mostrado cómo leer los datos, ya que es parte de la rutina de servicio de interrupción para nuestra interrupción externa de borde descendente. Un método alternativo sería establecer una bandera en el ISR, y en el bucle principal sondear la bandera y leer los datos de esa manera, pero creo que la forma en que lo he presentado es más limpia. Sea su propio juez y escriba el suyo como su MCU lo permita. Dicho esto, pasemos a descubrir cómo detectar cuándo la tarjeta saca un Elvis y ha abandonado el edificio.

Paso 6: detecte la tarjeta que sale del lector

Detectar la tarjeta saliendo del lector
Detectar la tarjeta saliendo del lector

Detecta cuando una tarjeta se ha ido

Formalmente, uno probaría el pin / CARD_PRESENT para ver si se ha vuelto ALTO nuevamente, pero no necesitamos que steenkin '/ CARD_PRESENT tome otro puerto de E / S. Aquí es donde entran esos temporizadores. Cada vez que se llama a la interrupción porque hemos detectado un flanco descendente en / STROBE, detenemos un temporizador, borramos el valor del temporizador y comenzamos a leer. Cuando terminamos de leer, volvemos a poner en marcha el cronómetro. Repita hasta la náusea o hasta que el temporizador alcance un valor determinado. Eso significa que se ha llamado a la última interrupción y no han entrado más datos, por lo que asumimos que eso es todo y comenzamos a procesar los datos que hemos recopilado. Para los temporizadores, utilizamos TIMER1, es decir, el temporizador de 16 bits. Estoy usando un resonador de 16 Mhz externamente a mi AVR. Si estás usando un arduino, probablemente también lo estés. Entonces, he elegido un valor de preescalador de 1024, lo que significa que cada (16, 000, 000/1024) veces el temporizador se incrementará. Es decir, “marcará” 15, 625 veces por segundo. El / CARD_PRESENT irá a ALTO indicando que la tarjeta ha salido del lector unos 150 ms después del último bit de datos. Sabiendo esto, decidí verificar cada 1/4 de segundo. Eso se vería así:

(((F_CPU) / PRESCALER) / 4) que resulta ser alrededor de 3900. Entonces, cuando el contador del temporizador TCNT1 llega a 3900, sé que han pasado alrededor de 300 ms y puedo concluir con bastante seguridad que la tarjeta ha salido del lector. Fácil

#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) Ha visto en el ISR donde el temporizador se inicia, se detiene y se borra en cada interrupción. Ahora, en el ciclo principal, solo verificamos si el contador del temporizador ha alcanzado nuestro valor objetivo y, de ser así, iniciamos el procesamiento de datos.

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

StopTimer (); ClearTimer (); Procesar datos(); ReadData (); idx = 0; bit = 6; bDataPresent = 0; memset (& buff, 0, MAX_BUFF_SZ1); }} Ahora es seguro procesar los datos

código formateado por

Paso 7: procesar los datos

Procesar los datos
Procesar los datos

Procesar los datos

La fase de procesamiento consta de:

  • Comprobando una SS válida
  • comprobando la paridad
  • convertir a ASCII
  • comprobando un ES válido
  • comprobando LRC

Aquí, no me molesto en verificar la paridad, ya que solo puse ese bit en cero. Tampoco calculo el LRC para este pequeño tutorial. Eso sería algo que un firmware más completo podría querer hacer. Aquí está el código para procesar los datos siguiendo los pasos anteriores (sin los mencionados anteriormente). Encuéntrelo en la imagen de abajo. Está comentado y se explica por sí mismo. Una nota especial sobre la paridad y ASCII: simplemente borro el bit de paridad (séptimo bit … es decir, un 1 con 6 ceros detrás) y para convertir de "datos de tarjeta" debe agregar 0x20 al valor. Eso es todo.

Paso 8: mostrar los datos

Mostrar los datos
Mostrar los datos
Mostrar los datos
Mostrar los datos

Mostrar los datos

La pantalla va a un programa de terminal que escribí específicamente para conectarse a un AVR a través de RS232 o USB. El programa se llama AVR Terminal. El método ReadData () es bastante feo y se le anima a encontrar una solución más limpia que la que se me ocurrió. También hay una salida de la función en AVR Terminal. La salida es la primera de una tarjeta de seguro médico y la segunda es de una tarjeta VISA. Haga clic en en la esquina superior izquierda de la imagen y elija imagen original o grande para verla mejor.

Paso 9: Descarga y finalización del código

En este instructivo, analicé algunos conceptos básicos de los lectores de tarjetas magnéticas y le mostré un código para comenzar en la dirección correcta en la lectura de datos de tarjetas magnéticas. Hay mucho más trabajo por hacer, como leer y decodificar la segunda pista, calcular el LRC y calcular la paridad impar en cada byte. El código fuente completo está disponible para descargar a continuación. Fue escrito en AVR Studio 4.17. Espero que hayas disfrutado de este instructivo y, como siempre, espero cualquier comentario o sugerencia que puedas tener. ¡Feliz codificación y AVR'ing!

Recomendado: