// https://forum.arduino.cc/t/problem-with-using-microswitches-to-measure-time-intervals/1315744
// https://wokwi.com/projects/413665351616591873


volatile bool flag;
volatile unsigned long timeOf;
byte bCount;

bool processError;

unsigned long times[8];
byte order[8];

const byte ledPin = 2;
const byte RESET = 3;
const byte ACK = 4;
const byte ERROR = 5;

const byte nSwitches = 6;
const byte SMASK = 0x3f;   // one where you have a switch
const byte noSwitch = 0x40;   // first no switch bit

byte theBit = 0x1;
byte oldB;
byte newB;

ISR (PCINT0_vect)
{
  timeOf = micros();
  flag = true;
}

# define CLEAR LOW
# define OPERATE  HIGH

void setup() {
  Serial.begin(115200);
  Serial.println("\nJello Whirled!\n");

  pinMode(ledPin, OUTPUT);
  PORTB |= SMASK;
  PCMSK0 |= SMASK;
  PCICR |= 1;   // what is the correct constant?

  pinMode(RESET, OUTPUT);
  digitalWrite(RESET, CLEAR);
  digitalWrite(RESET, OPERATE);

  pinMode(ERROR, OUTPUT);
  digitalWrite(ERROR, HIGH);
  delay(777);
  digitalWrite(ERROR, LOW);

  pinMode(ACK, INPUT_PULLUP);

  resetThisThing();
}

void loop() {
  bool ack = digitalRead(ACK) == LOW;
  if (ack) resetThisThing();

  if (flag) {
    noInterrupts();
    unsigned long myTime = timeOf;
    interrupts();
    // which bits changed?
    newB = PINB & SMASK;
    byte newly = oldB ^ newB;
    oldB = newB;

    byte ix = 0;
    for (byte xx = newly; xx; xx >>= 1, ix++) {
      if (xx == 1) {
        times[ix] = timeOf;
        order[bCount] = ix;
        bCount++;
      }
    }

    byte port = PINB & 0x3f;

    if ((port & theBit) != theBit) {
      Serial.println("                order error. ignored so far. maybe just reset and try again.");
      processError = true;
      digitalWrite(ERROR, processError ? HIGH : LOW);
    }

    Serial.print(bCount - 1);   // switches number 0 .. N - 1
    Serial.print("  ");
    Serial.println(myTime);

    flag = false;
    theBit <<= 1;

    if (bCount >= nSwitches) {
      report();
      if (!processError) resetThisThing();
    }
  }
}

void report()
{
    Serial.print("\nDone. Report : ");

  if (processError) Serial.println(" (Not in oder!) ");
  else Serial.println("");

  byte channel = SMASK;
  for (byte kx = 0; channel; kx++, channel >>= 1) {
    byte ix = order[kx];
    Serial.print(ix);
    Serial.print("  ");
    Serial.print(times[ix]);
    if (kx) {
      byte nx = order[kx - 1];
      Serial.print("        after ");
      Serial.println(times[ix] - times[nx]);
    }
    else Serial.println("");
  }
}

void resetThisThing()
{
  Serial.println("\nResetting.");

  processError = false;
  digitalWrite(ERROR, HIGH);
  delay(125);
  digitalWrite(ERROR, LOW);

  digitalWrite(RESET, CLEAR);
  digitalWrite(RESET, OPERATE);
  delay(333);

  oldB = PINB & SMASK;

  Serial.println("               Ready.\n");
  flag = false;   // does
  theBit = 0x1; 
  bCount = 0;
}

/* assumes contactd in order
      byte channel = SMASK;
      for (byte ix = 0; channel; ix++, channel >>= 1) {
        Serial.print(ix);
        Serial.print("  ");
        Serial.print(times[ix]);
        if (ix) {
          Serial.print("        after ");
          Serial.println(times[ix] - times[ix - 1]);
        }
        else Serial.println("");
      }
*/
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
nand1:A
nand1:B
nand1:OUT
nand2:A
nand2:B
nand2:OUT
r1:1
r1:2
led2:A
led2:C
led3:A
led3:C
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
nand3:A
nand3:B
nand3:OUT
nand4:A
nand4:B
nand4:OUT
r2:1
r2:2
led4:A
led4:C
led5:A
led5:C
btn4:1.l
btn4:2.l
btn4:1.r
btn4:2.r
nand5:A
nand5:B
nand5:OUT
nand6:A
nand6:B
nand6:OUT
r3:1
r3:2
led6:A
led6:C
led7:A
led7:C
btn5:1.l
btn5:2.l
btn5:1.r
btn5:2.r
nand7:A
nand7:B
nand7:OUT
nand8:A
nand8:B
nand8:OUT
r4:1
r4:2
led8:A
led8:C
led9:A
led9:C
ERROR
RESET
led10:A
led10:C
btn6:1.l
btn6:2.l
btn6:1.r
btn6:2.r
nand9:A
nand9:B
nand9:OUT
nand10:A
nand10:B
nand10:OUT
r5:1
r5:2
led11:A
led11:C
led12:A
led12:C
btn7:1.l
btn7:2.l
btn7:1.r
btn7:2.r
nand11:A
nand11:B
nand11:OUT
nand12:A
nand12:B
nand12:OUT
r6:1
r6:2
led13:A
led13:C
led14:A
led14:C