// 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