TTL Card Reader

183 views
Skip to first unread message

dakman05

unread,
Sep 25, 2012, 1:51:25 AM9/25/12
to ioio-...@googlegroups.com
Trying to get this Card reader to work but I guess I'm still not familiar with TWI /Digital Read ... 

Essentially this is the card reader i got


Here is my current pinout per the above (track 2 version )

1. pin 26 - DATA

2. pin 25 - CLOCK

3. pin 27 - LOADED

4. 5vdc 

5. GND

I tried TWI (async and non async) and Digital Read in attempt to get incoming bytes but I'm doing something wrong... I'm trying to read only so I'm wondering if writeReadAync is the right function?

What would be the way to initialize a TWI object for a card reader.. or should I be using Digital Read ? Seems like I need to know address information and response length.. The thing is the card reader is old school and plain TTL so I'm unclear on the frequency(100 khz), what the request should be etc.

I'm trying to piece this together with lady ada's mag swipe tutorial for arduino/teensy... and hack miami's version.. I've been able to get this to work in arduino but IOIO I guess I'm lost .. Any sample code would be appreciated..

http://www.ladyada.net/make/magstripe/index.html
http://hackmiami.org/2008/12/21/magnetic-stripe-card-reader/


Krishna

unread,
Sep 25, 2012, 2:28:13 AM9/25/12
to ioio-...@googlegroups.com
https://groups.google.com/forum/#!topic/ioio-users/fIjGcyjSYeY

Check this thread for sample code - please read full thread as code needs modification based on subsequent thread messages

Ytai Ben-Tsvi

unread,
Sep 25, 2012, 3:48:22 AM9/25/12
to ioio-...@googlegroups.com
Why do you think this is TWI???
It seems like it is just an incoming clock / data signal you should record. There's currently no firmware implementation for something like this on the IOIO (SPI-slave might have solved this), but depending on the rate you might be able to pull it off on the Android side (wait for a clock, read the value, etc.)

--
You received this message because you are subscribed to the Google Groups "ioio-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/ioio-users/-/WpMviCt-PvAJ.

To post to this group, send email to ioio-...@googlegroups.com.
To unsubscribe from this group, send email to ioio-users+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/ioio-users?hl=en.

dakman05

unread,
Sep 25, 2012, 3:55:28 AM9/25/12
to ioio-...@googlegroups.com
I see so just capture DigitalInput and map the highs and lows?? any code out there for something like this?

Ytai Ben-Tsvi

unread,
Sep 25, 2012, 4:06:57 AM9/25/12
to ioio-...@googlegroups.com
I don't have such a code, but it should be simple to write. Only thing that's not certain is whether it'll be fast enough to catch up. If it isn't - tell me - there are some more complicated tricks we can pull off.

To view this discussion on the web visit https://groups.google.com/d/msg/ioio-users/-/19pJVscIl8AJ.

dakman05

unread,
Sep 25, 2012, 4:57:02 AM9/25/12
to ioio-...@googlegroups.com
DigitalInput isnt fluctuating... I'm just getting 111 or 000 depending on how I open pin 26... Am I using the wrong function? Is there a Digital Read (like arduino)? 

dakman05

