My Wiegand project

Hi all!

First time poster, if I'm in wrong area please move.

I have written a program with nano to read three rfid-readers using wiegand26. I'm running out of ideas why my code doesn't work. With readers 1 and 2 I do get the right code. But reader 3 doesn't work, it looks like something resets the bit counter.

The actual inputs are working since I can modify the L-led with them. Also if I change one of the tx bytes to the counter2-value right after reading a bit, it will put out 1, but when it get's to checking if there's anything in counter2, there never is.

Also if I move variable definitions from global to inside void loop(), the serial communication stops (so no idea what's going on then).

The goto is because, I believe it's faster than the while, but after all the optimization I have done with the original code, doesn't seem to be necessary.

Anyone can figure out why? I have battled with this program for several ten hours and probably will for many more.

I will put out the code in following messages since, it has more characters than the allowed 9000.

first half of code:

#include <EEPROM.h>

void setup() {
  // Lukijan jalat
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);
  pinMode(A5, INPUT);
  digitalWrite(A0, HIGH);
  digitalWrite(A1, HIGH);
  digitalWrite(A2, HIGH);
  digitalWrite(A3, HIGH);
  digitalWrite(A4, HIGH);
  digitalWrite(A5, HIGH);
  
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
}
  // variable definitions
  byte rx[6], tx[6];      // Serial bytes
  byte bit1[40];        // bits got from readers
  byte bit2[40];        // bits got from readers
  byte bit3[40];        // bits got from readers
  unsigned long timeout[2];       // timeout for reading wiegand code
  unsigned long serialflush;      // counter, when to flush serial
  unsigned long gateopen[2];      // timer for code ok, pulses for doors/etc
  unsigned int gateopentime[2];   // pulse length as ms for doors/etc
  byte tavut[11]; //  bytes for storaging codes
  byte D1;        // Datalines from readers
  byte counter0;  // Counter for bits from the reader
  byte counter1;  // Counter for bits from the reader
  byte counter2;  // Counter for bits from the reader 
  byte tehty[2];  // bit is read for a reader
  byte readerdone[2];     // reader has finished reading the code 
  byte readerinprogress;  // which reader code is sent to pc
  
