Showing posts with label Clock Project. Show all posts
Showing posts with label Clock Project. Show all posts

Sunday, December 6, 2015

Clock Progress - Wood Cut for Case


The wood is all cut out for the clock case.  For this first attempt, I used some cheap 1/2 pine craft board from Lowes so I could make all of my mistakes at a low cost.   If this turns out, I may re-build it with some nicer wood.




Next is sanding, gluing and staining.  Then the lever mechanism and the electronics will be stuffed inside and I will have a real chess clock.

Saturday, November 14, 2015

Clock Progress - Lever mechanism for mechanical buttons

I have started working on my clock again.  Here is a picture of the lever mechanism for the mechanical buttons.   Magnets below each arm give the feel that the buttons are snapping into place.


Saturday, April 25, 2015

Thursday, April 23, 2015

Working Prototype

Here is my working Prototype

It is hard to get a good picture of the displays.





The clock on the left is counting down.  The button on the left is lit indicating which player is on the move.  I will try to post a video soon.


Making all of the wiring cables, and soldering everything to the perf board took a lot more time than I had expected.




Saturday, April 4, 2015

Plastic Prototype Enclosure


It is time to move off the breadboards and into the prototype in a box phase.   I bought a plastic storage box for about $4.  It is made from polypropylene which is easy to cut.  I drilled 1 inch holes in the bottom for the two lighted switches, and cut a large rectangle in the side for the displays.


This box is much larger than the final wood version will be.  The wood version will be shaped much more like a Chronos; a bit wider, lower and narrower, with a sloped front for the displays.  I also plan to use mechanical plungers instead of the buttons, but this will work for the prototype.  These buttons have an LED inside that I will use to indicate who is to move.  The sides of this box are transparent, so I won't have to open the box to show off the electronics inside.

Next step is to make wiring harnesses for the displays.  The headers on the displays have male pins spaced 0.1 inches.  This page has instructions for building the wiring harness.  Since the displays only use 12 of the 16 pins, and they are in groups of 6, I will likely use two 6 pin housings for each display.  I can get all the parts at the local electronics shop.

More pictures to follow.


Friday, March 27, 2015

It's a Clock !


I've got the basic clock sending time output to the displays.  The LEDs show who is on move, and the buttons switch the clocks and LEDs.



What is left to do (software):
- move counter
- increment and delay
- multiple periods
- Setup routine for setting time and choosing options using buttons
- save settings to non-volatile memory

What is left to do (hardware)
- switches (on/off and pause)
- 4 buttons for navigating the menus
- prototype case, probably plastic
- eventually a nice wooden case, with mechanical plungers.


Sketch Update

I modified the printTime() function to convert the time remaining for each player from 1/10 seconds to H:MM:SS and to write that to the displays, by calling a new writeNum() function.


// Function to write the time to the displays
void printTime() {                      // print time function
  int secDis1;
  int secDis10;
  int minDis1;
  int minDis10;
  int hrDis1;
  int secs;
  
  secs = timeR1 / 10;                  // convert 1/10 sec to H:MM:SS
  hrDis1 = secs / 3600;
  secs = secs % 3600;
  minDis10 = secs / 600;
  secs = secs % 600;
  minDis1 = secs / 60;
  secs = secs % 60;
  secDis10 = secs / 10;
  secDis1 = secs % 10;
  
  writeNum(hrDis1,3,1);
  writeNum(minDis10,7,1);
  writeNum(minDis1,10,1);
  writeNum(secDis10,14,1);
  writeNum(secDis1,17,1);
  
  secs = timeR2 / 10;                  // convert 1/10 sec to H:MM:SS
  hrDis1 = secs / 3600;
  secs = secs % 3600;
  minDis10 = secs / 600;
  secs = secs % 600;
  minDis1 = secs / 60;
  secs = secs % 60;
  secDis10 = secs / 10;
  secDis1 = secs % 10;
  
  writeNum(hrDis1,3,2);
  writeNum(minDis10,7,2);
  writeNum(minDis1,10,2);
  writeNum(secDis10,14,2);
  writeNum(secDis1,17,2); 
}