unread,
Sep 25, 2012, 5:03:44 AM9/25/12
to ioio-...@googlegroups.com
am i supposed to use UART for RX ? change pin? somethings not right :(


On Tuesday, September 25, 2012 1:07:18 AM UTC-7, Ytai wrote:

Ytai Ben-Tsvi

unread,
Sep 25, 2012, 11:43:13 AM9/25/12
to ioio-...@googlegroups.com

You should open both as digital inputs, wait for the start signal, the read the data line whenever the clock goes high (or maybe low?)

To view this discussion on the web visit https://groups.google.com/d/msg/ioio-users/-/90MutgdPGVIJ.

dakman05

unread,
Sep 25, 2012, 4:26:16 PM9/25/12
to ioio-...@googlegroups.com
Gotcha.. so tie the clock to a Digital Input read high and low and use UART for RX? 

Ytai Ben-Tsvi

unread,
Sep 25, 2012, 4:46:57 PM9/25/12
to ioio-...@googlegroups.com
No UART is involved here, just three digital inputs.

To view this discussion on the web visit https://groups.google.com/d/msg/ioio-users/-/XXLtrzQUySsJ.

dakman05

unread,
Sep 25, 2012, 8:27:58 PM9/25/12
to ioio-...@googlegroups.com
what pins should be used for CLOCK DATA and CARD READ?

Ytai Ben-Tsvi

unread,
Sep 25, 2012, 11:13:46 PM9/25/12
to ioio-...@googlegroups.com
Any pin can be used for digital input. If your reader is 5V, make sure to use 5V tolerant pins (the ones with the circle around them).

To view this discussion on the web visit https://groups.google.com/d/msg/ioio-users/-/zNKXCoCq2LQJ.

dakman05

unread,
Sep 26, 2012, 3:17:16 AM9/26/12
to ioio-...@googlegroups.com
So I got it to work using Arduino and I plan on piping the Serial data output to IOIO RX UART at 9600 baud   :) .. I had the pinouts wrong which was probably why nothing worked :( ... poor documentation ..

To simplify my circuit I would really prefer to use IOIO only and not an intermediary circuit ... The problem is I don't understand how interrupts work with IOIO and I'm trying to port this C code over to Android land. It seems like in Arduino functions are tied to AttachInterrupt calls triggering TTL/byte interpretation. See code highlighted below... How can I emulate the Arduino AttachInterrupt function (http://arduino.cc/en/Reference/AttachInterrupt )  with IOIO ?  


/*
 * Magnetic Stripe Reader
 * by Stephan King http://www.kingsdesign.com
 *
 * Reads a magnetic stripe.
 *
 */
 
int cld1Pin = 5;            // Card status pin
int rdtPin = 2;             // Data pin
int reading = 0;            // Reading status
volatile int buffer[400];   // Buffer for data
volatile int i = 0;         // Buffer counter
volatile int bit = 0;       // global bit
char cardData[40];          // holds card info
int charCount = 0;          // counter for info
int DEBUG = 0;
 
void setup() {
  Serial.begin(9600); 
 
  // The interrupts are key to reliable
  // reading of the clock and data feed
  attachInterrupt(0, changeBit, CHANGE);
  attachInterrupt(1, writeBit, FALLING);
}
 
void loop(){
 
  // Active when card present
  while(digitalRead(cld1Pin) == LOW){
    reading = 1;
  }     
 
  // Active when read is complete
  // Reset the buffer
  if(reading == 1) {  
 
    if (DEBUG == 1) {
      printBuffer();
    }
 
    decode();
    reading = 0;
    i = 0;
 
    int l;
    for (l = 0; l < 40; l = l + 1) {
      cardData[l] = '\n';
    }
 
    charCount = 0;
  }
}
 
// Flips the global bit
void changeBit(){
  if (bit == 0) {
    bit = 1;
  } else {
    bit = 0;
  }
}
 
// Writes the bit to the buffer
void writeBit(){
  buffer[i] = bit;
  i++;
}
 
// prints the buffer
void printBuffer(){
  int j;
  for (j = 0; j < 200; j = j + 1) {
    Serial.println(buffer[j]);
  }
}
 
int getStartSentinal(){
  int j;
  int queue[5];
  int sentinal = 0;
 
  for (j = 0; j < 400; j = j + 1) {
    queue[4] = queue[3];
    queue[3] = queue[2];
    queue[2] = queue[1];
    queue[1] = queue[0];
    queue[0] = buffer[j];
 
    if (DEBUG == 1) {
      Serial.print(queue[0]);
      Serial.print(queue[1]);
      Serial.print(queue[2]);
      Serial.print(queue[3]);
      Serial.println(queue[4]);
    }
 
    if (queue[0] == 0 & queue[1] == 1 & queue[2] == 0 & queue[3] == 1 & queue[4] == 1) {
      sentinal = j - 4;
      break;
    }
  }
 
  if (DEBUG == 1) {
    Serial.print("sentinal:");
    Serial.println(sentinal);
    Serial.println("");
  }
 
  return sentinal;
}
 
void decode() {
  int sentinal = getStartSentinal();
  int j;
  int i = 0;
  int k = 0;
  int thisByte[5];
 
  for (j = sentinal; j < 400 - sentinal; j = j + 1) {
    thisByte[i] = buffer[j];
    i++;
    if (i % 5 == 0) {
      i = 0;
      if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 0) {
        break;
      }
      printMyByte(thisByte);
    }
  }
 
  for (k = 0; k < charCount; k = k + 1) {
    Serial.print(cardData[k]);
  }
  Serial.println("");
 
}
 
void printMyByte(int thisByte[]) {
  int i;
  for (i = 0; i < 5; i = i + 1) {
    if (DEBUG == 1) {
      Serial.print(thisByte[i]);
    }
}
    if (DEBUG == 1) {
      Serial.print("\t");
      Serial.print(decodeByte(thisByte));
      Serial.println("");
    }
 
    cardData[charCount] = decodeByte(thisByte);
    charCount ++;
}
 
char decodeByte(int thisByte[]) {
    if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 1){
      return '0';
    }
    if (thisByte[0] == 1 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 0){
      return '1';
    }
 
    if (thisByte[0] == 0 & thisByte[1] == 1 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 0){
      return '2';
    }
 
    if (thisByte[0] == 1 & thisByte[1] == 1 & thisByte[2] == 0 & thisByte[3] == 0 & thisByte[4] == 1){
      return '3';
    }
 
    if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 1 & thisByte[3] == 0 & thisByte[4] == 0){
      return '4';
    }
 
    if (thisByte[0] == 1 & thisByte[1] == 0 & thisByte[2] == 1 & thisByte[3] == 0 & thisByte[4] == 1){
      return '5';
    }
 
    if (thisByte[0] == 0 & thisByte[1] == 1 & thisByte[2] == 1 & thisByte[3] == 0 & thisByte[4] == 1){
      return '6';
    }
 
    if (thisByte[0] == 1 & thisByte[1] == 1 & thisByte[2] == 1 & thisByte[3] == 0 & thisByte[4] == 0){
      return '7';
    }
 
    if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 1 & thisByte[4] == 0){
      return '8';
    }
 
    if (thisByte[0] == 1 & thisByte[1] == 0 & thisByte[2] == 0 & thisByte[3] == 1 & thisByte[4] == 1){
      return '9';
    }
 
    if (thisByte[0] == 0 & thisByte[1] == 1 & thisByte[2] == 0 & thisByte[3] == 1 & thisByte[4] == 1){
      return ':';
    }
 
    if (thisByte[0] == 1 & thisByte[1] == 1 & thisByte[2] == 0 & thisByte[3] == 1 & thisByte[4] == 0){
      return ';';
    }
 
    if (thisByte[0] == 0 & thisByte[1] == 0 & thisByte[2] == 1 & thisByte[3] == 1 & thisByte[4] == 1){
      return '<';
    }
 
    if (thisByte[0] == 1 & thisByte[1] == 0 & thisByte[2] == 1 & thisByte[3] == 1 & thisByte[4] == 0){
      return '=';
    }
 
    if (thisByte[0] == 0 & thisByte[1] == 1 & thisByte[2] == 1 & thisByte[3] == 1 & thisByte[4] == 0){
      return '>';
    }
 
    if (thisByte[0] == 1 & thisByte[1] == 1 & thisByte[2] == 1 & thisByte[3] == 1 & thisByte[4] == 1){
      return '?';
    }
}

