Michael Guerero
Published © GPL3+

Automated Chess Board

Moves chess pieces around the board invisibly and seemingly magically.

IntermediateShowcase (no instructions)53,448
Automated Chess Board

Things used in this project

Story

Read more

Schematics

Automated_chessboard_Layout

Board powered from USB cable for all logic devices. Steppers and electromagnet (Solenoid) are powered from external power brick that is 9 volts and max 5 amps.

Code

Automated_chessboard

Arduino
Code will:
*Home magnet with end stops at position A1.
*Receive square address (Letter, Number) from Serial Monitor for piece to be moved.
*Translate input into number of steps to be completed by stepper motors.
*Receive square address (Letter, Number) from Serial Monitor for new piece location.
*Turn on electromagnet.
*Translate input into number of steps to be completed by stepper motors.
*Turn off electromagnet.

Notes:
*Stepper motors will run simultaneously (during zeroing and moving with the magnet off ) until one reaches its max steps and then the other will continue until it reaches the specified square.

*When the magnet is on and moving a piece the steppers initially offset to the corner and moves along the line between squares to prevent pieces interfering with each other. For example, this allows someone to move their knight before moving the pawns in front of it.
const int stepsBetweenSquares = 318;
const int stepPinX = 3; 
const int dirPinX = 4; 
const int stepPinY = 5;
const int dirPinY = 6;
const int limitSwitchX = 8;
const int limitSwitchY = 9;
const int magnetPinPos = 10;
const int magnetPinNeg = 11;
int x1 = 0; int x2 = 1;
int y1 = 0; int y2 = 1;
int xsteps;
int ysteps;
int x = 0;
int y = 0;

void setup() {
  Serial.begin(9600);
  pinMode(stepPinX,OUTPUT); 
  pinMode(dirPinX,OUTPUT);
  pinMode(stepPinY,OUTPUT); 
  pinMode(dirPinY,OUTPUT);
  pinMode(limitSwitchX, INPUT);
  pinMode(limitSwitchY, INPUT);
  pinMode(magnetPinPos, OUTPUT);
  pinMode(magnetPinNeg, OUTPUT);
  

//_________________________________________________________________________________________________
// Zero position to square A1
//--------------------------------------------------------------------------------------------------
  zeroDiagonal();
}


void loop() {
//___________________________________________________________________________________________________
// Recieve position adress of piece to be moved from Serial monitor (Letter, Number)
//---------------------------------------------------------------------------------------------------
  Serial.print("Piece to be moved letter adress:  ");
  while (!Serial.available());
    x1 = readSerialLetter();
      
  Serial.print("Piece to be moved number adress:  ");
  while (!Serial.available());
    y1 = readSerialNumber();      


//______________________________________________________________________________________________
// Move to Position of piece to be moved
//-----------------------------------------------------------------------------------------------
  xsteps = stepsBetweenSquares*(x1-x2);
  ysteps = stepsBetweenSquares*(y1-y2);
  
  movePieceDiagonal(xsteps, ysteps);
 

//_______________________________________________________________________________________________
// Recieve position adress of piece new location from Serial Monitor (Letter, Number)
//-----------------------------------------------------------------------------------------------
  Serial.print("New location letter adress:  ");
  while (!Serial.available());
    x2 = readSerialLetter();

  Serial.print("New location number adress:  ");
  while (!Serial.available());
    y2 = readSerialNumber();
  Serial.println();

  
//________________________________________________________________________________________________
// Turn on magnet
//------------------------------------------------------------------------------------------------
  digitalWrite(magnetPinPos, HIGH);
  digitalWrite(magnetPinNeg, LOW);

  
//________________________________________________________________________________________________
// Move piece to new location
//-------------------------------------------------------------------------------------------------
  xsteps = stepsBetweenSquares*(x2-x1);
  ysteps = stepsBetweenSquares*(y2-y1);
  
  digitalWrite(dirPinX, HIGH); digitalWrite(dirPinY, LOW);
  offsetPiece();
  delay(50);
  movePiece(xsteps, dirPinX, stepPinX);
  movePiece(-ysteps, dirPinY, stepPinY);
  delay(50);
  digitalWrite(dirPinX, LOW); digitalWrite(dirPinY, HIGH);
  offsetPiece();

//__________________________________________________________________________________________________
// Turn off magnet
//----------------------------------------------------------------------------------------------------
  digitalWrite(magnetPinPos, LOW);
  digitalWrite(magnetPinNeg, LOW);
}


