CHESS stopwatch

Hello, I have problem with timing. I´m programming something like chess stopwatch with 2 lines of time (1 for each player RF/GDP).

It´s working with mechanic connection PIN 6 and 3 to GND (just hold second end of wire in hand)…Look at attached picture with orange wire.
LCD is I2C with backlight.
I´m using slovak language, so, some variabes or declarations is in slovak. :wink:

Problem No. 1:
Look at attached picture with LCD display. Problem is, that seconds are counting to neverending number… I was trying to solve it but I´m lost :confused: Same problem is minutes and hours…

Problem No. 2:
I want to do something like START/STOP (PAUSE) button on CD players. Ideally, if I start RF player–>GDP will stop counting (e.g. 01:24:53) and if I start GDP player–>RF will stop and GDP continue counting (from last time 01:24:53).

In future this will works on RFID tags, but now, I need to solve this 2 problems.

#include <Time.h>
#include <TimeLib.h>
#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal.h>




const int BUTTON = 6;
const int BUTTONGDP = 3;

//const String INITIAL_MESSAGE = "press to start";
const String TIMING_MESSAGE = "Dominator c.1 RP2017";

int buttonVal = 0;
int buttonOldVal = 0;
int buttonState = 0;
int milisekundy = 0;
int seconds = 0;
int minutes = 0;
int hours = 0;
int sekundy = 0;

int buttonGDPVal = 0;
int buttonGDPOldVal = 0;
int buttonGDPState = 0;
int milisekundyGDP = 0;
int secondsGDP = 0;
int minutesGDP = 0;
int hoursGDP = 0;
int sekundyGDP = 0;

long startTime = 0;
long endTime = 0;
bool showTimer = false;

long startTimeGDP = 0;
long endTimeGDP = 0;
boolean showTimerGDP = false;



LiquidCrystal_I2C lcd(0x3F, 20, 4);


void setup() {

  lcd.init();
  lcd.backlight();
  lcd.print(TIMING_MESSAGE);

 
  pinMode(BUTTON, INPUT);
  pinMode(BUTTONGDP, INPUT);
  
}

void startTimer() {

  showTimer = true;
  startTime = millis();
  milisekundy = millis() / 1000;
  //milisekundyGDP = millis()/1000;

  lcd.clear();
  lcd.print(TIMING_MESSAGE);

}

void startTimerGDP() {

  showTimerGDP = true;
  startTimeGDP = millis();
  //milisekundy = millis()/1000;
  milisekundyGDP = millis() / 1000;

   lcd.clear();
  lcd.print(TIMING_MESSAGE);

}

void endTimer() {

  lcd.clear();
  //lcd.print(INITIAL_MESSAGE);
   lcd.setCursor(0, 1);
  lcd.print(endTime / 1000);

}


void endTimerGDP() {


  lcd.clear();
  //lcd.print(INITIAL_MESSAGE);
  lcd.setCursor(0, 2);
  lcd.print(endTime / 1000);
}


void printTime() {

  long milisekundy = endTime = millis() - startTime;
  long sekundy = milisekundy / 1000;
  long minuty = milisekundy / 60000;


  lcd.setCursor(0, 3);
  lcd.print ("RF = ");
  lcd.print(milisekundy / 3600000); //hodiny
  lcd.print(":");
  lcd.print(minuty);    //minuty
  lcd.print(":");
  lcd.print(sekundy);

  lcd.setCursor (0, 0);
  lcd.print ("RP2017 Dominator c.1");
  lcd.setCursor(0,1);
  lcd.print("--------------------");
}

void printTimeGDP()
{
  long milisekundyGDP = endTimeGDP = millis() - startTimeGDP;
  long sekundyGDP = milisekundyGDP / 1000;
  long minutyGDP = milisekundyGDP / 60000;

  lcd.setCursor(0, 2);
  lcd.print ("GDP= ");
  lcd.print(milisekundyGDP / 3600000); //hodiny
  lcd.print(":");
  lcd.print(minutyGDP);    //minuty
  lcd.print(":");
  lcd.print(sekundyGDP);

  lcd.setCursor (0, 0);
  lcd.print ("RP2017 Dominator c.1");
}


