Last active
August 3, 2022 19:42
-
-
Save noahcoad/85e2bbeb6463367598eb326d9776111c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Magnetic Card Reader with ESP32 Arduino | |
// Created on 2020-06-13 by Noah Coad | |
// | |
// Connect card reader cable to ESP32 pins: | |
// DATA (yellow) = 15, PRESENT (orange) = 14, STROBE (green) = 32 | |
// | |
// I'm using Adafruit HUZZAH32 ESP32 Feather Board, but any ESP32 should work | |
// And the Magtek 21050071 card reader, which reads the 2nd card track only (encoded in 5 bits) | |
// Double check your card reader, which track(s) it reads, because track #1 is encoded differently | |
// | |
// Much thanks to nevdull's tutorial which this is based off of: | |
// https://www.instructables.com/id/Turn-your-Arduino-into-a-Magnetic-Card-Reader/ | |
// | |
// variables | |
const int PIN_LED = 13; | |
// card data struct | |
struct CardReader { | |
const uint8_t PIN_CARD_DATA; | |
const uint8_t PIN_CARD_PRESENT; | |
const uint8_t PIN_CARD_STROBE; | |
bool bDataPresent; | |
char buff[40]; | |
int64_t stamp; | |
uint8_t data, bitpos, idx; | |
}; | |
// init card info | |
CardReader reader = {15, 14, 32, false, "", 0, 0, 0, 0}; | |
// interrupt | |
void IRAM_ATTR isr() { | |
// reset our timer | |
reader.stamp = 0; | |
// a digital 1 is read as a low pin | |
if (digitalRead(reader.PIN_CARD_DATA) == LOW) { // low=1 | |
bitSet(reader.data, reader.bitpos++); | |
reader.bDataPresent = true; | |
} else if (reader.bDataPresent) { | |
bitClear(reader.data, reader.bitpos++); | |
} | |
// if we've ready five bits already | |
// save off this byte worth of data | |
if (reader.bitpos == 5) { | |
reader.buff[reader.idx++] = reader.data; | |
reader.bitpos = 0; | |
} | |
// remember when last bit was | |
reader.stamp = millis(); | |
} | |
void setup() { | |
// put your setup code here, to run once: | |
Serial.begin(115200); | |
// setup the pin modes | |
pinMode(reader.PIN_CARD_DATA, INPUT_PULLUP); | |
pinMode(reader.PIN_CARD_PRESENT, INPUT_PULLUP); | |
pinMode(reader.PIN_CARD_STROBE, INPUT_PULLUP); | |
pinMode(PIN_LED, OUTPUT); | |
digitalWrite(PIN_LED, LOW); | |
// attach interrupt | |
attachInterrupt(reader.PIN_CARD_STROBE, isr, FALLING); | |
// reset card data | |
initCardData(); | |
} | |
void loop() { | |
// put your main code here, to run repeatedly: | |
// if data is ready | |
if (reader.bDataPresent) { | |
if (reader.stamp > 0 && ((millis() - reader.stamp) > 10)) { | |
printf("Card slide: "); | |
for (int x = 0; x < reader.idx - 1; x++) { | |
bitClear(reader.buff[x], 4); | |
printf("%1X", reader.buff[x]); | |
} | |
printf("\n"); | |
digitalWrite(PIN_LED, LOW); | |
// check validity | |
int pos = 0; | |
for (int x = 14; x < reader.idx; x++) | |
if (reader.buff[x] == 0x0D) { pos = x; break; } | |
bool valid = pos > 13 && pos < 21 && reader.buff[0] == 0x0B && reader.idx > pos + 4; | |
// show card info if valid | |
if (valid) { | |
for (int x = 1; x < pos + 5; x++) reader.buff[x] += 48; | |
printf(" valid, card # %.*s, exp %.*s/%.*s\n", pos - 1, &(reader.buff[1]), | |
2, &(reader.buff[pos + 3]), 2, &(reader.buff[pos + 1])); | |
} | |
else printf(" invalid\n"); | |
initCardData(); | |
} else { | |
digitalWrite(PIN_LED, HIGH); | |
} | |
} | |
} | |
void initCardData() { | |
reader.idx = 0; | |
reader.bDataPresent = false; | |
reader.bitpos = 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Works like a charm. I had another use with pin 32 so i connected to pin 13. ESP-32. i could not find a library for this reader, and i came across this. You have a wonderful day