Ytai Ben-Tsvi

unread,
Sep 26, 2012, 3:37:27 AM9/26/12
to ioio-...@googlegroups.com
Whenever you open a pin for DigitalInput in IOIO, it becomes "interrupt driven" in the sense that the IOIO will report to Android on every change.
However, currently, this is not exposed in a way that's useful for what you need, so you'll need some hacking in IOIOLib.
Start by logging IncomingState.handleReportDigitalInStatus(int pin, boolean level). This should have all the information, and then you'll need to change the behavior of this method to do what you want (i.e. sample the incoming bits according to the external clock, and decode them when scan is complete).

To view this discussion on the web visit https://groups.google.com/d/msg/ioio-users/-/TiEccgmI0ScJ.

dakman05

unread,
Sep 26, 2012, 4:27:02 AM9/26/12
to ioio-...@googlegroups.com

Yea I'll prolly just stick to Arduino doing the TTL to UART for me....seems like this Arduino code is working well .. TTL is greek to me and with this card data stuff, interpretting bytes it can get complicated see-> Card-O-Rama: Magnetic Stripe Technology and Beyond  lol .. just soldered it up and about to test UART to Android.Toast :) This essentially eliminates any bluetooth, usb host mode headaches and now I can send the card data to our CC processor via the standard ADB/OpenAccessory connection to IOIO

Thanks again Ytai  for all your help on my IOIO quest.. IOIO is a game changer! and your super fast baudrate response on these groups is even more awesome... :) 

dakman05

unread,
Apr 27, 2013, 4:50:40 AM4/27/13
to ioio-...@googlegroups.com
would something like this work? http://arduino.cc/forum/index.php?topic=8516.0;wap2 

do you think its possible to parse bytes like this with IOIO / IOIO Uart functions?  is it quick enough?

thanks -dave

On Wednesday, September 26, 2012 12:37:48 AM UTC-7, Ytai wrote:

Ytai Ben-Tsvi

unread,
Apr 27, 2013, 3:20:38 PM4/27/13
to ioio-...@googlegroups.com
Refer to my previous post. If you tap directly into the lower layers of IOIOLib you probably can.


To unsubscribe from this group and stop receiving emails from it, send an email to ioio-users+...@googlegroups.com.

To post to this group, send email to ioio-...@googlegroups.com.

David K

unread,
Apr 27, 2013, 3:50:30 PM4/27/13
to ioio-...@googlegroups.com
I spent some time navigating in the "caves of IOIOLib".. Am I editing the right file? seems like this is the file that sends/receives bytes from IOIO /IOIO firmware



case UART_REPORT_TX_STATUS:
arg1 = readByte();
arg2 = readByte();
handler_.handleUartReportTxStatus(arg1 & 0x03,
(arg1 >> 2) | (arg2 << 6));
break;

case UART_DATA:
arg1 = readByte();
for (int i = 0; i < (arg1 & 0x3F) + 1; ++i) {
data[i] = (byte) readByte();
}
handler_.handleUartData(arg1 >> 6, (arg1 & 0x3F) + 1,
data);
break;

case UART_STATUS:
arg1 = readByte();
if ((arg1 & 0x80) != 0) {
handler_.handleUartOpen(arg1 & 0x03);
} else {
handler_.handleUartClose(arg1 & 0x03);
}
break;

Ytai Ben-Tsvi

unread,
Apr 27, 2013, 6:47:54 PM4/27/13
to ioio-...@googlegroups.com

This has nothing to do with UART. Use digital inputs as I recommended 2 posts ago.

andriivl...@gmail.com

unread,
May 31, 2018, 12:33:35 AM5/31/18
to ioio-users
it is not fast enought to cath up, wha tricks can we pull
Reply all
Reply to author
Forward
0 new messages