Introduction: Connect 4: Automized Board Game
For a year project for the "Universitée Libre de Bruxelles", it was asked us to electronize (to automate) a board game. The board game chosen was the popular game: "Connect 4". Instead of putting your coins in the desired column directly, you put them at the beginning of the game into a container. When the game starts, you choose the desired column in which you want to place a coin, by pressing a number on the keypad. That is the primary function of our prototype. We also put secondary functions that are discussed below, but you can also customize the robot with your ideas. The steps of this paper will be the following:
- Buying the electronic components
- Buying the material and construction of the mechanical components
- Design of the pieces
- Assembly
- Cable diagram
- How the computer code works
- Global discussion on the project
- Video demonstrations of the functioning prototype
- Possible improvements
Step 1: Buying the Electronic Components
This section contains all the electronic components we used and why we use them:
1. A solenoïd motor
The first thing our prototype needs to do is to grab a coin. For this purpose, we can use lots of motors, such as a DC motor, a stepper motor or a servo motor. The instructions that the motor needs to do are quite simple: grab the coin, drop the coin. The DC motor and the stepper motor can do lots of other things. These functions are superfluous. The servo motor plays the same rule as the solenoïd, except that the servo rotates and the solenoïd translates. The easiest motor to implement in the construction is the solenoïd due to the simple linear motion.
2. A stepper motor + his driver
The second thing our prototype needs to do is to move our gripper in a linear motion above the connect 4. For this purpose, we can use lots of motors, such as a DC motor, a stepper motor or a servo motor. The two last motors translate and rotate by small steps respectively. The DC motor turns at a certain given speed and does not know which distance it turned. The stepper motor is the perfect motor since it turns of a given angle. It needs to be controlled thanks to a driver. The only thing to do is to transform this rotation into a translation. For this, we use a timing belt system.
Another reason to use this type of linear motion is that this system is used for 3D printers.
3. Two contact sensors
We need one contact sensor to set up the gripper at one side of the prototype. After the initialization phase, the game can begin. Another contact sensor needs to be put on the other side of the prototype, for the gripper to know when it reached the other player's side. When it arrives on the other side, the gripper can grab the coin of the next player.
4. Keypad
Now that the prototype knows how to grab a coin, how to move it and what are the two limits of its motion, it needs to know where to release the coin. For this function, we just thought about a keypad with a minimum of 7 inputs. (the number of columns of the game is 7)
5. An Arduino UNO
To control all these signals, we decided to use an Arduino UNO, because it is very easy to learn how to use it and has enough pins for all the components we want to control.
6. Two LEDs
All the components above are needed for the good functioning of the game. Now you can customize the project. What we added are two LEDs of different colors, to know if the prototype is running, or if it is waiting for you to play.
7. Other components
We also used a resistance, a diode, a transistor. These components and their value can be found in step 5: the cable diagram.
Step 2: Buying the Material and Construction of the Mechanical Components
The things you need to buy to create this project are the following:
- 14 screws of length 16mm of diameter 2.5mm (In order to fix the gripper assembly)
- 4 screws of length 8mm and diameter 3mm (To fix the stepper motor)
- 10 screws of length 16mm and diameter 3mm (Body assembly)
- 10 screws of length 20mm and diameter 3mm (Body assembly)
- 5 screws of length of at least 50mm and diameter 6mm (To fix both bar supports)
Please note that you need the respective bolts for each screw.
- around a dozen small pointy screws (length of around 10mm)
- 2 metal bars of length 47cm and 8mm diameter
- 1 small metal rod of length of 2cm and 3mm diameter
- 2 linear ball bearings of length 24mm and an inner diameter of 8mm and an outer diameter of 15mm
- 1 roller bearing of inner diameter 3mm and an outer diameter of 10mm
- 1 Pulley (for the motor side) of diameter 5mm (given as an STL file in the next step)
- 1 Pulley (for the Block) of diameter 10 mm (also given as an STL file in the next step)
There are four big things to build. We will explain to you what we did: from the gripper to the body of the prototype.
1. The gripper
The function of the gripper is to grab the coins at the two extremities and release it when it arrives at the right position. Fundamentally, we need a controlled system that blocks the coin and releases it. For that, we use a solenoid (see Step 1), which is an electronic component, that has a linear translation motion when a voltage is applied to it. But to use the solenoid, we also need a particular structure that provides the support to the coin when the solenoid is on.
The gripper has the most complex structure because, in addition to the solenoid and the grasp function, the gripper needs to move linearly. This justifies the shape of the bottom part of the gripper. This is explained hereafter
The design was made on SolidWorks. Simple parts are cut in wood plates with a laser cutter. More complex parts are made in PET with the use of a 3D printer.
2. The linear motion
The linear motion of the gripper is the main function of the project after the gripper. It allows the gripper to move above the game. For that, we chose a timing belt system, with two metal bars that serve as guide rails for the gripper.
The two bars are parallel and fixed at the right height. The gripper can accept, in his structure, two linear ball bearings that allow the gripper to move with the least friction on the bars. With that, we have a linear displacement, but it is not controlled.
To control the displacement of the gripper, we use a stepper motor (see Step 1), placed at one extremity of the bars (in between both bars). On this stepper, we fixed a pulley with the right dimension; a similar system was made at the opposite side of the bars. The opposite pulley system consists of a block, in which we placed a thin bar. On this bar, we placed the second pulley, which can rotate freely.
The final step of the linear displacement of our gripper is the belt. We have to fix and tension the belt in order for the system to work correctly. For that, we use a simple fixation made of a small plate, that is screwed to the bottom part of the gripper. The belt is located between the bottom part of the gripper and the plate. Therefore, when we screw the plate on the bottom of the gripper, the belt is squeezed. In order to tension the belt, the block which has the second pulley is movable. Therefore, we position the belt correctly on both pulleys and fix the belt first. Then we push the block with the pulley in place, thus tensioning the belt, and finish by fixing the block.
Pieces manufactured with a 3D printer, here, are the fixation blocks for the bars. One of them has an extension in order to fix the stepper with four screws. And the other has space to place and fix the block for the pulley system.
3. The coin container (slides)
This part of the conception consists of a simple canal that guides the coins in the right position in order for the gripper to fulfill its function. We place the coins above the structure; they roll and follow the path until they are blocked and ready to be grabbed.
For this system, some pieces were created with a 3D printer too, because a laser cutter doesn't allow their manufacture (too complex since angles are cut in the thickness of the wood).
4. The body
It has a frame utility. At the top of the frame, is fixed the Arduino, the board with the electronic component and a battery. The frame accepts other systems and it is used to unite other components.
It is mainly made with wood planks using a laser cutter.
Step 3: Design of Pieces
In this section, the wooden parts are given as pictures with quotations and
the 3D parts are given in STL files (found at the end of this step). The wooden pieces are also provided in a DXF format (with their respective names). In the following listings, all wooden pieces are 3mm thick unless specified.
1. BODY (Pieces made of wood)
- Piece 0: 1st picture (6mm thickness)
- Piece 3: 2nd picture (6mm thickness)
- Piece 4: 3rd picture (6mm thickness)
- Piece 6: 4th picture
- Sidewall: 5th picture (6mm thickness)
- Bottom plate: 6th picture
- Top plate: 7th picture
- Mechanism support: 8th picture
2. BODY (Pieces 3D printed)
- Bar support (motor side): 1st file
- Bar support (pulley side): 2nd file
- Piece 1 (left & right): 3rd file
- Piece 2 (left & right): 4th file
- Piece 5: 5th file
3. Gripper (Parts made of wood)
- Front/Back wall: 9th picture
- Sidewall: 10th picture
- Inner wall: 11th picture
- Solenoid resting plate: 12th picture
4. Gripper (Parts 3D printed)
- Top part: 6th file
- Bottom of the gripper (where the linear ball bearings are placed): 7th file
Global representations of the gripper and the body are seen in pictures 13 to 19.
Attachments
- BlockPulley.STL
- Pulley(Block).STL
- Pulley(Motor).STL
- BarSupport_Pulley.STL
- BarSupport_Motor.STL
- Piece1(left).STL
- Piece1(right).STL
- Piece2(left).STL
- Piece2(right).STL
- Piece5.STL
- Gripper_Top.STL
- BottomGripper_Support.STL
- BottomPlate.DXF
- Gripper_Front-BackWall.DXF
- Gripper_InnerWall.DXF
- Gripper_SideWall.DXF
- Gripper_SolenoidSupport.DXF
- MechanismSupport.DXF
- Piece0.DXF
- Piece3.DXF
- Piece4.DXF
- Piece6.DXF
- SideWall.DXF
- TopPlate.DXF
- Squeeze_plate.DXF
Step 4: Assembly
The main assembly method consists of pieces interlocked and tightened, using a system made of screws and bolts. Basically, the pieces were designed in such a way that, there are holes with dimensions of the length of a screw and the diameter of a bolt. Moreover, holes of a dimension equal to the diameter of the screw were also designed. Due to this, it is possible to tighten and maintain in position different pieces. In some cases, pieces were screwed but without bolts.
The first part consists of assembling pieces of the body with the tightening method. The canal system for the coins is a part of the body, so it is also done with the same tightening method. At this point, the linear system can be made. The two bars are placed in blocks with holes at the right height. Be aware to place the gripper (see step 2) with its linear bearing on bars in the right direction, before clamping the bars with the two blocks. Once the gripper placed, the blocks are fixed with big screws and bolts, to safely maintain the position, and avoid displacement. The gripper is simply made, using the tightening method, and putting the solenoid (see Step 1) inside.
At this point, the stepper (see Step 1) can be fixed on the block with screws. On the other side, the pulley system (see Step 2) can be fixed to the block, with the same big screw used for the other block. Before fixing the pulley block, the belt must be stretched and attached to the gripper. The mechanical assembly is done, but the solenoid, the stepper motor, and the sensors must be connected to the Arduino, as explained in the next step.
Detailed assembly of the body :
First, we will assemble the coin container. Take the "Piece 0" and screw the following pieces to it: "Piece 2", "Piece 3" and "Piece 4". Pieces 3 and 4 need to be screwed with no bolts or fixed in the way that pleases you. (The positioning of these pieces are seen in the 3rd picture.)
Next, the container, assembled just before, needs to be inserted into "Piece 6". Before placing the two sidewalls on each side and fixing them using screws and bolts, put the "Mechanism support" piece in its designated place (as seen in the 4th picture).
The body is now completed. The next thing to do is to build the gripper. The assembly of the gripper is quite simple. Taking the solenoid resting plate, it is possible to place the back wall, the front wall, and the two side walls and attach them. The inner wall is placed inside the gripper, at the same time as the solenoid (put the back end of the solenoid inside the hole of the inner wall). Finally, the top part and the bottom support (made with a 3D printer), are placed.
The last thing to do is to implement the mechanism itself. Insert the two bars into the holes of the "Bar support (pulley)" piece. Next insert the two linear ball bearings in the holes of the "Bottom support" of the gripper. Then insert the bars into the gripper system (inside the linear ball bearings). Now clamp the other end of the bars with the "Bar support (motor)" piece. Now all that is left is to screw the motor on the "Bar support (motor)" and put the pulley on the stepper motor. You can fix the "Bar support (motor)" to the "Mechanism support" plate with the 2 big screws.
The final step is to put the timing belt. Take the "Block" piece and insert the thin bar with the roller bearing and the pulley fixed on it. Next put the timing belt around both pulleys with one part of the belt, that goes under the gripper and the other part, that is located between the "solenoid resting plate" and the "Bottom support". To fix the belt, screw the little plate between the "solenoid resting plate" and the "Bottom support" with the belt located underneath this plate, in order to squeeze the belt. Now you can move the "Block" in place inside the rectangular hole of the "Bar support (pulley)" and fix both, the "Block" and the "Bar support (pulley), to the "Mechanism support" plate (using 3 big screws).
To conclude this assembly, the roof of the body can now be placed and screwed using pointy screws into the sidewalls. Now you can pick up the robot and place it on the bottom plate, for more stability (try to make your bottom plate thick. The thicker it is, the more stable it will be, but not more than 1cm).
The full assembly of the prototype is now done. You can thus put your connect 4 games in place.
Attachments
Step 5: Cable Diagram
This is an overview of our cable diagram. We will decompose and explain each part in order to create the cable schematic.
- We can see that the two lines above on the protoboard are charged with a power supply of 0-14V. This supply is used to feed our 2 motors. Do not forget to put a common mass with the Arduino. In the diagram, this is done with the black wire on the right.
- The stepper motor is directly connected to the driver. There are 4 cables and they are coupled two by two. You have to put the coupled cable next to each other. That means in the pins 1.a 1.b and the two others in 2.a 2.b of the driver. Then a part of the driver is fed with the power supply and another part directly with the Arduino 0-5V. After this, you can put the Dir pin of the driver in the 4th digital pin of the Arduino and the Step pin to the 3rd digital pin of the Arduino. Don't forget to cable the pink wire on the photo.
- The solenoid motor works with one pin, located in the 2nd digital pin of the Arduino. The cable scheme needs a resistance of 1 kOhm, a diode 1N4001 and a transistor TIP 127. The latter will play the role of a simple electronic switch. Therefore a diode is essential to prevent an excessive voltage to occur and destroy our circuit. This is due to the fact that the solenoid has an inductive part and the voltage will be high when switch off the current (inductive law). Finally, the resistance prevents that too much current flow in the circuit.
- The LEDs are 5mm Led and, are connected to the Arduino with a resistance of 220 Ohm each. The LEDs have a direction that you can see with the length of the arm. The smallest arm is put to the mass. If you make a mistake, the LED will be destroyed.
- For the contact sensor, in order to not use two pins, we put them in parallel. Be aware that it is the "NO" (normally open) pin which is connected in the circuit and the "NC" (normally closed) pin which is not used. The "NC" pin is the default configuration of the contact sensor (the common is connected to this pin) and when pressing the button of the contact sensor, it is the "NO" pin that is connected to the common. Since we want the gripper to stop when pressing the button on the contact sensor, the "NO" pin will be connected to the common and give the information to the Arduino. You will see, in the next step, that we say to turn until you reach a contact sensor, one of the two. But in fact, it always reaches the sensor we want because the gripper goes already in the good direction. The value of the resistance is 10 kOhm
- The keypad we use is 4x4. It has in reality 8 pins that we have to connect. In fact, we only use 3x3 buttons. That's why we only use 6 wires to connect the keyboard (the last column and the last row of the keypad aren't used. There is no reason to wire them.). You have to pay attention to connect it in the good order into the Arduino.
Step 6: How the Computer Code Works
<pre><br> <p>#include Keypad.h<br>#include AccelStepper.h</p><p>//Arduino Pins attribuation const int GreenledPin = 13; const int YellowledPin = 12; const byte numRows = 3; const byte numCols = 3; const int stepPin = 3; const int dirPin = 4; const int solenoidPin = 2; const int buttonsPin = 11;</p><p>int compteur_piece = 0; //Serve to know the direction of the stepper motor int sens = 1; //Serve to know the direction of the stepper motor</p><p>//Computations of stepper motor angle const float R_poulie = 0.572; const float espace_colonne = 3.46; const float espace_cote = 5; const float angle_1colonne = (180*espace_colonne)/(PI*R_poulie); const float angle_cote = (180*espace_cote)/(PI*R_poulie); const float angle_total = 6*angle_1colonne + 2*angle_cote; const float deplacement_total = 200*(angle_total/360);</p><p>int buttonsState = 0; //Initialization of the contact sensors</p><p>//Keypad Pins char keys[numRows][numCols]= { {'1', '2', '3'},{'4', '5', '6'}, {'7', '8', '9'}}; byte rowPins[numRows] = {10,9,8}; //Rows 0 to 2 byte colPins[numCols]= {7,6,5}; //Columns 0 to 2</p><p>//Initialization of an instance of the Keypad class Keypad myKeypad= Keypad(makeKeymap(keys), rowPins, colPins, numRows, numCols);</p><p>//Library to control the stepper motor AccelStepper stepper = AccelStepper(1, stepPin, dirPin);</p><p>//Setup of the software void setup() { pinMode(stepPin,OUTPUT); //Setup of the stepper motor stepPin pinMode(dirPin,OUTPUT); //Setup of the stepper motor dirPin digitalWrite(dirPin,LOW); //Enables the motor to move in a particular direction pinMode(GreenledPin, OUTPUT); //Setup of the GreenledPin pinMode(YellowledPin, OUTPUT); //Setup of the YellowledPin pinMode(solenoidPin, OUTPUT); //Setup of the solenoidPin stepper.setMaxSpeed(1000); //Setup of the stepper motor maximum speed }</p><p>//If key is pressed, this key is stored in 'keypressed' variable //If key is not equal to 'NO_KEY', then this key is printed out //If key is 8, the gripper go on one side to initialize the game //If key is 9, the gripper go on the other to initialize the game //If key is between 1 and 7, the gripper go to desired column (1 corresponds to the first column, 2 to the second, ...)</p><p>void loop() { char keypressed = myKeypad.getKey(); int keypressed_int; float deplacement; digitalWrite(GreenledPin, HIGH); if (keypressed != NO_KEY){ digitalWrite(GreenledPin, LOW); digitalWrite(YellowledPin, HIGH); delay(1000); if (keypressed == '1'){ keypressed_int = 1; } if (keypressed == '2'){ keypressed_int = 2; } if (keypressed == '3'){ keypressed_int = 3; } if (keypressed == '4'){ keypressed_int = 4; } if (keypressed == '5'){ keypressed_int = 5; } if (keypressed == '6'){ keypressed_int = 6; } if (keypressed == '7'){ keypressed_int = 7; } if (keypressed == '8'){ keypressed_int = 8; buttonsState = digitalRead(buttonsPin); while (digitalRead(buttonsPin) == 0){ //Gripper continues to move until one of the 2 contact sensors is pushed stepper.setSpeed(400); stepper.runSpeed(); } compteur_piece = 0; stepper.setCurrentPosition(0); digitalWrite(YellowledPin, LOW); } if (keypressed == '9'){ keypressed_int = 9; buttonsState = digitalRead(buttonsPin); while (buttonsState == 0){ stepper.setSpeed(-400); stepper.runSpeed(); buttonsState = digitalRead(buttonsPin); } compteur_piece = 1; stepper.setCurrentPosition(0); digitalWrite(YellowledPin, LOW); } if (keypressed_int <= 7){ if (compteur_piece % 2 == 0){ sens = -1; } else { sens = 1; } digitalWrite(solenoidPin, HIGH); //Gripper takes the coin deplacement = 200*(keypressed_int-1)*angle_1colonne/360+200*angle_cote/360; delay(1000); //Gripper starts to move while (abs(stepper.currentPosition()) < deplacement){ stepper.setSpeed(400*sens); stepper.runSpeed(); } delay(1000); //Release the coin digitalWrite(solenoidPin, LOW); delay(1000); buttonsState = 0; //Reset the gripper position while (digitalRead(buttonsPin) == 0){ stepper.setSpeed(400*sens); stepper.runSpeed(); } </p><p> //Change the player compteur_piece ++; digitalWrite(YellowledPin, LOW); stepper.setCurrentPosition(0); } } }</p>
Step 7: Global Discussion:
During this project several problems where encountered and the solutions found are detailed hereafter:
First, the coin blocker was too small. Therefore when several coins were added in the coin tank, the coin that the gripper is supposed to take overpassed the coin blocker. To resolve this, we simply found the best dimensions for this blocker by trial and error (we found that a height of 17mm was enough).
A second problem appeared since initially we had just one contact sensor. Consequently, we knew precisely the position of the gripper only at the beginning, and its following real positions were deduced from the software. Therefore, when the stepper motor missed a step for an unknown reason, the real position of the gripper is not strictly identical to its calculated one with the software. For one movement of the gripper, it was not a problem but when the game advanced, the error was accumulating, and the movement of the gripper was therefore not the expected one. In order to remedy this problem, we simply decided to add a second contact sensor on the other side, to initialize de position of the gripper, at each of its movement sequences. Due to this change, the roof of the gripper needed to be changed to take into account this second sensor.
There was also a third problem, the pulley block, that was 3D-printed, was of a poor density, and therefore, didn't withstand the moment due to the tension of the timing belt. So we reprinted this piece with a density of 80% and that solved the problem.
Overall, this project was a success and we wish that whoever tries to make this project succeeds as we did. The most complicated part of this project is to make sure that the linear motion isn't subject to many friction forces. Therefore one should try to minimize the friction as much as possible, in order for the prototype to be very precise, and drop the coin in the correct desired column.
Step 8: Photo and Videos of the Operation of the Prototype
Here above, you can find a photo of the whole system, and several videos including a time-lapse connect 4 game and the operation of our prototype more closely.
The first video shows a time-lapse of a whole Connect 4 game.
The second video shows the functioning of the solenoid. The motor grabs the coin and releases it when arriving in the right position.
The third one shows a backside view of the gripper. As said previously, the gripper grabs and release the coin, and then goes to the other side until reaching the contact sensor.
The fourth and fifth videos show both of them different views of the functioning of the pulley on the stepper motor side.
The last video shows the frontside view of the gripper.
Step 9: Possible Improvement
In this section, we will write about what we could improve in our current design. We also propose what could be done in the future.
1. Improvement in our current prototype
- A first improvement could be to find a better system to tension the belt. For now, it takes a little bit of time to tend it (and relies on force, but is sufficient since the tension of the belt isn't that much.).
- A second improvement could be to solder every electronic component on a Shield that can come above the Arduino UNO.
2. Future improvements
- A first improvement could be to implement different game modes. Now the code is programmed for 2 players and no AI. An idea to play alone is to implement an Artificial Intelligence. Another idea could be that the gripper chooses randomly who plays at every turn. This means, every time a coin is released, the Arduino will choose randomly where to go. So a player could play two or three times in a row (but of course, it can't be 4 times in a row because that would be an insta-win. Also, 3 times in a row should be rare. Therefore we would weight the probability of playing several times in a row, putting more weight on one and two, than on three.)
- A second improvement could be to implement a third motor to restart the game. It could be done by a solenoïd. It would slide the coin holder, located at the bottom of the grid, when the game is finished, to release the pieces and then close it to restart another game.
- A third improvement could be to not move the gripper when a column is already full. So, if a player mistakenly selected a full column, the game would not react.