int Home = 2; //Cylinder Home Sensor int RodOut = 3;// Rod Out Sensor int LedGrn1 = 4; //Test 1 ok int LedGrn2 = 5; //Test 2 ok int LedGrn3 = 6; //Test 3 ok int LedRed = 7; //Alarm LED int DUT = 8; //Device Under Test int Start = 9; //Start Button on PCB int LedYelRodOut = 10; //Timer ON LED unsigned long previous = 0; const long interval1 = 1000; // time cylinder rod stays out const long interval2 = 1000; //interval2 gives 1/2 second to ensure switch is fully depressed before alarm changed to 1 sec bool Test1 = false; bool Test2 = false; bool Test3 = false; bool Alarm = false; bool Run = false; bool AlarmOn = false; void setup() { pinMode(Home, INPUT); pinMode(RodOut, INPUT); pinMode(LedGrn1, OUTPUT); pinMode(LedGrn2, OUTPUT); pinMode(LedGrn3, OUTPUT); pinMode(LedRed, OUTPUT); pinMode(DUT, INPUT); pinMode(Start, INPUT); pinMode(LedYelRodOut, OUTPUT); } void loop() // TEST 1 ROUTINE { if ( digitalRead (Start) == HIGH) { Run = true; } unsigned long current = millis(); //current register will increment in milliseconds. if ((Run == true) && (digitalRead(Home) == HIGH) && (digitalRead (DUT) == LOW) && (Test1 == false) && (Alarm == false)) //Test1 is ok. { Test1 = true; digitalWrite (LedGrn1, Test1); previous = current; } //since Test 1 is ok,we're kicking off the timer process to prepare for the timed cylinder activation. // Note: we had to put Test1==false, in the if statement, else the timer would reset again at the rod return cycle. // If Test 1 is ok we will ignore lines 62 to 68 and go directly to line 72. // If Test1 fails: //Here too, we need to have a timer to give some time for the alarm to sound otherwise, the alarm will reset //immediately in the reset all sequence. On the other hand, if we don't put AlarmOn bool, the alarm will //be enabled again immediately after the timer has timed-out. if ((Run == true) && (Test1 == false) && (AlarmOn == false)) //Alarm if Test1 fails. { Alarm = true; digitalWrite (LedRed, Alarm); AlarmOn = true; previous = current; } // TIMER >> ACTIVATE CYLINDER ROUTINE if ((Run == true) && current - previous < interval1 && (Test1 == true)) { digitalWrite (LedYelRodOut, HIGH); } else { digitalWrite (LedYelRodOut, LOW); } //TEST 2 ROUTINE if ((Test1 == true) && (digitalRead (RodOut) == true) && (digitalRead (DUT) == HIGH)) { Test2 = true; digitalWrite (LedGrn2, Test2); } if ((Run == true) && (current - previous > interval2) && (Test2 == false) ) //interval gives time for sw. to activate before alarm { Alarm = true; digitalWrite (LedRed, Alarm); } //TEST 3 ROUTINE if ((digitalRead(RodOut) == LOW) && (digitalRead (DUT) == LOW) && (Test1 == true) && (Test2 == true) && (Alarm == false)) { Test3 = true; digitalWrite (LedGrn3, Test3); } if ((Test2 == true) && (Test3 == false) && (digitalRead(Home) == HIGH)) { Alarm = true; digitalWrite (LedRed, Alarm); } if ((current - previous > 2500) && ((Alarm == true) || (Test3 == true))) // this is a general reset and will avoid the program getting stuck at any point { Test1 = false; Test2 = false; Test3 = false; Alarm = false; Run = false; AlarmOn = false; digitalWrite (LedGrn1, Test1); digitalWrite (LedGrn2, Test2); digitalWrite (LedGrn3, Test3); digitalWrite (LedRed, Alarm); } }