Sunday, March 15, 2015

Clock Project - Progress Update


Phase 2 is moving along nicely.  I have completed all of the projects in the booklet that came with the Arduino kit, and have read all of the relevant chapters in the book Teach Yourself Arduino Programming in 24 Hours by Richard Blum, published by Sams.

Today I started writing and testing some clock code.  I built a simple circuit to test the code:  it has two push button switches, a green LED for each side to indicate whose turn it is, and a red LED for each flag.  The circuit looks something like this (drawn using the Fritzing program which can be downloaded at http://fritzing.org/home/).



Here is a schematic for the circuit:  (drawn using the website http://www.digikey.com/schemeit/# )



The switches are connected to pins 2 and 3 on the Arduino.  A 10 K ohm pull up resistor keeps the pin at 5 volts until the button is pressed which pulls the pin to ground.  In the code you will see that I have to initialize pins 2 and 3 for digital input.

Pins 8 and 9 are connected to the green LEDs and pins 10 and 11 are connected to the red LEDs.  These pins are configured for digital output.


And now... the program

The program, called a sketch is listed below.  It flows something like this:


  • Initialize the variables
  • Setup function that initializes the input and output pins and sets variable states (every sketch has to have this function)
  • Loop function (also required in every sketch)  executes in a never ending loop.  This is where the body of code is.  The basic parts of my code in the loop:
    • Don't start counting until the first button press
    • On a button press, light the correct LED, and assign the "turn" variable to the opponent
    • Check if 1000 milliseconds have gone by,  if so, call the subroutine to print the times to the serial port (can be monitored on the PC)
    • Check to see if either time is down to zero, if so, light the corresponding LED.
  • Any other functions.  I only have one, to print the time to the serial port.  Later, this is where the code to write to the LCD displays will live.
This is what the output looks like on the serial monitor screen:  
(for this example, each player has 15 seconds on their clock)

                                                                     (nothing happens until the 1st button press)
Player 1 button                                             (Green LED for player 2 lights)
2  Player 1 = 15  Player 2 = 15
2  Player 1 = 15  Player 2 = 14
2  Player 1 = 15  Player 2 = 13
2  Player 1 = 15  Player 2 = 12
2  Player 1 = 15  Player 2 = 11
Player 2 button                                             (Green LED for player 1 lights)
1  Player 1 = 15  Player 2 = 11
1  Player 1 = 14  Player 2 = 11
1  Player 1 = 13  Player 2 = 11
1  Player 1 = 12  Player 2 = 11
1  Player 1 = 11  Player 2 = 11
Player 1 button                                             (Green LED for player 2 lights)
2  Player 1 = 11  Player 2 = 11
2  Player 1 = 11  Player 2 = 10
2  Player 1 = 11  Player 2 = 9
2  Player 1 = 11  Player 2 = 8
2  Player 1 = 11  Player 2 = 7
2  Player 1 = 11  Player 2 = 6
2  Player 1 = 11  Player 2 = 5
2  Player 1 = 11  Player 2 = 4
2  Player 1 = 11  Player 2 = 3
2  Player 1 = 11  Player 2 = 2
2  Player 1 = 11  Player 2 = 1
2  Player 1 = 11  Player 2 = 0
Player 2 Flag                                                 (Red LED for player 2 lights)
2  Player 1 = 11  Player 2 = 0


Some thoughts and plans:


  • The way the code is written, if a player hits the clock using less than a second, he will not have any time come off his clock.  (like the old Master Quartz clocks).  I think think the best fix for this is to update the clock every 1/10 second.  I tested this and it worked fine, but the serial display filled up really fast, so I put it back to 1 second for this blog post.
  • The program continues to run after one player flags.  That players clock will not count down past zero, but if he hits his clock, the opponent's flag will count down, so that it is possible to have both players flag.  This is the correct behavior for USCF rules.
  • I will need to add code for common options:
    • Delay time before the clocks start to count
    • Increment time added each move
    • More than one time period
  • Once I get some LCD displays, I will need to write code for:
    • Choosing options and setting initial time
    • Displaying the time on the LCD displays.



Here is the sketch listing:

//   
//  Chess Clock Practice Sketches
//
//  Bob Nolan
//  3/15/2015
//

// Declare Global Variables
unsigned int timeR1;
unsigned int timeR2;
unsigned long lastMilliS;
int turn;
int ledPin1 = 8;
int ledPin2 = 9;
int switchPin1 = 2;
int switchPin2 = 3;
int flagPin1 = 10;
int flagPin2 = 11;
boolean checkButton;
boolean flag1=0;
boolean flag2=0;

void setup() {
  Serial.begin(9600);
  timeR1 = 15;                // set initial time
  timeR2 = 15;                // need to add user input routine
  turn=0;
  pinMode(ledPin1,OUTPUT);
  pinMode(ledPin2,OUTPUT);
  pinMode(switchPin1,INPUT);
  pinMode(switchPin2,INPUT);
  pinMode(flagPin1,OUTPUT);
  pinMode(flagPin2,OUTPUT);
}

void loop() {  
 if (turn==0){              // dont start counting until 1st button press
    lastMilliS=millis();
 }
  if (millis()-lastMilliS >= 1000) {   // every 1000 msec, update time
    lastMilliS=millis();
    if((turn==1)&&(!flag1)){
      timeR1--;
    }
    if((turn==2)&&(!flag2)){
      timeR2--;
    }
    printTime();
  }
  checkButton=digitalRead(switchPin1);   // player 1 button press
  if(!checkButton && (turn!=2)){
    digitalWrite(ledPin2,HIGH);
    digitalWrite(ledPin1,LOW);
    turn = 2;
    Serial.println("Player 1 button");
    printTime();
    
  }
  checkButton=digitalRead(switchPin2);   // player 2 button press
  if(!checkButton && (turn!=1)){
    digitalWrite(ledPin1,HIGH);
    digitalWrite(ledPin2,LOW);
    turn = 1;
    Serial.println("Player 2 button");
    printTime();
   
  }
  if((timeR1<=0)&&(!flag1)){            // player 1 flag
    digitalWrite(flagPin1,HIGH);
    Serial.println("Player 1 Flag");
    flag1=1;
  }
  if((timeR2==0)&&(!flag2)){            // player 2 flag
    digitalWrite(flagPin2,HIGH);
    Serial.println("Player 2 Flag");
    flag2=1;    
  }
}

void printTime() {                      // print time function
   Serial.print(turn);                  
   Serial.print("  Player 1 = ");
   Serial.print(timeR1);
   Serial.print("  Player 2 = ");
   Serial.println(timeR2);
}

2 comments:

  1. What about using MATLAB/Simulink for programming?

    ReplyDelete
    Replies
    1. Unfortunately I have no experience with MATLAB/Simulink. The Arduino version of C is about all I can handle.

      Delete