//================================================^================================================
//
//  https://forum.arduino.cc/t/problem-with-using-microswitches-to-measure-time-intervals/1315744/27
//
//  
//
//  Version    YY/MM/DD    Comments
//  =======    ========    ========================================================================
//  1.00       24/10/27    Running code
//
//
//
//Notes:
//  A sequence starts when the first switch closes.
//  The switches must be closed in sequence. 
//  i.e. 1st switch then the 2nd then the 3rd . . . then the 7th


/*//

#define switchClosed           LOW
#define switchOpen             HIGH


const byte heartbeatLED = 13;
const byte loopLED = 12;


byte pinSwitch[]             = {3, 4, 5, 6, 7, 8, 9};
byte lastSwitchState[]       = {switchOpen, switchOpen, switchOpen, switchOpen, switchOpen, switchOpen, switchOpen};
unsigned long timestamp[]    = {0, 0, 0, 0, 0, 0, 0};
unsigned long timeTaken[]    = {0, 0, 0, 0, 0, 0, 0};

byte totalSwitches           = sizeof(pinSwitch);

//timing stuff
unsigned long heartbeatTime;
unsigned long checkSwitchTime;


//                                          s e t u p ( )
//================================================^================================================
void setup()
{
  Serial.begin(1000000);  //... why not.

  pinMode(heartbeatLED, OUTPUT);
  pinMode(loopLED, OUTPUT);

  //in my case turn on internal pull-up resistors
  for (byte x = 0; x < totalSwitches; x++)
  {
    pinMode(pinSwitch[x], INPUT_PULLUP);
  }

  Serial.println("\nReady for next measurement");
  Serial.println("Switches are to close in order 0, 1, 2, 3, 4, 5, 6");

} //END of   setup()

//...
void loop() {


  static unsigned long counter;
  if ((counter & 0x3ff) == 0) {
//  if (1) {
    digitalWrite(loopLED, digitalRead(loopLED) == LOW ? HIGH : LOW);

  }
  counter++;

//  loopOG();
  loopLD();
}

//                                           l o o p ( )
//================================================^================================================
void loopLD()
{
  //========================================================================  T I M E R  heartbeatLED
  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatTime >= 500ul)
  {
    //restart this TIMER
    heartbeatTime = millis();

    //toggle the heartbeat LED
    digitalWrite(heartbeatLED, digitalRead(heartbeatLED) == HIGH ? LOW : HIGH);
  }

  //========================================================================  T I M E R  check switches
  //is it time to scan our switches (every 500us) ?
  if (micros() - checkSwitchTime >= 500ul)
  {
    //restart this TIMER
    checkSwitchTime = micros();

    checkSwitches();
  }

} //END of   loop()


//                                  c h e c k S w i t c h e s ( )
//===============================================^================================================
void checkSwitches()
{
  byte state;
  static byte switchNumber = 0;

  //========================================================================  pinSwitch[]
  state = digitalRead(pinSwitch[switchNumber]);

  //================================================
  //has this switch changed state ?
  if (lastSwitchState[switchNumber] != state)
  {
    //update to the new state
    lastSwitchState[switchNumber] = state;

    //========================
    //has this switch been closed ?
    if (state == switchClosed)
    {
      Serial.print("close # ");
      Serial.print(switchNumber);
      Serial.print("  ");
      Serial.println(micros());
  


      //the time this switch closed
      timestamp[switchNumber] = micros();

      //is this switch the first switch ?
      if (switchNumber > 0)
      {
        //time from the last switch to this switch going closed
        timeTaken[switchNumber] = timestamp[switchNumber] - timestamp[switchNumber - 1];

        //is this the last switch closed ?
        if (switchNumber >= totalSwitches - 1)
        {
          Serial.println("\nThe time the switch closed");

          //summarize the switch sequence
          for (byte x = 0; x < totalSwitches; x++)
          {
            Serial.print("Switch ");
            Serial.print(x);
            Serial.print(" : ");
            Serial.println(timestamp[x]);
          }

          Serial.println("\nMicroseconds between switch operation");

          for (byte x = 1; x < totalSwitches; x++)
          {
            Serial.print("Time from switch ");
            Serial.print(x - 1);
            Serial.print(" to switch ");
            Serial.print(x);
            Serial.print(" :");
            Serial.println(timeTaken[x]);
          }

          Serial.println("\nReady for next measurement");
        }
      }

    } //END of switch closed

    //========================
    //when a switch opens advance to the next switch in our sequence
    //has the switch been opened ?
    else if (state == switchOpen)
    {

      Serial.print("open # ");
      Serial.print(switchNumber);
      Serial.print("  ");
      Serial.println(micros());
  

      //get ready for the next switch to be read
      switchNumber++;

      //is this the last switch
      if (switchNumber == totalSwitches)
      {
        switchNumber = 0;
      }

    } //END of  switch opened

  } //END of this switch

} //END of   checkSwitches()


//int pinSwitch[8] = {3,4,5,6,7,8,9};

unsigned long ogTimestamp[7]={0,0,0,0,0,0,0};

int pinnumber=0;

unsigned long ogTimeTaken[6]={0,0,0,0,0,0};

// all done already 'K?
void setupX() {
  // put your setup code here, to run once:
  for (int i=0;i<7;i++){
    pinMode(pinSwitch[i], INPUT_PULLUP);
  }
  Serial.begin(115200);
}

void loopOG() {
  // put your main code here, to run repeatedly:
 if (digitalRead(pinSwitch[pinnumber])==0){
    ogTimestamp[pinnumber]=micros();
    pinnumber++;
 }

// if (micros()-ogTimestamp[0]>=20000000 && ogTimestamp[0]!=0 || pinnumber>6){
  if (pinnumber>6){
    printTime();
    resetsystem();
 }
}

unsigned long printTime(){
  for (int i=0; i < pinnumber; i++){
    Serial.print("  alt time ");
    Serial.print(i);
    Serial.print(" : ");
    Serial.println(ogTimestamp[i]);
  }

  for (int i=0; i < pinnumber - 1; i++) {
    ogTimeTaken[i] = ogTimestamp[i + 1] - ogTimestamp[i];
    Serial.print("  alt time from switch ");
    Serial.print(i);
    Serial.print(" to switch ");
    Serial.print(i + 1);
    Serial.print(" :");
    Serial.println(ogTimeTaken[i]);
  }
}

void resetsystem(){
  for (int i=0; i < 7; i++){
    ogTimestamp[i]=0;
  }
  for (int i=0;i < 6;i++){
    ogTimeTaken[i]=0;
  }
  pinnumber=0;
  Serial.println("Ready for next measurement");
  delay(1000);
}
















//================================================^================================================



//================================================^================================================

//A sequence starts when the first switch closes.
//The switches must be closed in sequence. 
//i.e. 1st switch then the 2nd then the 3rd . . . then the 6th


#define switchClosed           LOW
#define switchOpen             HIGH


const byte heartbeatLED      = 13;

byte pinSwitch[]             = {3, 4, 5, 6, 7, 8, 9};
byte lastSwitchState[]       = {switchOpen, switchOpen, switchOpen, switchOpen, switchOpen, switchOpen, switchOpen};
unsigned long timestamp[]    = {0, 0, 0, 0, 0, 0, 0};
unsigned long timeTaken[]    = {0, 0, 0, 0, 0, 0, 0};

byte totalSwitches           = sizeof(pinSwitch);
int pinnumber = 0;

//timing stuff
unsigned long heartbeatTime;
unsigned long checkSwitchTime;


//================================================^================================================
void setup()
{
  Serial.begin(115200);

  pinMode(heartbeatLED, OUTPUT);

  //in my case turn on internal pull-up resistors
  for (byte x = 0; x < totalSwitches; x++)
  {
    pinMode(pinSwitch[x], INPUT_PULLUP);
  }

  Serial.println("\nReady for next measurement");

} //END of   setup()


//================================================^================================================
void loop()
{
  //========================================================================  T I M E R  heartbeatLED
  //is it time to toggle the heartbeat LED ?
  if (millis() - heartbeatTime >= 500ul)
  {
    //restart this TIMER
    heartbeatTime = millis();

    //toggle the heartbeat LED
    digitalWrite(heartbeatLED, digitalRead(heartbeatLED) == HIGH ? LOW : HIGH);
  }

  //========================================================================  T I M E R  check switches
  //is it time to scan our switches (every 500us) ?
  if (micros() - checkSwitchTime >= 500ul)
  {
    //restart this TIMER
    checkSwitchTime = micros();

    checkSwitches();
  }

} //END of   loop()


//================================================^================================================
void checkSwitches()
{
  byte state;
  static byte switchNumber = 0;

  //========================================================================  pinSwitch[]
  state = digitalRead(pinSwitch[switchNumber]);

  //================================================
  //has this switch changed state ?
  if (lastSwitchState[switchNumber] != state)
  {
    //update to the new state
    lastSwitchState[switchNumber] = state;

    //========================
    //has this switch been closed ?
    if (state == switchClosed)
    {
      Serial.print("Switch #");
      Serial.println(switchNumber);

      //the time this switch closed
      timestamp[switchNumber] = micros();

      //is this switch the first switch ?
      if (switchNumber > 0)
      {
        //time from the last switch to this switch going closed
        timeTaken[switchNumber] = micros() - timestamp[switchNumber - 1];

        //is this the last switch closed ?


        if (switchNumber >= totalSwitches - 1)


        {
          Serial.println("\nThe time the switch closed");

          //summerize the switch sequence
          for (byte x = 0; x < totalSwitches; x++)
          {
            Serial.print("Switch ");
            Serial.print(x);
            Serial.print(" : ");
            Serial.println(timestamp[x]);
          }

          Serial.println("\nTime between switch operation");

          for (byte x = 1; x < totalSwitches; x++)
          {
            Serial.print("Time from switch ");
            Serial.print(x - 1);
            Serial.print(" to switch ");
            Serial.print(x);
            Serial.print(" :");
            Serial.println(timeTaken[x]);
          }

          Serial.println("\nReady for next measurement");
        }
      }

    } //END of switch closed

    //========================
    //has the switch been opened ?
    else if (state == switchOpen)
    {
      //get ready for the next switch to be read
      switchNumber++;

      //is this the last switch
      if (switchNumber == totalSwitches)
      {
        switchNumber = 0;
      }

    } //END of  switch opened

  } //END of this switch

} //END of   checkSwitches()
*/
/*

int pinSwitch[8] = {3,4,5,6,7,8,9};

unsigned long timestamp[7]={0,0,0,0,0,0,0};

int pinnumber=0;

unsigned long timeTaken[6]={0,0,0,0,0,0};

void setup() {
  // put your setup code here, to run once:
  for (int i=0;i<7;i++){
    pinMode(pinSwitch[i], INPUT_PULLUP);
  }
  Serial.begin(115200);
}

void loop() {
  // put your main code here, to run repeatedly:
 if (digitalRead(pinSwitch[pinnumber])==0){
    timestamp[pinnumber]=micros();
    pinnumber++;
 }

// if (micros()-timestamp[0]>=20000000 && timestamp[0]!=0 || pinnumber>6){
  if (pinnumber>6){
    printTime();
    resetsystem();
 }
}

unsigned long printTime(){
  for (int i=0; i < pinnumber; i++){
    Serial.print("Switch ");
    Serial.print(i);
    Serial.print(" : ");
    Serial.println(timestamp[i]);
  }

  for (int i=0; i < pinnumber - 1; i++) {
    timeTaken[i] = timestamp[i + 1] - timestamp[i];
    Serial.print("Time from switch ");
    Serial.print(i);
    Serial.print(" to switch ");
    Serial.print(i + 1);
    Serial.print(" :");
    Serial.println(timeTaken[i]);
  }
}

void resetsystem(){
  for (int i=0; i < 7; i++){
    timestamp[i]=0;
  }
  for (int i=0;i < 6;i++){
    timeTaken[i]=0;
  }
  pinnumber=0;
  Serial.println("Ready for next measurement");
  delay(1000);
}
*/
/* alto777 modified */