void loop() {


  gateopentime[0] = 2000;
  gateopentime[1] = 2000;
  gateopentime[2] = 2000;
  
  Serial.begin(9600);
  
  //Start the actual loop
  while(true){
  start:
  // check if a some of the gate pulses has been on for enough time  
  if(PORTB & B00011100) {  
     if (millis() > gateopen[0] + gateopentime[0] && millis() - gateopentime[0] > gateopentime[0]) {
       PORTB = PORTB & B11111011;
     } 
     if (millis() > gateopen[1] + gateopentime[1] && millis() - gateopentime[1] > gateopentime[1]) {
       PORTB = PORTB & B11110111;
     } 
     if (millis() > gateopen[2] + gateopentime[2] && millis() - gateopentime[2] > gateopentime[2]) PORTB = PORTB & B11101111;
  }
  
  // data from reader 1
  D1 = PINC & B00000011;  
  if (D1 == B00000011) {
    tehty[0]=0;    // pause between bit's on the code or code done
     if(counter0) {
     if (millis() > timeout[0] + 200 && timeout[0] < millis()) { // timeout on reader 1, check if there's enough bits
        tx[3]=101;
        if (counter0 >= 26){ // 26 bits counted reader 1
          
          if(bit1[0]) tavut[0] = 1; else tavut[0]=0;
          if(bit1[1]) tavut[0] = tavut[0] + 2;
          if(bit1[2]) tavut[0] = tavut[0] + 4;
          if(bit1[3]) tavut[0] = tavut[0] + 8;
          if(bit1[4]) tavut[0] = tavut[0] + 16;
          if(bit1[5]) tavut[0] = tavut[0] + 32;
          if(bit1[6]) tavut[0] = tavut[0] + 64;
          if(bit1[7]) tavut[0] = tavut[0] + 128;
      
          if(bit1[8]) tavut[1] = 1; else tavut[1]=0;
          if(bit1[9]) tavut[1] = tavut[1] + 2;
          if(bit1[10]) tavut[1] = tavut[1] + 4;
          if(bit1[11]) tavut[1] = tavut[1] + 8;
          if(bit1[12]) tavut[1] = tavut[1] + 16;
          if(bit1[13]) tavut[1] = tavut[1] + 32;
          if(bit1[14]) tavut[1] = tavut[1] + 64;
          if(bit1[15]) tavut[1] = tavut[1] + 128;
      
          if(bit1[16]) tavut[2] = 1; else tavut[2]=0;
          if(bit1[17]) tavut[2] = tavut[2] + 2;
          if(bit1[18]) tavut[2] = tavut[2] + 4;
          if(bit1[19]) tavut[2] = tavut[2] + 8;
          if(bit1[20]) tavut[2] = tavut[2] + 16;
          if(bit1[21]) tavut[2] = tavut[2] + 32;
          if(bit1[22]) tavut[2] = tavut[2] + 64;
          if(bit1[23]) tavut[2] = tavut[2] + 128;
      
          if(bit1[24]) tavut[3] = 1; else tavut[3]=0;
          if(bit1[25]) tavut[3] = tavut[3] + 2;
          
          readerdone[0]=1;
     }
      counter0=0;       // timeout between bits from the reader
    }}
  } else if (D1 == B00000001 && !tehty[0]){
    timeout[0] = millis();
    bit1[counter0]=0;
    counter0++;  
    tehty[0]=1;
 } else if (D1 == B00000010 && !tehty[0]){
    timeout[0] = millis();
    bit1[counter0]=1;
    counter0++;  
    tehty[0]=1;
 }

  // data from reader 2
  D1 = PINC & B00001100;  
    if (D1 == B00001100) {
    tehty[1]=0;    // pause between bit's on the code or code done
    if (counter1) {
       if (millis() > timeout[1] + 200 && timeout[1] < millis()) { // timeout on reader 2, check if there's enough bits
       // 26 bits from reader 2
       if (counter1 >= 26){
          tavut[4]=0;
          tavut[5]=0;
          tavut[6]=0;
          tavut[7]=0;
          
          if(bit2[0]) tavut[4] = 1;
          if(bit2[1]) tavut[4] = tavut[4] + 2;
          if(bit2[2]) tavut[4] = tavut[4] + 4;
          if(bit2[3]) tavut[4] = tavut[4] + 8;
          if(bit2[4]) tavut[4] = tavut[4] + 16;
          if(bit2[5]) tavut[4] = tavut[4] + 32;
          if(bit2[6]) tavut[4] = tavut[4] + 64;
          if(bit2[7]) tavut[4] = tavut[4] + 128;
      
          if(bit2[8]) tavut[5] = 1;
          if(bit2[9]) tavut[5] = tavut[5] + 2;
          if(bit2[10]) tavut[5] = tavut[5] + 4;
          if(bit2[11]) tavut[5] = tavut[5] + 8;
          if(bit2[12]) tavut[5] = tavut[5] + 16;
          if(bit2[13]) tavut[5] = tavut[5] + 32;
          if(bit2[14]) tavut[5] = tavut[5] + 64;
          if(bit2[15]) tavut[5] = tavut[5] + 128;
      
          if(bit2[16]) tavut[6] = 1;
          if(bit2[17]) tavut[6] = tavut[6] + 2;
          if(bit2[18]) tavut[6] = tavut[6] + 4;
          if(bit2[19]) tavut[6] = tavut[6] + 8;
          if(bit2[20]) tavut[6] = tavut[6] + 16;
          if(bit2[21]) tavut[6] = tavut[6] + 32;
          if(bit2[22]) tavut[6] = tavut[6] + 64;
          if(bit2[23]) tavut[6] = tavut[6] + 128;
      
          if(bit2[24]) tavut[7] = 1;
          if(bit2[25]) tavut[7] = tavut[7] + 2;
      
          readerdone[1]=1;
       }   
       counter1=0;       // timeout between bits from the reader
     }}
  } else if (D1 == B00000100 && !tehty[1]){
    timeout[1] = millis();
    bit2[counter1]=0;
    counter1++;  
    tehty[1]=1;
 } else if (D1 == B00001000 && !tehty[1]){
    timeout[1] = millis();
    bit2[counter1]=1;
    counter1++;
    tehty[1]=1;
 } 

  // data from reader 3
  D1 = PINC & B00110000;  
    if (D1 == B00110000) {
    tehty[2]=0;    // pause between bit's on the code or code done
    if (counter2) {
       if (millis() > timeout[2] + 250 && timeout[2] < millis()) { // timeout on reader 3, check if there's enough bits
       tx[3]=103;
       // 26 bits from reader 2
       if (counter2 >= 26){
          tavut[8]=0;
          tavut[9]=0;
          tavut[10]=0;
          tavut[11]=0;
          
          if(bit3[0]) tavut[8] = 1;
          if(bit3[1]) tavut[8] = tavut[8] + 2;
          if(bit3[2]) tavut[8] = tavut[8] + 4;
          if(bit3[3]) tavut[8] = tavut[8] + 8;
          if(bit3[4]) tavut[8] = tavut[8] + 16;
          if(bit3[5]) tavut[8] = tavut[8] + 32;
          if(bit3[6]) tavut[8] = tavut[8] + 64;
          if(bit3[7]) tavut[8] = tavut[8] + 128;
      
          if(bit3[8]) tavut[9] = 1;
          if(bit3[9]) tavut[9] = tavut[9] + 2;
          if(bit3[10]) tavut[9] = tavut[9] + 4;
          if(bit3[11]) tavut[9] = tavut[9] + 8;
          if(bit3[12]) tavut[9] = tavut[9] + 16;
          if(bit3[13]) tavut[9] = tavut[9] + 32;
          if(bit3[14]) tavut[9] = tavut[9] + 64;
          if(bit3[15]) tavut[9] = tavut[9] + 128;
      
          if(bit3[16]) tavut[10] = 1;
          if(bit3[17]) tavut[10] = tavut[10] + 2;
          if(bit3[18]) tavut[10] = tavut[10] + 4;
          if(bit3[19]) tavut[10] = tavut[10] + 8;
          if(bit3[20]) tavut[10] = tavut[10] + 16;
          if(bit3[21]) tavut[10] = tavut[10] + 32;
          if(bit3[22]) tavut[10] = tavut[10] + 64;
          if(bit3[23]) tavut[10] = tavut[10] + 128;
      
          if(bit3[24]) tavut[11] = 1;
          if(bit3[25]) tavut[11] = tavut[11] + 2;
      
          readerdone[2]=1;
       }   
       counter2=0;       // timeout between bits from the reader
     }}
  } else if (D1 == B00010000 && !tehty[1]){
    timeout[2] = millis();
    bit3[counter2]=0;
    counter2++;  
    tehty[2]=1;
 } else if (D1 == B00100000 && !tehty[1]){
    timeout[2] = millis();
    bit3[counter2]=1;
    counter2++;
    tehty[2]=1;
 }

second half:

  // serial communication. If reading is on on some reader, lets skip it.
  if (Serial.available()==7 && !counter0 && !counter1 && !counter2) {
            // 7 bytes recieved, that's the right amount from pc. 7th byte should always be 210
            Serial.readBytes(rx, 7);
            if(!rx[4] && !readerinprogress) {
              if (readerdone[0]) {
                tx[4] = 1; // Info for PC that the code read is a new one.
                tx[5] = 1; // Info for PC that which reader read the code.              
                // let's send last read code to the pc.
                tx[0]=tavut[0];
                tx[1]=tavut[1];
                tx[2]=tavut[2];
                tx[3]=tavut[3];
                readerinprogress = 1;
              } else if (readerdone[1]) {
                tx[4] = 1; // Info for PC that the code read is a new one.
                tx[5] = 2; // Info for PC that which reader read the code.              
                // let's send last read code to the pc.
                tx[0]=tavut[4];
                tx[1]=tavut[5];
                tx[2]=tavut[6];
                tx[3]=tavut[7];
                readerinprogress = 2;
              } else if (readerdone[2]) {
                tx[4] = 1; // Info for PC that the code read is a new one.
                tx[5] = 3; // Info for PC that which reader read the code.              
                // let's send last read code to the pc.
                tx[0]=tavut[8];
                tx[1]=tavut[9];
                tx[2]=tavut[10];
                tx[3]=tavut[11];
                readerinprogress = 3;
              }
            }
            
            // mirror last read byte back to pc. It should always be 210, if it's not, then there's
            // a sync or com problem going on and the pc will flush all it's communication and try
            // again.
            tx[6]=rx[6];
           
            if(rx[6] == 210) {
              // command from pc
              if (rx[4] == 8) {  // command 8, write eeprom
                  tx[4] = 9;
                  EEPROM.write(rx[5], rx[3]);
              } else if (rx[4] == 4) {  // command 4, read eeprom
                  tx[4] = 8;
                  tx[5] = EEPROM.read(rx[5]);
              } else if (rx[4] == 5) {  // command 5, open reader 1 relay
                  PORTB = PORTB | B00000100; //digitalWrite(10, HIGH); // reader 1 relay
                  gateopen[0]=millis();
                  tx[4] = 4;
                  tx[5] = 0;
                  readerdone[0]=0;
              } else if (rx[4] == 6) { // command 6, open reader 2 relay
                  PORTB = PORTB | B00001000; //digitalWrite(11, HIGH); // reader 2 relay
                  gateopen[1]=millis();
                  tx[4] = 5;
                  tx[5] = 0;
                  readerdone[1]=0;
              } else if (rx[4] == 7) { // command 7, open reader 3 relay
                  PORTB = PORTB | B00010000; //digitalWrite(12, HIGH); // reader 3 relay
                  gateopen[2]=millis();
                  tx[4] = 6;
                  tx[5] = 0;
                  readerdone[2]=0;
              }else if (rx[4] == 10) { // command 10, everything done
                  if(readerinprogress) {
                     readerdone[readerinprogress-1] = 0;
                     readerinprogress = 0;  
                  }
                  tx[4]=0;  // PC tells us work is done
                  tx[5]=0;  // reset bytes and that's it.
              }
              
              Serial.write("PC");  // the communication must begin with PC or the pc won't regognize it.
              Serial.write(tx, 7);
              serialflush = millis();
            } else {
              while(Serial.available()) Serial.read();
            }
            
            
           
            
      } else if(Serial.available() > 7) {
            // there are too many bytes in the buffer, let's flush them and get on with it.
            while(Serial.available()) Serial.read();
      } else if(millis() > serialflush+800 && millis() - 800 > serialflush) {
              // flush what's been read, it has been too long for that.
              while(Serial.available()>0) Serial.read();
              // Coms have failed, the mirrored byte isn't 210 so the pc will know about this.
              tx[6]=0;
              Serial.write("PC");
              Serial.write(tx, 7);
              serialflush = millis();
      }
   goto start;
  }
}

