Trying to run 2 timing funcions

I am trying to run 2 timing functions. I can get either one to run independently, but once one timer starts, the other one will NOT run. The basic jist is that the user starts the timer. The timer will run until the a hanging weight breaks the ‘test material’ and it falls and trips the limit switch below (see JPG for image).

Thanks for your help. I am a mfg engineer with very little software training.

StopWatch1.txt (3.41 KB)

Image from Original Post so we don’t have to download it. See this Simple Image Guide

Tester pic.JPG

…R

I can’t figure how your code is supposed to work - can you write a short description of the different parts please. And then tell us exactly what happens and what you want it to do that is different.

Also it is much easier if you post your code as a .ino file and if you post short programs within your text. Use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum

…R

Here’s the attached Arduino program in “INO” format. Also with better documentation. Thank you, Ben

Stopwatch1.ino (3.68 KB)

Jeez, why not just POST the code?

#include <LiquidCrystal.h>
LiquidCrystal lcd(3,4,8,9,10,11);
const int Start1 = 2;   //start switch for test station 1
const int WtDrop1 = A2;    //Weight drop switch for test station 1
const int Start2 = A0;       //start switch for test station 2
const int WtDrop2 = A1;   //Weight drop switch for test station 2
const int LED = 13;          //Arduino SMT LED

void setup(){
  lcd.begin(16,2);  //setup the LCD's number of columns and rows
  
  Serial.begin(9600);
  
  pinMode(Start1, INPUT);   //starts timer #1      
  pinMode(WtDrop1, INPUT); //Limit switch sensing if weight #1 has dropped       
  pinMode(Start2, INPUT);   //starts timer #2 
  pinMode(WtDrop2, INPUT); //Limit switch sensing if weight #2 has dropped      
  pinMode(LED, OUTPUT);
  lcd.clear();
}
double sec1 = 0;         //seconds for test 1
double hr1 = 0;         //hours test 1
double time1 = millis();  //timing variable for test 1
double runtime1 = 0;            //timing variable for test 1
double sec2 = 0;         //SECONDS FOR TESTER 2
double hr2 = 0;         //HOURS FOR TESTER 2
double time2 = millis();  //TIMING VARIABLE FOR TESTER 2
double runtime2 = 0;             //TIMING VARIABLE FOR TESTER 2

void loop()
{
  //START OF THE ACTUAL PROGRAM SO PAY CAREFUL ATTENTION TO THIS
lcd.clear();
digitalWrite(LED, LOW);  //turn off LED to start the program
delay(100);
  
 if(digitalRead(Start1)==HIGH) //If Start 1 button is on, please proceed
 {
    time1 = millis();
   while(digitalRead(WtDrop1) == LOW) //While the Weight Drop switch #1 is NOT depressed
   {
     runtime1 = millis();          //did use 'c'
   sec1 = (runtime1 - time1) / 1000;  //converts time in seconds, did use 'c'
   hr1 = sec1 / 3600;        //converts time to hours
   lcd.setCursor(1,0);  //set the cursor to column 1, line 1
   lcd.print(hr1);
   lcd.print(" Hr Test1 going");
   lcd.scrollDisplayLeft();  //shifting data on LCD
   delay(333);
   }
 }
  if(digitalRead(WtDrop1)==HIGH)  //If tart 1 button is on, please proceed 
   {
     while(digitalRead(Start1) == HIGH) //While the Weight Drop switch #1 is depressed
     {
       lcd.setCursor(1,0);
       lcd.print(hr1);
       lcd.print(" HR TEST#1 IS OVER ");
       lcd.scrollDisplayLeft();
       delay(333);
   }
  }
  if(digitalRead(Start1)==LOW) //if Start #1 button is OFF, tell user test is "test1 not used"
  lcd.print("Test1 NOT used");
  delay(100);
  
  //THE END OF TEST LOOP #1, NOW THE START OF TEST LOOP #2
   
if(digitalRead(Start2) == HIGH)  //if Start #2 is on, please proceed
 {
 time2 = millis();
   while(digitalRead(WtDrop2) == LOW) //While Weight Drop#2 switch is NOT depressed
   {
     runtime2 = millis();          
   sec2 = (runtime2 - time2) / 1000;  //converts time in seconds
   hr2 = sec2 / 3600;        //converts time to hours
   lcd.setCursor(0,1);  //set the cursor to column 0, line 2
   lcd.print(hr2);
   lcd.print(" Hr Test#2 Running ");
   //lcd.setCursor(0,1);  //set the cursor to column 0, line 2
   lcd.scrollDisplayLeft();  //shifting data on LCD
   digitalWrite(LED, HIGH);  //turn on LED if switch #2 is activated
   delay(222);
   //Serial.println(sec2);
   }
 }
 
   if(digitalRead(WtDrop2) == HIGH)  //if Start #2 is on, please proceed
     {
      while(digitalRead(Start2)==HIGH) //While Weight Drop #2 switch IS depressed
      {
       lcd.setCursor(0,1);
       lcd.print(hr2);
       lcd.print(" Hr--TEST#2 IS OVER ");
       //lcd.setCursor(0,1);
       //Serial.println(i);
       Serial.println("Weight2 Trigger tripped");
       lcd.scrollDisplayLeft();
       delay(200);
     }
   }
   if(digitalRead(Start2)==LOW)  //If Start #2 is OFF, tell user "test2 not used"
   lcd.setCursor(0,1);  //set the cursor to column 0, line 2
   lcd.print("Test2 NOT used");
  delay(100);
}