# include "digitalWriteFast.h"

const byte pinSwitch[] = {3,4,5,6,7,8,9};
const byte nSwitches = sizeof pinSwitch / sizeof *pinSwitch;

unsigned long timeStamp[nSwitches];

void setup() {
  for (int i=0;i<7;i++){
    pinMode(pinSwitch[i], INPUT_PULLUP);
  }
  Serial.begin(115200);

  resetSystem();
}

# define PRESST LOW
# define RESET  7000  // flame out time ms
int switchNumber;     // next expected switch index

void loopx() {
  static unsigned long startTime;

  if (digitalRead(pinSwitch[switchNumber]) == PRESST) {
    timeStamp[switchNumber] = micros();
    if (switchNumber == 0) startTime = millis();
    switchNumber++;
  }

  if (millis() - startTime > RESET && timeStamp[0] != 0 || switchNumber == nSwitches) {
    printReport(nSwitches);
    resetSystem();
  }
}

void loop() {
  static unsigned long startTime;

  int cc = 0;
  if (digitalReadFast(3) == PRESST) {
    if (digitalReadFast(3) == PRESST) cc++;
    if (digitalReadFast(3) == PRESST) cc++;
    if (digitalReadFast(3) == PRESST) cc++;
    if (digitalReadFast(3) == PRESST) cc++;
    if (digitalReadFast(3) == PRESST) cc++;
    if (digitalReadFast(3) == PRESST) cc++;
    if (digitalReadFast(3) == PRESST) cc++;
  }

  if (cc && cc != 7) {
    Serial.println(cc);
    cc = 0;
  }
}

unsigned long printReport(byte nItems)
{
  for (byte ii = 0; ii < nItems; ii++) {
    Serial.print("Switch ");
    Serial.print(ii);
    Serial.print(" : ");
    Serial.println(timeStamp[ii]);
  }

  for (byte ii = 0; ii < nItems - 1; ii++) {
    Serial.print("Time ");
    Serial.print(ii);
    Serial.print(" to ");
    Serial.print(ii + 1);
    Serial.print(" : ");
    Serial.println(timeStamp[ii + 1] - timeStamp[ii]);
  }
}

void resetSystem()
{
  timeStamp[0] = 0;
  switchNumber = 0;
  Serial.println("Ready for next measurement");
//  delay(1000); ready or not?
}