Now with scratching my head until it started bleeding I found something. First of all there’s a pointer error. Just in the end of the first half of the code. tehty[1] should be tehty[2]. Probably changed it when debugging and copied the reader 2 code to reader 3 code. This didn’t settle the problem as it probably wasn’t my original problem.

Then I used the led on pin 13 to find out where exactly did my counter reset. It was right after the line that resets tehty[2]. Didn’t seem to make any sense. I did some tinkering with the variable declarations, changed order and that did have some effect, just didn’t make it work. Then I changed every array on variable bigger than they needed to be. Boom, it started working. After that I started to change them back to origininal, one by one.

The result is, that every array of unisgned long has to be one variable longer, than what I use. Now what’s that about?

Edit:
I just changed the serialflush into an array and it fixed one more bug.

Now what's that about?

In what code?

Here’s the code after all I have been trying out. Probalby still need to share it in two, because it’s quite long. I changed to mega to see if there was difference, but after modifying the code to right pins, the action didn’t change. That’s why there are some minor differences here.

#include <EEPROM.h>

void setup() {
  // Lukijan jalat
  pinMode(A8, INPUT);
  pinMode(A9, INPUT);
  pinMode(A10, INPUT);
  pinMode(A11, INPUT);
  pinMode(A12, INPUT);
  pinMode(A13, INPUT);
  digitalWrite(A8, HIGH);
  digitalWrite(A9, HIGH);
  digitalWrite(A10, HIGH);
  digitalWrite(A11, HIGH);
  digitalWrite(A12, HIGH);
  digitalWrite(A13, HIGH);
 
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
}
  // variable definitions
  byte tehty[2];  // bit is read for a reader
  byte rx[6], tx[6];      // Serial bytes
  byte readerdone[2];     // reader has finished reading the code
  byte tavut[11]; //  bytes for storaging codes
  byte bit1[255];        // bits got from readers
  byte bit2[255];        // bits got from readers
  byte bit3[255];        // bits got from readers
  unsigned long timeout[3];       // timeout for reading wiegand code
  unsigned long serialflush[1];      // counter, when to flush serial
  unsigned long gateopen[3];      // timer for code ok, pulses for doors/etc
  unsigned int gateopentime[3];   // pulse length as ms for doors/etc
  byte D1;        // Datalines from readers
  byte counter0;  // Counter for bits from the reader
  byte counter1;  // Counter for bits from the reader
  byte counter2;  // Counter for bits from the reader
  byte readerinprogress;  // which reader code is sent to pc
  