/////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS ////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////

int readSerialLetter(){
  int i;
  while(i < 1 || i > 8){
    i = Serial.read(); 
    i = i - 64;
    }
  Serial.println(i);
  Serial.parseInt();
  return i;
  }

//////////////////////////////////////////////////////////////////////////////////////////////////////

int readSerialNumber(){
  int i;
  while (i < 1 || i > 8){
    i = Serial.parseInt();
    }
  Serial.println(i);
  Serial.parseInt();
  return i;
  }

////////////////////////////////////////////////////////////////////////////////////////////////////////

void zeroDiagonal(){
  digitalWrite(dirPinX, LOW);
  digitalWrite(dirPinY, HIGH);
  while (digitalRead(limitSwitchX) == HIGH && digitalRead(limitSwitchY) == HIGH){
    moveDiagonal(1.5);
  }
  while (digitalRead(limitSwitchX) == HIGH){
    moveLinear(stepPinX, 1.5);
  }
  while (digitalRead(limitSwitchY) == HIGH){
    moveLinear(stepPinY, 1.5);
  }
  while (digitalRead(limitSwitchX) == LOW){         //Backoff switch
    digitalWrite(dirPinX, HIGH);
    moveLinear(stepPinX, 1);
  }
  while (digitalRead(limitSwitchY) == LOW){         //Backoff switch
    digitalWrite(dirPinY, LOW);
    moveLinear(stepPinY, 1);
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////

void movePiece(int steps, int dirPin, int stepPin){
  if (steps > 0){
    digitalWrite(dirPin,HIGH);
  }
  else{
    steps = abs(steps);
    digitalWrite(dirPin, LOW);
  }
  for(int i = 0; i < steps; i++) {
    moveLinear(stepPin, 2.5);
  }
  }

////////////////////////////////////////////////////////////////////////////////////////////////////////

void movePieceDiagonal(int xsteps, int ysteps){
  if (ysteps > 0){
    digitalWrite(dirPinY, LOW);
  }
  else{
    ysteps = abs(ysteps);
    digitalWrite(dirPinY, HIGH);
  }
  if (xsteps > 0){
    digitalWrite(dirPinX, HIGH);
  } 
  else{
    xsteps = abs(xsteps);
    digitalWrite(dirPinX, LOW);
  }
  x = 0; y = 0; 
  while (x < xsteps && y < ysteps){
    moveDiagonal(1.5);
    x++; y++;
  }
  for(x; x < xsteps; x++){
    moveLinear(stepPinX, 1.5);
  }
  for(y; y < ysteps; y++){
    moveLinear(stepPinY, 1.5);
  }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

void offsetPiece(){
  for (int i=0; i < stepsBetweenSquares/2; i++){
    moveDiagonal(2.5);
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void moveDiagonal(int delayTime){
    digitalWrite(stepPinX, HIGH);
    digitalWrite(stepPinY, HIGH);
    delay(delayTime);
    digitalWrite(stepPinX, LOW);
    digitalWrite(stepPinY, LOW);
    delay(delayTime);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void moveLinear(int stepPin, int delayTime){
  digitalWrite(stepPin, HIGH);
  delay(delayTime);
  digitalWrite(stepPin, LOW);
  delay(delayTime);
}

Credits

Michael Guerero

Michael Guerero

3 projects • 43 followers
Earned my BS in Mechanical Engineering from Cal Poly Pomona in 2018. Currently working for the California Air Resources Board.

Comments