// 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("");
      }
*/
ERROR
RESET