void loop() {


  gateopentime[0] = 2000;
  gateopentime[1] = 2000;
  gateopentime[2] = 2000;
 
  Serial.begin(9600);
 
  //Start the actual loop
  while(true){
  start:
  // check if a some of the gate pulses has been on for enough time 
  if(PORTB & B01110000) { 
     if (millis() > gateopen[0] + gateopentime[0] && millis() - gateopentime[0] > gateopentime[0]) {
       PORTB = PORTB & B11101111;
     }
     if (millis() > gateopen[1] + gateopentime[1] && millis() - gateopentime[1] > gateopentime[1]) {
       PORTB = PORTB & B11011111;
     }
     if (millis() > gateopen[2] + gateopentime[2] && millis() - gateopentime[2] > gateopentime[2]) PORTB = PORTB & B10111111;
  }
 
  // data from reader 1
  D1 = PINK & B00000011; 
  if (D1 == B00000011) {
    tehty[0]=0;    // pause between bit's on the code or code done
     if(counter0) {
     if (millis() > timeout[0] + 200 && timeout[0] < millis()) { // timeout on reader 1, check if there's enough bits
        tx[3]=101;
        if (counter0 >= 26){ // 26 bits counted reader 1
         
          if(bit1[0]) tavut[0] = 1; else tavut[0]=0;
          if(bit1[1]) tavut[0] = tavut[0] + 2;
          if(bit1[2]) tavut[0] = tavut[0] + 4;
          if(bit1[3]) tavut[0] = tavut[0] + 8;
          if(bit1[4]) tavut[0] = tavut[0] + 16;
          if(bit1[5]) tavut[0] = tavut[0] + 32;
          if(bit1[6]) tavut[0] = tavut[0] + 64;
          if(bit1[7]) tavut[0] = tavut[0] + 128;
     
          if(bit1[8]) tavut[1] = 1; else tavut[1]=0;
          if(bit1[9]) tavut[1] = tavut[1] + 2;
          if(bit1[10]) tavut[1] = tavut[1] + 4;
          if(bit1[11]) tavut[1] = tavut[1] + 8;
          if(bit1[12]) tavut[1] = tavut[1] + 16;
          if(bit1[13]) tavut[1] = tavut[1] + 32;
          if(bit1[14]) tavut[1] = tavut[1] + 64;
          if(bit1[15]) tavut[1] = tavut[1] + 128;
     
          if(bit1[16]) tavut[2] = 1; else tavut[2]=0;
          if(bit1[17]) tavut[2] = tavut[2] + 2;
          if(bit1[18]) tavut[2] = tavut[2] + 4;
          if(bit1[19]) tavut[2] = tavut[2] + 8;
          if(bit1[20]) tavut[2] = tavut[2] + 16;
          if(bit1[21]) tavut[2] = tavut[2] + 32;
          if(bit1[22]) tavut[2] = tavut[2] + 64;
          if(bit1[23]) tavut[2] = tavut[2] + 128;
     
          if(bit1[24]) tavut[3] = 1; else tavut[3]=0;
          if(bit1[25]) tavut[3] = tavut[3] + 2;
         
          readerdone[0]=1;
     }
      counter0=0;       // timeout between bits from the reader
    }}
  } else if (D1 == B00000001 && !tehty[0]){
    timeout[0] = millis();
    bit1[counter0]=0;
    counter0++; 
    tehty[0]=1;
 } else if (D1 == B00000010 && !tehty[0]){
    timeout[0] = millis();
    bit1[counter0]=1;
    counter0++; 
    tehty[0]=1;
 }

  // data from reader 2
  D1 = PINK & B00001100; 
    if (D1 == B00001100) {
    tehty[1]=0;    // pause between bit's on the code or code done
    if (counter1) {
       if (millis() > timeout[1] + 200 && timeout[1] < millis()) { // timeout on reader 2, check if there's enough bits
       // 26 bits from reader 2
       if (counter1 >= 26){
          tavut[4]=0;
          tavut[5]=0;
          tavut[6]=0;
          tavut[7]=0;
         
          if(bit2[0]) tavut[4] = 1;
          if(bit2[1]) tavut[4] = tavut[4] + 2;
          if(bit2[2]) tavut[4] = tavut[4] + 4;
          if(bit2[3]) tavut[4] = tavut[4] + 8;
          if(bit2[4]) tavut[4] = tavut[4] + 16;
          if(bit2[5]) tavut[4] = tavut[4] + 32;
          if(bit2[6]) tavut[4] = tavut[4] + 64;
          if(bit2[7]) tavut[4] = tavut[4] + 128;
     
          if(bit2[8]) tavut[5] = 1;
          if(bit2[9]) tavut[5] = tavut[5] + 2;
          if(bit2[10]) tavut[5] = tavut[5] + 4;
          if(bit2[11]) tavut[5] = tavut[5] + 8;
          if(bit2[12]) tavut[5] = tavut[5] + 16;
          if(bit2[13]) tavut[5] = tavut[5] + 32;
          if(bit2[14]) tavut[5] = tavut[5] + 64;
          if(bit2[15]) tavut[5] = tavut[5] + 128;
     
          if(bit2[16]) tavut[6] = 1;
          if(bit2[17]) tavut[6] = tavut[6] + 2;
          if(bit2[18]) tavut[6] = tavut[6] + 4;
          if(bit2[19]) tavut[6] = tavut[6] + 8;
          if(bit2[20]) tavut[6] = tavut[6] + 16;
          if(bit2[21]) tavut[6] = tavut[6] + 32;
          if(bit2[22]) tavut[6] = tavut[6] + 64;
          if(bit2[23]) tavut[6] = tavut[6] + 128;
     
          if(bit2[24]) tavut[7] = 1;
          if(bit2[25]) tavut[7] = tavut[7] + 2;
     
          readerdone[1]=1;
       }   
       counter1=0;       // timeout between bits from the reader
     }}
  } else if (D1 == B00000100 && !tehty[1]){
    timeout[1] = millis();
    bit2[counter1]=0;
    counter1++; 
    tehty[1]=1;
 } else if (D1 == B00001000 && !tehty[1]){
    timeout[1] = millis();
    bit2[counter1]=1;
    counter1++;
    tehty[1]=1;
 }
 
         

  // data from reader 3
  D1 = PINK & B00110000; 
    if (D1 == B00110000) {
    tehty[2]=0;    // pause between bit's on the code or code done
    if (counter2){
      if (millis() > timeout[2] + 300 && timeout[2] < millis()) { // timeout on reader 3, check if there's enough bits
       // 26 bits from reader 2
       if (counter2 >= 26){
          tavut[8]=0;
          tavut[9]=0;
          tavut[10]=0;
          tavut[11]=0;
         
          if(bit3[0]) tavut[8] = 1;
          if(bit3[1]) tavut[8] = tavut[8] + 2;
          if(bit3[2]) tavut[8] = tavut[8] + 4;
          if(bit3[3]) tavut[8] = tavut[8] + 8;
          if(bit3[4]) tavut[8] = tavut[8] + 16;
          if(bit3[5]) tavut[8] = tavut[8] + 32;
          if(bit3[6]) tavut[8] = tavut[8] + 64;
          if(bit3[7]) tavut[8] = tavut[8] + 128;
     
          if(bit3[8]) tavut[9] = 1;
          if(bit3[9]) tavut[9] = tavut[9] + 2;
          if(bit3[10]) tavut[9] = tavut[9] + 4;
          if(bit3[11]) tavut[9] = tavut[9] + 8;
          if(bit3[12]) tavut[9] = tavut[9] + 16;
          if(bit3[13]) tavut[9] = tavut[9] + 32;
          if(bit3[14]) tavut[9] = tavut[9] + 64;
          if(bit3[15]) tavut[9] = tavut[9] + 128;
     
          if(bit3[16]) tavut[10] = 1;
          if(bit3[17]) tavut[10] = tavut[10] + 2;
          if(bit3[18]) tavut[10] = tavut[10] + 4;
          if(bit3[19]) tavut[10] = tavut[10] + 8;
          if(bit3[20]) tavut[10] = tavut[10] + 16;
          if(bit3[21]) tavut[10] = tavut[10] + 32;
          if(bit3[22]) tavut[10] = tavut[10] + 64;
          if(bit3[23]) tavut[10] = tavut[10] + 128;
     
          if(bit3[24]) tavut[11] = 1;
          if(bit3[25]) tavut[11] = tavut[11] + 2;
     
          readerdone[2]=1;
       }   
       counter2=0;       // timeout between bits from the reader
     }}
  } else if (D1 == B00010000 && !tehty[2]){
    timeout[2] = millis();
    bit3[counter2]=0;
    counter2++; 
    tehty[2]=1;
} else if (D1 == B00100000 && !tehty[2]){
    timeout[2] = millis();
    bit3[counter2]=1;
    counter2++;
    tehty[2]=1;
 }

and the second half

  // serial communication. If reading is on on some reader, lets skip it.
  if (Serial.available()==7  /* &&  !counter0 && !counter1 && !counter2 */) {
            // 7 bytes recieved, that's the right amount from pc. 7th byte should always be 210
            Serial.readBytes(rx, 7);
            if(!rx[4] && !readerinprogress) {
              if (readerdone[0]) {
                tx[4] = 1; // Info for PC that the code read is a new one.
                tx[5] = 1; // Info for PC that which reader read the code.             
                // let's send last read code to the pc.
                tx[0]=tavut[0];
                tx[1]=tavut[1];
                tx[2]=tavut[2];
                tx[3]=tavut[3];
                readerinprogress = 1;
              } else if (readerdone[1]) {
                tx[4] = 1; // Info for PC that the code read is a new one.
                tx[5] = 2; // Info for PC that which reader read the code.             
                // let's send last read code to the pc.
                tx[0]=tavut[4];
                tx[1]=tavut[5];
                tx[2]=tavut[6];
                tx[3]=tavut[7];
                readerinprogress = 2;
              } else if (readerdone[2]) {
                tx[4] = 1; // Info for PC that the code read is a new one.
                tx[5] = 3; // Info for PC that which reader read the code.             
                // let's send last read code to the pc.
                tx[0]=tavut[8];
                tx[1]=tavut[9];
                tx[2]=tavut[10];
                tx[3]=tavut[11];
                readerinprogress = 3;
              }
            }
           
            // mirror last read byte back to pc. It should always be 210, if it's not, then there's
            // a sync or com problem going on and the pc will flush all it's communication and try
            // again.
            tx[6]=rx[6];
           
            if(rx[6] == 210) {
              // command from pc
              if (rx[4] == 8) {  // command 8, write eeprom
                  tx[4] = 9;
                  EEPROM.write(rx[5], rx[3]);
              } else if (rx[4] == 4) {  // command 4, read eeprom
                  tx[4] = 8;
                  tx[5] = EEPROM.read(rx[5]);
              } else if (rx[4] == 5) {  // command 5, open reader 1 relay
                  PORTB = PORTB | B00010000; //digitalWrite(10, HIGH); // reader 1 relay
                  gateopen[0]=millis();
                  tx[4] = 4;
                  tx[5] = 0;
                  readerdone[0]=0;
              } else if (rx[4] == 6) { // command 6, open reader 2 relay
                  PORTB = PORTB | B00100000; //digitalWrite(11, HIGH); // reader 2 relay
                  gateopen[1]=millis();
                  tx[4] = 5;
                  tx[5] = 0;
                  readerdone[1]=0;
              } else if (rx[4] == 7) { // command 7, open reader 3 relay
                  PORTB = PORTB | B01000000; //digitalWrite(12, HIGH); // reader 3 relay
                  gateopen[2]=millis();
                  tx[4] = 6;
                  tx[5] = 0;
                  readerdone[2]=0;
              }else if (rx[4] == 10) { // command 10, everything done
                  if(readerinprogress) {
                     readerdone[readerinprogress-1] = 0;
                     readerinprogress = 0; 
                  }
                  tx[4]=0;  // PC tells us work is done
                  tx[5]=0;  // reset bytes and that's it.
              }
             
              Serial.write("PC");  // the communication must begin with PC or the pc won't regognize it.
              Serial.write(tx, 7);
              serialflush[0] = millis();
            } else {
              while(Serial.available()) Serial.read();
            }
           
           
           
           
      } else if(Serial.available() > 7) {
            // there are too many bytes in the buffer, let's flush them and get on with it.
            while(Serial.available()) Serial.read();
      } else if(millis() > serialflush[0]+800 && millis() - 800 > serialflush[0]) {
              // flush what's been read, it has been too long for that.
              while(Serial.available()>0) Serial.read();
              // Coms have failed, the mirrored byte isn't 210 so the pc will know about this.
              tx[6]=0;
              Serial.write("PC");
              Serial.write(tx, 7);
              serialflush[0] = millis();
      }
   goto start;
  }
}
       }   
       counter2=0;       // timeout between bits from the reader
     }}
  } else if (D1 == B00010000 && !tehty[2]){

I can't follow that mess. NOTHING follows a } on the same line. ONE } per line. Put every { on a new line.

Use Tools + Auto Format. Post you code as an attachment. Do not ecpect us to sew it back together.

Done as you instructed. I don’t expect you to do anything with the code (at least now, that I got it working).
The question is for the array sizes with the unsigned longs.
For example timeout is declared to be [3], even if I only use [2]. If it’s declared smaller, the program will do unexpected things. This goes for every unsigned long I use. Is there a reason for this? Even with the only one that wasn’t array (serialflush), I had to change it to an array with size of [1]. Otherwise there was some crazy things going on.

Beta008Mega.ino (12.2 KB)

Done as you instructed.

Well, I guess that every means something different to you than it does to me.

void setup() {
void loop() {
  while (true) {

Rupersero:
For example timeout is declared to be [3], even if I only use [2]. If it’s declared smaller, the program will do unexpected things

       if (millis() > timeout[2] + 300 && timeout[2] < millis()) { // timeout on reader 3, check if there's enough bits

The declaration gives the size. But arrays start at zero. So when you say timeout[2] you are indexing the 3rd element of the array.

By the way, your program is nearly impossible to read, since it has no defined constants, only numerical values. Among other reasons.

aarg:
The declaration gives the size. But arrays start at zero. So when you say timeout[2] you are indexing the 3rd element of the array.

Yes. And when it's declared as:
unsigned long timeout[2];
shouldn't there be three elements? Now I had to declare it as timeout[3], even the biggest pointer I use is [2].

Yes. And when it's declared as:
unsigned long timeout[2];
shouldn't there be three elements?

No. The number in the braces in the declaration is the number of elements, not the upper index.

PaulS:
No. The number in the braces in the declaration is the number of elements, not the upper index.

Ah, that explains a lot of what’s going on. As I have done most of my programming using some sort of version of basic, I just assumed it works the same way. Thank you for clearing this for me.

As attachment is the fixed code. It reads three wiegand 26-readers without using interruptions. Probably can do more by the same logic.
Pins for the readers are A8-A13, going like D0 reader 1, D1 reader 1, D0 reader 2 and so on. Uses internal pullup resistors. Maybe there’s something someone can use. Probably should get rid of my communication and relay-stuff and write their own though.

Beta008Mega.ino (12.5 KB)

Rupersero:
Maybe there's something someone can use.

You break so many design and style rules, I would honestly disagree. Starting from scratch would probably be faster. Sorry, but...