Part of the writeNum() function:




// function to write digits to the displays
void writeNum(int charDigit, int charPos, int turn){
   switch (charDigit){
      case 0:
         if (turn==1){
           lcd1.setCursor(charPos,0);
           lcd1.write(1);
           lcd1.write(2);
           lcd1.write(2);
           lcd1.setCursor(charPos,1);
           lcd1.write(3);
           lcd1.write(32);
           lcd1.write(3);
           lcd1.setCursor(charPos,2);
           lcd1.write(3);
           lcd1.write(32);
           lcd1.write(3);
           lcd1.setCursor(charPos,3);
           lcd1.write(3);
           lcd1.write(2);
           lcd1.write(4);
         }
         else{
           lcd2.setCursor(charPos,0);
           lcd2.write(1);
           lcd2.write(2);
           lcd2.write(2);
           lcd2.setCursor(charPos,1);
           lcd2.write(3);
           lcd2.write(32);
           lcd2.write(3);
           lcd2.setCursor(charPos,2);
           lcd2.write(3);
           lcd2.write(32);
           lcd2.write(3);
           lcd2.setCursor(charPos,3);
           lcd2.write(3);
           lcd2.write(2);
           lcd2.write(4); 
         }
         break;

and this continues for each of the 10 digits, plus a blank space if I want to use that later.

Thursday, March 26, 2015

Functioning Clock and BIG NUMBERS

Working Chess Clock

I now have a functioning chess clock.  Lots of work yet to be done, but the basic functions are all working.

I took the code from the earlier clock test, and changed it from sending the output to the serial port, to writing the time to the displays.  I also made the updates every 1/10 second.

This picture shows the two buttons and the green LEDs which indicate whose turn it is to move:


The buttons are wired to pins 2 and 3, with 10 K ohm pull-up resistors to +5V.  Closing the switch pulls the pin to ground.

The LED anodes are connected to pins 4 and 5, with 560 ohm resistors between the cathode and ground.  (similar to the schematics published earlier, but the pins have changed).

This next picture shows the display for player 2.  Note, it is counting down tenths of seconds.


I will attach the sketch at the bottom of this post.


Big Numbers

I also did some work on making large numbers for the time display.  (I don't know why this blog page insists on turning the image sideways, it is horizontal on my PC, but you can still see the large digits).



These large numbers were made by combining 7 custom characters.  The custom characters are numbered 0 through 7, but I used 1 through 7 because those were the numbers I used when I drew out the patterns on graph paper.  Note, if you use character 0, the data type must be declared something like this:  lcd.write((byte)0);   It has something to do with control codes vs. custom characters.  Luckily, since I used 1-7, I didn't run into this issue, but read about it on other web pages.

Some pieces of the sketch that created these large numbers:

#include <LiquidCrystal.h>
LiquidCrystal lcd1(6,7,9,10,11,12);
LiquidCrystal lcd2(6,8,9,10,11,12);

// create bit maps of the custom characters.  5 columns by 8 rows.
byte customChar1[8] = {
  B00000,
  B00000,
  B00000,
  B00000,
  B00011,
  B00011,
  B00011,
  B00011
};
.
.
.

void setup() {
   lcd1.begin(20, 4);
   lcd2.begin(20, 4);
   lcd1.createChar(1,customChar1);   //  assign the bitmap pattern to character 1
   .
   .
   .
}

void loop() {
   lcd1.setCursor(3,0);
   lcd1.write(1);     // write character 1
   .
   .
   .
}


And now, my most up to date clock sketch (from the photos at the top of this post):



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

// Include LCD display library and set up pinouts
#include <LiquidCrystal.h>
LiquidCrystal lcd1(6,7,9,10,11,12);
LiquidCrystal lcd2(6,8,9,10,11,12);

// Declare Global Variables
unsigned int timeR1;
unsigned int timeR2;
unsigned long lastMilliS;
int turn;
int ledPin1 = 4;
int ledPin2 = 5;
int switchPin1 = 2;
int switchPin2 = 3;
boolean checkButton;
boolean flag1=0;
boolean flag2=0;

void setup() {
  timeR1 = 150;                // set initial time.  Time is in 1/10 sec
  timeR2 = 150;                // need to add user input routine
  turn=0;
  pinMode(ledPin1,OUTPUT);
  pinMode(ledPin2,OUTPUT);
  pinMode(switchPin1,INPUT);
  pinMode(switchPin2,INPUT);
  lcd1.begin(20,4);
  lcd2.begin(20,4);
  lcd1.print("Player 1");
  lcd2.print("Player 2");
}

void loop() {  
 if (turn==0){              // dont start counting until 1st button press
    lastMilliS=millis();
 }
  if (millis()-lastMilliS >= 100) {   // every 100 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;
    printTime();
    
  }
  checkButton=digitalRead(switchPin2);   // player 2 button press
  if(!checkButton && (turn!=1)){
    digitalWrite(ledPin1,HIGH);
    digitalWrite(ledPin2,LOW);
    turn = 1;
    printTime();
   
  }
  if((timeR1<=0)&&(!flag1)){            // player 1 flag
    lcd1.setCursor(0,2);
    lcd1.print("Flag");
    flag1=1;
  }
  if((timeR2==0)&&(!flag2)){            // player 2 flag
    lcd2.setCursor(0,2);
    lcd2.print("Flag");
    flag2=1;    
  }
}

void printTime() {                      // print time function
   lcd1.setCursor(0,1);
   lcd1.print(timeR1);
   lcd1.print("  ");
   lcd2.setCursor(0,1);
   lcd2.print(timeR2);
   lcd2.print("  ");
}

Wednesday, March 25, 2015

More progress with the displays


I have both displays hooked up and working independently now, and like I had hoped, it only takes 7 output pins to drive both displays.

Here is how they are wired

LCD Pin Arduino Pin
1 Logic Gnd Gnd
2 Logic +5V +5V
3 Contrast Pot sweep
4 RS Pin 6
5 RW Gnd
6 EN (LCD1) Pin 7
6 EN (LCD 2) Pin 8
7
8
9
10
11 DB4 Pin 9
12 DB5 Pin 10
13 DB6 Pin 11
14 DB7 Pin 12
15 Backlight +5V +5V
16 Backlight Gnd Gnd

I used one potentiometer to control the contrast on both displays.  All of the connections go to both displays except the enable which has pin 7 going to display 1 and pin 8 going to display 2.

Sample Sketch

I used the following sketch to test that I had both displays wired correctly.  Notice that I had to define the pinouts for LCD1 and LCD2.


#include <LiquidCrystal.h>

LiquidCrystal lcd1(6,7,9,10,11,12);
LiquidCrystal lcd2(6,8,9,10,11,12);

void setup() {
  // put your setup code here, to run once:
lcd1.begin(20, 4);
lcd2.begin(20, 4);

 lcd1.print("Player 1");
 lcd2.print("Player 2");

}

void loop() {
  // put your main code here, to run repeatedly:
 lcd1.setCursor(0,1);
 lcd1.print(millis()/1000);
 delay(1000);
 lcd2.setCursor(0,1);
 lcd2.print(millis()/1000);
 delay(1000);
}

Tuesday, March 24, 2015

Phase 3 - Integrate the displays

Phase 3 has begun!



The displays arrived today.  First I soldered on the headers.  It has probably been 25 years since I did any precise soldering so it doesn't look like a professional job, but it works.  I tested each connection with my ohm meter to make sure I had a good contact and wasn't shorted to the next pin over.

Next I followed the tutorial from the Adafruit website to wire up the displays.  Then loaded the "Hello World" example.  I swapped the displays to make sure both were working correctly.  That was quicker than running another set of jumpers.

Next steps:
- update my clock sketch to send the time to the displays
- figure out how to do my custom characters for the large digits
- polish up the sketch and add delay, increment, and multiple periods
- create a setup routine so the time and other settings can be set with button presses

I'll post more updates as I make progress.

Tuesday, March 17, 2015

Displays have been ordered


Tonight I ordered two 4x20 LCD displays.



Also, here is a picture from the clock test.


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);
}

Tuesday, March 10, 2015

The Arduino has arrived



The Arduino experimenter's kit arrived today. 




I loaded the software without much trouble.  The only issue I had was the software recognized the Arduino was plugged into COM 3, but it was trying to write the program to COM 1.  This may have been due to having two instances of the software open.  After I closed one of them, it has worked ever since.

I built the first project from the booklet:  Making an LED blink.  I guess this is the "Hello World" program of the Arduino world.


So far this is going much more smoothly than I had hoped.   I will try to do a project each evening.  That should give me a good start at writing the chess clock program.


Monday, March 2, 2015

Building My Own Chess Clock


I now own 3 digital chess clocks:
  • DGT North American
  • DGT Easy Plus
  • Duel Timer
Each of them has drawbacks.  For instance, the DGT North American does not show the delay seconds counting down,  The Easy Plus cannot do more than one time period, and the Duel Timer only indicates whose turn it is to move on the display (no light or mechanical button).


So as an Engineer, I figure I can make something that can address all of these issues.  This is likely to become a massive project, so I will break it down into manageable chunks.


Phase 1 - Choose a Microcontroller

Based on what I have found on the interwebs, I am looking at the Arduine Uno R3.   Everything needed is onboard, just plug in and start programming.  Here are the specs:

MicrocontrollerATmega328
Operating Voltage5V
Input Voltage (recommended)7-12V
Input Voltage (limits)6-20V
Digital I/O Pins14 (of which 6 provide PWM output)
Analog Input Pins6
DC Current per I/O Pin40 mA
DC Current for 3.3V Pin50 mA
Flash Memory32 KB (ATmega328) of which 0.5 KB used by bootloader
SRAM2 KB (ATmega328)
EEPROM1 KB (ATmega328)
Clock Speed16 MHz
Length68.6 mm
Width53.4 mm
Weight25 g


Phase 2 - Learn to program the microcontroller

I can get the Arduino as with a starter kit that includes enough components and instructions for some first projects.  Plus there a lot of tutorials and videos on the web with instructions.  Failing that, I might even read some books.   It shouldn't take too long for me to be able to write the code for an elementary count down timer that switches to the other counter when a button is pressed.


Phase 3  -  Integrate the Displays

Right now I am looking at the HD4470 20x4 LCD display, one for each side.
The 8 custom characters would allow me to design a segmented display that would use 3 lines for the time H:MM:SS and the 4th line for information such as delay countdown (or increment), period, and move counter.  I mocked up something with only 5 custom characters that might look like this:



This display can be controlled with just 6 digital lines, one of which is the enable.  If I understand correctly, I could control 2 displays with just 7 lines, with a unique enable going to each display, and the rest of the data going to both.


Phase 4 -  Build the Case

For the first attempt, I will probably just use a clear plastic box, some large buttons and LEDs to indicate which player to move.  That would leave me 3 more digital pins to add Pause, and setting buttons.

The ultimate goal is to make a nice wooden body with mechanical buttons that click into place, just like my wife's nice Jerger analog clock.


Pressing the Start Button

Publishing my thoughts here forced me to spend some time thinking about what I would need and doing some research.  It also gives both my readers a chance to guide me back to the right path if I am starting out in the wrong direction.  So now is your chance; leave me some comments.

I'll publish some future posts with status reports and pictures as I make progress.