Magnetic Card Reader - compile errors

So after trying unsuccessfully to write some code to read track 1 I found some code on LadyAda site which reads track 1 but for the life of my I can't get it going :frowning: My C coding is terrible at the best of times.
I keep getting compile errors:

sketch_jul16c.cpp: In function 'void loop()':
sketch_jul16c:242: error: a function-definition is not allowed here before '{' token
sketch_jul16c:293: error: expected `}' at end of input

The compiler keeps complaining about this line:

uint8_t verifycard(byte track[]) {
#define PIEZO 3
#define CLOCK2 10
#define DATA2 9
#define CARD2 23

#define TRACK1_LEN 79
#define BUFF 30
uint8_t track1[TRACK1_LEN+BUFF];
uint8_t scratch[TRACK1_LEN+BUFF];

#define RIGHT 1
#define LEFT 0

#define BYTELENGTH 7 // 6 + 1 parity

//#define _SERIAL 1


void beep(uint8_t pin, long freq, long dur) {
  long d = 500000/ freq;

  for (long i=0; i< freq * dur / 2000; i++) {
    digitalWrite(pin, HIGH);
    delayMicroseconds(d);
    digitalWrite(pin, LOW);
    delayMicroseconds(d);
  }  
}


void setup()
{
#ifdef _SERIAL
  Serial.begin(9600); // USB is always 12 Mbit/sec
#endif
 
  pinMode(5, OUTPUT);
  pinMode(PIEZO, OUTPUT);
  digitalWrite(5, LOW);
  
  beep(PIEZO, 4000, 200);
}

//http://stripesnoop.sourceforge.net/devel/magtek-app.pdf

void loop()
{
  while (digitalRead(CARD2));
  uint8_t zeros = 0;
  
  // card was swiped!
  // check clocked in data
  for (uint8_t t1 = 0; t1 < TRACK1_LEN; t1++) {
    track1[t1] = 0;
    for (uint8_t b=0; b < BYTELENGTH; b++) {

      // wait while clock is high
      while (digitalRead(CLOCK2) && !digitalRead(CARD2));
      // we sample on the falling edge!
      uint8_t x = digitalRead(DATA2);
      if (!x) {
      // data is LSB and inverted!
        track1[t1] |= _BV(b);
      }
      // heep hanging out while its low
      while (!digitalRead(CLOCK2) && !digitalRead(CARD2));
     
    }
    
    if ((t1 == 0) && (track1[t1] == 0)) {
     // get rid of leading 0's
     zeros++;
     t1--;
     continue;
    }
    
    if (zeros < 4) {
      t1--;
     continue;
    }
    if ((t1 == 1) && (track1[t1] == 0)) {
     t1 = -1;
     zeros = 1;
     continue;
    }
  }
  
  // shift left until we have no more starting zero bits!
  while ((track1[0] & 0x1) == 0 ) {
    shifttrack(track1, scratch, LEFT);
  }

  if (!verifycard(track1)) {
    // Serial.println("flippy?");
    
    // didnt pass verification, perhaps we can try flipping it around?
    for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) 
     scratch[i] = 0;  // clear out the scratch
     
    for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) {
      // for each bit starting with the MSB of the LAST 'byte' to the LSB of the first byte
      for (int8_t j=0; j < 7; j++) {
         if (track1[TRACK1_LEN+BUFF-1-i] & _BV(6-j))
           scratch[i] |= _BV(j);            
      } 
    }
    
    for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) {
      track1[i] = scratch[i];
    }
    
    // get rid of leading zero bits and possible single bit flips
    while (((track1[0] & 0x1) == 0) || track1[1] == 0)
      shifttrack(track1, scratch, LEFT);
  }
    
  if (verifycard(track1)) {

#ifdef _SERIAL
    Serial.println("Swiped!");
    for (uint8_t i = 0; i < TRACK1_LEN; i++) {
      Serial.print(track1[i], HEX); 
      Serial.print(" "); 
    }
    Serial.println();
    for (uint8_t i = 0; i < TRACK1_LEN; i++) {
#if ARDUINO >= 100
      Serial.write((track1[i] & 0x3F)+0x20);
#else
      Serial.print((track1[i] & 0x3F)+0x20, BYTE); 
#endif
      Serial.print(" "); 
    }
    Serial.println();
    for (uint8_t i = 0; i < 6; i++) {
      for (uint8_t j = 0; j < 7; j++) {
       if (track1[i] & _BV(j)) {
         Serial.print('1');
       } else {
         Serial.print('0');
       }
      }
    }
    Serial.println();
#endif

    // FIND PAN
    uint8_t i=2;
    while ((track1[i] & 0x3F) != 0x3E) {
#if ARDUINO >= 100
 #ifdef _SERIAL
        Serial.write((track1[i] & 0x3F)+0x20);
 #endif
 #ifdef _KEYBOARD
      //  Keyboard.write((track1[i] & 0x3F)+0x20);
 #endif
#else
 #ifdef _SERIAL
        Serial.print((track1[i] & 0x3F)+0x20, BYTE); 
 #endif
 #ifdef _KEYBOARD
    //    Keyboard.print((track1[i] & 0x3F)+0x20, BYTE);
 #endif
#endif
      i++;
    }
    i++;
    char fname[26], lname[26];
    
    // LAST NAME
    uint8_t j=0;
    while ((track1[i] & 0x3F) != 0xF) {
#ifdef _SERIAL
#if ARDUINO >= 100
      Serial.write((track1[i] & 0x3F)+0x20);
#else
      Serial.print((track1[i] & 0x3F)+0x20, BYTE); 
#endif
#endif
      lname[j++] = (track1[i] & 0x3F)+0x20;
      i++;
    }
    lname[j] = 0;
    i++;
    j=0;
    // FIRST NAME
    while ((track1[i] & 0x3F) != 0x3E) {
#ifdef _SERIAL
#if ARDUINO >= 100
      Serial.write((track1[i] & 0x3F)+0x20);
#else
      Serial.print((track1[i] & 0x3F)+0x20, BYTE); 
#endif
#endif
      
      fname[j++] = (track1[i] & 0x3F)+0x20;

      i++;
    }
    fname[j] = 0;
    i++;
    char y1, y2, m1, m2;
    y1 = (track1[i++] & 0x3F)+0x20;
    y2 = (track1[i++] & 0x3F)+0x20;
    m1 = (track1[i++] & 0x3F)+0x20;
    m2 = (track1[i++] & 0x3F)+0x20;
  

    beep(PIEZO, 4000, 200);
  } else {
    beep(PIEZO, 1000, 200);
    
#ifdef _SERIAL
      Serial.println("Failed!");
      for (uint8_t i = 0; i < TRACK1_LEN; i++) {
        Serial.print(track1[i], HEX); 
        Serial.print(" "); 
      }
      Serial.println();
      for (uint8_t i = 0; i < 6; i++) {
        for (uint8_t j = 0; j < 7; j++) {
         if (track1[i] & _BV(j)) {
           Serial.print('1');
         } else {
           Serial.print('0');
         }
        }
      }
    }
    Serial.println();
#endif
  
  //Serial.println(zeros, DEC);
  
  for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) {
    track1[i] = scratch[i] = 0;
  }
  
  while (! digitalRead(CARD2));
  return;
}

uint8_t verifycard(byte track[]) {
  uint8_t parityok = 1;
  
  // calculate parity for each byte
  for (uint8_t i = 0; i < TRACK1_LEN; i++) {
    uint8_t p = 1;
    for (uint8_t j = 0; j < 6; j++) {
      if (track1[i] & _BV(j))
        p++;
    }
    p %= 2;
    if (p != track1[i] >> 6) {
      //Serial.print("Bad parity on ");
      //Serial.println(track1[i], HEX);
      parityok = 0;
    }
    if (track1[i] == 0x1F) break;
  }
  
  if ((track1[0] == 0x45) && (track1[1] == 0x62) && parityok) {
    return 1;
  }
  return 0;
}



// We use this to s
void shifttrack(byte track[], byte shiftbuffer[], uint8_t dir) {
  if (dir == RIGHT) {
    // shift right
     uint8_t x =0;
    
    for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) {
      shiftbuffer[i] = ((track[i] << 1) | x) & 0x3F;
      x = (track[i]>>6) & 0x1; // snag the parity bit
    } 
  } else {
    // left
    uint8_t x =0;
    
    for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) {
      x = track[i+1] & 0x1; // snag the bit
      shiftbuffer[i] = ((track[i] >> 1) | (x << 6));

    } 
  }
  
  for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) {
    track[i] = shiftbuffer[i];
  }
}
  while (digitalRead(CARD2));

The return type from digitalRead() is not boolean. You should not write code assuming it is. The ; on the end is a pretty poor indicator that you know that nothing is going to happen. Use curly braces and a comment.

The compiler keeps complaining about this line:

My guess is that you do not have the correct number of { and }. However the use of { on a line with other code, and the overall size of loop() makes me disinclined to actually count and try to match them up.

found it:
line 229 conditionally closes a brace only when _SERIAL is defined

Thanks - I removed that brace - I"ll keep looking as there must be another one somewhere. Still the same error.

Update: ok - found the error. I just uncommented this :slight_smile:

 #define _SERIAL 1

Now compiles fine.