Either the variables used or the comments are wrong. Which is which?

if( digitalRead( WtDrop1 ) == HIGH ) {         // If Start 1 button is on, please proceed
   while( digitalRead( Start1 ) == HIGH ) {    // While the Weight Drop switch #1 is depressed

mrbenwalker@yahoo.com:
Also with better documentation.

I was hoping you would describe the program in a little essay that describes the job it needs to do - perhaps like this

  • The purpose of the project is to measure XXXX
  • The program waits for the operator to do YYYY then he presses a button to start MMMM happening.
  • etc
  • etc
  • etc

That way I can relate to the program code to the real-world job it is trying to accomplish.

...R

Here’s an essay summary of my program. There are 2 independent test stations. The goal is to hang a test material from the top with an attached weight. The user will start the timer once the material and weight are hung. The timer will continue until the material breaks. Once the test material breaks, the weight will fall and trip the limit switch below, thus stopping the timer. Typical test times range from 30 minutes up to one week.

I can get either timer to work, but NOT both at the same time. Whichever timer is selected first, it will only work on that one. Thanks, Ben

Thanks. That makes things a good deal clearer. However I don't understand the relevance of "2 independent test stations". Do you mean that one of them is used to record the time when the test starts and the other is used to record the time when the test ends?

For the long time periods you mention I reckon that millis() is not sufficiently accurate or stable and you should use a Real Time Clock (RTC) module.

...R

Thanks Robin. Either station can record the start & stop time for that particular test. For example, station #1 (on the left) can test substrate A, while station #2 can test substrate B. I want to know how long can a substrate adhere to the top bar before it breaks and trips the limit switch below. This test can be as short as 30 minutes or take up to 1 week. For example, the user could start station 1 Monday morning, but then start station 2 on Tuesday morning. The goal is to find the "time to failure" for substrates A & B (run on stations 1 & 2 respectively). Finally, either station is independent of one another (other than they share the same Arduino & LCD display).

I researched that the Millis function can run up to 50 days before it has issues. I only need to run up to 7 days max.

Thank you, Ben

mrbenwalker@yahoo.com:
Thanks Robin. Either station can record the start & stop time for that particular test.

You are missing the point I have been trying to clarify. If Station A records the start will it also record the stop time? Or is it possible that Station A will record the start time and Station B will record the stop time. (By the way, I am assuming that the two stations are using completely separate Arduinos - is that correct?).

I researched that the Millis function can run up to 50 days before it has issues. I only need to run up to 7 days max.

It will run for about 50 days but it does not measure time as accurately as an RTC because the Arduino does not run at precisely 16 MHz and the frequency can vary when the temperature changes.

…R

double time1 = millis();  //timing variable for test 1

What type does millis return? Why are you intentionally losing precision in your timing?

while(digitalRead(WtDrop1) == LOW) //While the Weight Drop switch #1 is NOT depressed
   {
     runtime1 = millis();          //did use 'c'
   sec1 = (runtime1 - time1) / 1000;  //converts time in seconds, did use 'c'
   hr1 = sec1 / 3600;        //converts time to hours
   lcd.setCursor(1,0);  //set the cursor to column 1, line 1
   lcd.print(hr1);
   lcd.print(" Hr Test1 going");
   lcd.scrollDisplayLeft();  //shifting data on LCD
   delay(333);
   }

Since you are using a while loop here your program is trapped here doing only the code inside this while loop until the weight drops. It is not running any of the rest of your code. The while loop blocks.

Why do you need a while loop there? Just let the loop function do the looping and read these things in if statements. That way you can deal with both stations instead of trapping yourself running only this small piece of the code.

You also seem to expect your buttons to read backwards. Have you added external pull-down resistors to facilitate this? If not then you should be using the internal pull-ups and pressed buttons should read LOW and not HIGH. If you've got them wired to read HIGH when pressed then you have them wired up backwards.

Rather than delaying by 200 and measuring the number of delays, you take the value of mills() when the test starts, and take the value of millis() again when you first see that the switch has closed. Subtract, and that's the elapsed time.

Most of the time, the loop() does nothing at all and exits. It's just going "Has the switch closed yet? nope. Has the switch closed yet? nope. Has the switch closed yet? Yes - ok, record the time, update the display, etc."