void loop() {

  buttonVal = digitalRead(BUTTON);
  buttonGDPVal = digitalRead(BUTTONGDP);
  

  if (buttonVal == HIGH && buttonOldVal == LOW)
 {
    buttonState = 1 - buttonState;

   if (buttonState == 1) 
   {
      startTimer();
    } else {
      endTimer();
    }

  }

  if (showTimer == true) {
    printTime();
  }

  buttonOldVal = buttonVal;

  if (buttonGDPVal == HIGH && buttonGDPOldVal == LOW) {
    buttonGDPState = 1 - buttonGDPState;

    if (buttonGDPState == 1) {
      startTimerGDP();
    } else {
      endTimer();

    }
  }
  if (showTimerGDP == true) {
    printTimeGDP();
  }
  buttonGDPOldVal = buttonGDPVal;
}

First of all: please edit your first post and put code tags (the “</>”-button in the editor) around your code part.

I have difficulties to understand how you stopwatch should work. The chess timers I now work the way that if one side activates the timer, the other timer stops and this side runs and vice-versa. In your code both timers could run at the same time. Is that your intention?

To convert a millisecond into hours, minutes and seconds you can use the following template:

uint32_t milliseconds = 33422334; // or any other value
uint32_t seconds = (milliseconds / 1000) % 60;
uint32_t minutes = (milliseconds / 1000 / 60) % 60;
uint32_t hours = (milliseconds / 1000 / 60 / 60);

Thank a lot. Now, scetch counting 1...2....3.....59....09...19..29......99....10....11...12...13... It´good but second character stay on "9" until counting count to 9 and higher...

Now, problem No.2... Yes, you´re right, I need solve It this way.

" The chess timers I now work the way that if one side activates the timer, the other timer stops and this side runs and vice-versa. In your code both timers could run at the same time. Is that your intention? "

Now, scetch counting 1…2…3…59…09…19…29…99…10…11…12…13… It´good but second character stay on “9” until counting count to 9 and higher…

You should either clear the screen before each update or print the numbers in double digits:

void print_double_digit(uint8_t num) {
  if (num < 10) {
    lcd.print("0");
  }
  lcd.print(num);
}

To get the desired functional behavior, call the opposite EndTimer function inside the StartTime function. But then you should remove the lcd.clear() call from the EndTimer functions, I guess.

Problem No.1 is totally solved. Thank you pylon program of counting under 10 sec/min is after little modification fully function. I´ve just write simple “if…” code to void printTime and it´s working.

Here is that simple code

if (sekundyGDP<10){
    lcd.print(" ");}

  if (minutyGDP<10) {
    lcd.print(" ");}

Thank you a lot. Now, harder problem No. 2 :slight_smile:

Thank you a lot. Now, harder problem No. 2

Please describe in more detail what problem no. 2 is. I thought that the last sentence of my last post describes how to solve what I think your problem is. If it doesn't you have to provide more details.

How I wrote:

I want to do something like START/STOP (PAUSE) button on CD players. Ideally, if I start RF player-->GDP will stop counting (e.g. 01:24:53) and if I start GDP player-->RF will stop and GDP continue counting (from last time 01:24:53).

Your definition was more exactly...

I have difficulties to understand how you stopwatch should work. The chess timers I now work the way that if one side activates the timer, the other timer stops and this side runs and vice-versa. In your code both timers could run at the same time. Is that your intention?

I know, now its working 2 players at the same time. My vision of function:

1) power on- no player´s time run, LCD backlight turn on, LCD write initial message

2) switch to RF player (PIN6) ----> RF player´s time counting

3) switch to GDP player (PIN3) ----> RF player´s time stop (e.g. 00:03:18)---> GDP player´s time start counting

4) switch to RF player (PIN6)----> GDP player´s time stop and RF player´s time continue from last value (00:03:18)

and still this way....

It´s classical chess stopwatch principe.

1) power on- no player´s time run, LCD backlight turn on, LCD write initial message

2) switch to RF player (PIN6) ----> RF player´s time counting

3) switch to GDP player (PIN3) ----> RF player´s time stop (e.g. 00:03:18)---> GDP player´s time start counting

4) switch to RF player (PIN6)----> GDP player´s time stop and RF player´s time continue from last value (00:03:18)

Why don't you just implement that? You already have functions to start and stop each timer. Just act accordingly if one of the switches is activated. You just have to remove the lcd.clear() from the EndTimer functions as I wrote earlier.

Try that and post the resulting sketch. If it doesn't work, provide information about what didn't work as you expected it. We will try to help you then. We don't write the code for you.