Hardware components | ||||||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
Software apps and online services | ||||||
![]() |
| |||||
Hand tools and fabrication machines | ||||||
![]() |
|
To enjoy the fun of playing table tennis on a small desk with friends in a few minutes of free time, I build this project. In this project, the process of swinging the racket to serve the ball is instead by pressing the serve buttons, thus it only needs a small desk to play table tennis.
Arduino IDE
HARDWARE:Arduino Nano: To choose one button from two serve buttons to serve first.
To decide which user scores in each round.
To accumulate the scores of two users separately.
To compare the total scores of two users and decide the final winner.
LCD screen: The users could see who serves the ball first from the screen.
To display the scores of two users separately.
The users could see who serves the ball first from the screen.
To display the winner.
Buttons: By pressing a button to simulate a swing of a racket.
WORKING PROCESS:- The red button and the blue button work as serve buttons and the green buttons are ready-to-serve buttons.
- The green buttons are ready-to-serve buttons.
- The black button is the reset button, users could press the black button to clear their scores.
- To start the game, two users should press the two ready-to-serve buttons (green button) at the same time, then the system would randomly choses one button from two serve buttons to serve first.
- Let's assume the system chooses the red button to serve first, when the user of the red button press the red button, the RGB strip would glow red. And when the rear light of the RGB strip comes on, the front light would automatically goes out.
- If the user of the blue button serve earlier than the user of the red button, the LED light would not lit up. At this situation the user of the red button would earn the score automatically, and this round is over, the system would automatically pick up a button to serve first again.
- And in this round( red button serve first ) the user of the blue button would only earn the score if the user of the blue button press the blue button to serve at the same time as the middle light of the RGB strip lit up. Neither the early tee shot nor the late tee shot will score.
- And if one user scores 11 points of this game, the user would win and the RGB strip would display the color of the user's serve button.
- Connect the left part green button(ready-to-serve button) to Arduino D2.
- Connect the blue button(left serve button) to Arduino D3.
- Connect the black button(reset button) to Arduino D4.
- Connect the red button(right serve button) to Arduino D7.
- Connect the right green button(right ready-to-serve button) to Arduino D12.
- Connects the RGB strip Arduino D9.(you can find the schematic from my attachment)
- Download Arduino IDE from Software | Arduino.
- Download the program for the project from my attachment.
- Import the program for the project to Arduino IDE via selecting File/Open.
- Select Board and Port on Arduino IDE.
- Download ZIP libraries from https://github.com/olikraus/U8g2_Arduino and https://github.com/adafruit/Adafruit_NeoPixel/find/master .
- Add ZIP libraries to Arduino IDE via collecting Sketch/Include Library/Add.ZIP Library.
Compile and upload.
/*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************BY HUIQIAO****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
#include <Arduino.h> // Calling program
#include <U8g2lib.h> // Calling ICD screen library progrm
#include <Wire.h> // Calling I2C libray program
#include <Adafruit_NeoPixel.h> // Calling RGB libry program
#include <avr/power.h> // Calling RGB library program
#define NumPixels 11 // Define 11 LEDs
#define winScore 11 // Define user should score 11 points to win
#define leftReadyPin 2 // Left readytoserve button connects to ArduinoD2
#define leftServePin 3 // Lefr serve button connects to ArduinoD3
#define buttonZeroPin 4 // reset button connects to ArduinoD4
#define rightServePin 7 // Right serve button connects to ArduinoD7
#define rightReadyPin 12 // Right readytoserve button connects to ArduinoD12
#define ws2812Pin 9 // RGB strip connects to ArduinoD9
Adafruit_NeoPixel pixels(NumPixels, ws2812Pin, NEO_GRB + NEO_KHZ800);
U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE);
int leftScore = 0; // Left scores
int rightScore = 0; // Right scores
int i = 0; // LEDs count of RGB strip from left part
int j = 10; // LEDs count of RGB strip from right part
int randomNumber; // To choose who serves first randomly
int Step_state = 0x00; // To show which stage of the game
int colorNumber = 0; // color variable
long blinkTime1 = 0; // Blink time variable
long blinkTime2 = 0;
long blinkTime3 = 0;
long Period1 = 500; // Gap time before each blink
long Period2 = 1000; // Speed of LEDs of RGB strip
bool endingState = false;
struct Button {
int lastButtonState = HIGH; // Innitialise
boolean flag = false; // True-false status
// Define long()
long lastDebounceTime = 0; // Record debounce variable
long debounceDelay = 50; // Debounce time variable is 50ms
};
Button button[5]; // set up 3 new buttons
void setup() {
Serial.begin(9600); // Rate
pinMode(leftReadyPin, INPUT_PULLUP); // Set up lbutton 1 uses pullup to input
pinMode(leftServePin, INPUT_PULLUP); // Set up Lbutton 2 uses......
pinMode(buttonZeroPin, INPUT_PULLUP); // Set up Lbutton 3 uses......
pinMode(rightServePin, INPUT_PULLUP); // Set up Rbutton 1 uses......
pinMode(rightReadyPin, INPUT_PULLUP); // Set up Rbutton 2 uses......
pixels.begin();
pixels.clear();
pixels.show();
u8g2.begin();
}
void loop() {
switch (Step_state) {
case 0x00: { // Statge is 0
buttonFlag(); // Reset button function
chooseServe(); // Choose serve function
} break;
case 0x01: { // Stage 1
buttonFlag(); // Reset button function
waitingReady(); // Wait for ready to serve button
} break;
case 0x02: { // Stage 2
buttonFlag(); // Reset button function
Screen(); // Screen function
if (endingState == true) { // If one user winns
Step_state = 0x04;
endingState = false;
} else {
Step_state = 0x03;
}
} break;
case 0x03: { // Stage 3
buttonFlag(); // Reset button clear function
score(); // Score function
} break;
case 0x04: { // Stage 4
winBlink(); // Blink RGB strip when one suer wins
buttonFlag(); // Reset button to clear
} break;
default: break;
}
}
void chooseServe() {
randomNumber = random(0, 100);
for (int m = 0; m < NumPixels; m ++) { // RGB strip glow off
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
u8g2.setFont(u8g2_font_9x15_mf);
u8g2.firstPage();
do {
if (randomNumber % 2 == 0) { // Make sure LCD scree display first
Serial.println("");
u8g2.drawStr(20, 40, "leftServe!");
}
else if (randomNumber % 2 == 1) { // Make sure LCD scree display first
Serial.println("");
u8g2.drawStr(10, 40, "rightServe!");
}
} while ( u8g2.nextPage() );
Serial.print(button[0].flag);
Serial.print(",");
Serial.println(button[4].flag);
Serial.println("aaa");
Step_state = 0x01;
}
void waitingReady() {
Serial.print(button[0].flag);
Serial.print(",");
Serial.println(button[4].flag);
if (button[0].flag != true) { // if button1 doesnot down
Button(leftReadyPin, 0); // condition of button 1
}
else {
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
pixels.show();
}
if (button[4].flag != true) {
Button(rightReadyPin, 4);
}
else {
pixels.setPixelColor(10, pixels.Color(255, 0, 0));
pixels.show();
}
if ((button[0].flag == true) && (button[4].flag == true)) {
pixels.setPixelColor(10, pixels.Color(255, 0, 0));
pixels.setPixelColor(0, pixels.Color(0, 0, 255));
pixels.show();
Serial.println("ready");
Step_state = 0x02;
}
}
void Screen() {
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_9x15_mf); // scores
u8g2.drawStr(0, 10, "Left");
u8g2.drawStr(80, 10, "Right");
u8g2.setFont(u8g2_font_calibration_gothic_nbp_tr);
u8g2.setCursor(10, 40);
u8g2.print(leftScore);
u8g2.setCursor(98, 40);
u8g2.print(rightScore);
if (leftScore == winScore) { // when left wins
u8g2.setCursor(10, 40);
u8g2.print(leftScore);
u8g2.drawStr(0, 60, "Win !"); // screen displays
endingState = true;
}
if (rightScore == winScore) { // Right wins
u8g2.setCursor(98, 40);
u8g2.print(rightScore);
u8g2.drawStr(100, 60, "Win !"); // screen displays
endingState = true;
}
} while ( u8g2.nextPage() );
}
void score() {
Button(leftServePin, 1);
Button(rightServePin, 3);
if (randomNumber % 2 == 0) {
if ((button[1].flag != true) && (button[3].flag == true)) {
leftScore ++;
for (int m = 0; m < 11; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
u8g2.firstPage();
do {
u8g2.drawStr(20, 40, "left+1!");
} while ( u8g2.nextPage() );
delay(3000);
i = 0;
j = 10;
for (int m = 0; m < 5; m ++) {
button[m].flag = false;
}
randomNumber = random(0, 100);
if (leftScore != winScore) {
Step_state = 0x00;
} else {
Step_state = 0x02;
}
}
else {
if (button[1].flag == true) {
leftBlink();
}
if (button[3].flag == true) {
rightBlink();
}
if ((button[1].flag == true) && (button[3].flag != true) && (i >= 6)) {
leftScore ++;
for (int m = 0; m < i; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
u8g2.firstPage();
do {
u8g2.drawStr(20, 40, "left+1!");
}
while ( u8g2.nextPage() );
delay(3000);
i = 0;
j = 10;
for (int m = 0; m < 5; m ++) {
button[m].flag = false;
}
randomNumber = random(0, 100);
if (leftScore != winScore) {
Step_state = 0x00;
}
else {
Step_state = 0x02;
}
}
else if ((button[1].flag == true) && (button[3].flag == true)) {
if ((i == 5) && (j == 9)) {
rightScore ++;
for (int m = 0; m < i; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
for (int m = 10; m > j; m --) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
u8g2.firstPage();
do {
u8g2.drawStr(20, 40, "right+1!");
}
while ( u8g2.nextPage() );
delay(3000);
i = 0;
j = 10;
for (int m = 0; m < 5; m ++) {
button[m].flag = false;
}
randomNumber = random(0, 100);
if (rightScore != winScore) {
Step_state = 0x00;
}
else {
Step_state = 0x02;
}
}
else {
leftScore ++;
for (int m = 0; m < i; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
for (int m = 10; m > j; m --) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
u8g2.firstPage();
do {
u8g2.drawStr(20, 40, "left+1!");
}
while ( u8g2.nextPage() );
delay(3000);
i = 0;
j = 10;
for (int m = 0; m < 5; m ++) {
button[m].flag = false;
}
randomNumber = random(0, 100);
if (leftScore != winScore) {
Step_state = 0x00;
} else {
Step_state = 0x02;
}
}
}
}
}
else if (randomNumber % 2 == 1) {
if ((button[1].flag == true) && (button[3].flag != true)) {
rightScore ++;
for (int m = 0; m < NumPixels; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
u8g2.firstPage();
do {
u8g2.drawStr(20, 40, "right+1!");
} while ( u8g2.nextPage() );
delay(3000);
i = 0;
j = 10;
for (int m = 0; m < 5; m ++) {
button[m].flag = false;
}
randomNumber = random(0, 100);
if (rightScore != winScore) {
Step_state = 0x00;
} else {
Step_state = 0x02;
}
}
else {
if (button[1].flag == true) {
leftBlink();
}
if (button[3].flag == true) {
rightBlink();
}
if ((button[1].flag != true) && (button[3].flag == true) && (j <= 4)) {
rightScore ++;
for (int m = 10; m > j; m --) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
u8g2.firstPage();
do {
u8g2.drawStr(20, 40, "right+1!");
}
while ( u8g2.nextPage() );
delay(3000);
i = 0;
j = 10;
for (int m = 0; m < 5; m ++) {
button[m].flag = false;
}
randomNumber = random(0, 100);
if (rightScore != winScore) {
Step_state = 0x00;
}
else {
Step_state = 0x02;
}
}
if ((button[1].flag == true) && (button[3].flag == true)) {
if ((i == 1) && (j == 5)) {
leftScore ++;
for (int m = 0; m < i; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
for (int m = 10; m > j; m --) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
u8g2.firstPage();
do {
u8g2.drawStr(20, 40, "left+1!");
}
while ( u8g2.nextPage() );
delay(3000);
i = 0;
j = 10;
for (int m = 0; m < 5; m ++) {
button[m].flag = false;
}
randomNumber = random(0, 100);
if (leftScore != winScore) {
Step_state = 0x00;
}
else {
Step_state = 0x02;
}
} else {
rightScore ++;
for (int m = 0; m < i; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
for (int m = 10; m > j; m --) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
u8g2.firstPage();
do {
u8g2.drawStr(20, 40, "right+1!");
}
while ( u8g2.nextPage() );
delay(3000);
i = 0;
j = 10;
for (int m = 0; m < 5; m ++) {
button[m].flag = false;
}
randomNumber = random(0, 100);
if (rightScore != winScore) {
Step_state = 0x00;
} else {
Step_state = 0x02;
}
}
}
}
}
}
void buttonFlag() {
Button(buttonZeroPin, 2);
if (button[2].flag == true) {
for (int m = 0; m < NumPixels; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
leftScore = 0;
rightScore = 0;
button[0].flag = false;
button[1].flag = false;
button[2].flag = false;
button[3].flag = false;
button[4].flag = false;
i = 0;
j = 10;
u8g2.firstPage();
do {
u8g2.drawStr(0, 40, "gameRestart!");
} while ( u8g2.nextPage() );
delay(3000);
Step_state = 0x00;
}
}
void leftBlink() {
unsigned long currentMillis = millis();
if (i < NumPixels) {
if (currentMillis - blinkTime1 >= Period1) { //period1ms
for (int m = 0; m < i; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
}
if (currentMillis - blinkTime1 >= Period2) { //period2ms
blinkTime1 = currentMillis;
i++;
pixels.setPixelColor(i, pixels.Color(0, 0, 255));
pixels.show();
}
}
if (i == NumPixels) {
for (int m = 0; m < NumPixels; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
}
}
void rightBlink() {
unsigned long currentMillis = millis();
if (j > 0) {
if (currentMillis - blinkTime2 >= Period1) { //periodms
for (int m = 10; m > j; m --) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
}
if (currentMillis - blinkTime2 >= Period2) { //periodms
blinkTime2 = currentMillis;
j--;
pixels.setPixelColor(j, pixels.Color(255, 0, 0));
pixels.show();
}
}
if (j == 0) {
for (int m = 0; m < NumPixels; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
}
}
void Button(int button_Pin, int button_num) {
int reading = digitalRead(button_Pin);
if (reading != button[button_num].lastButtonState) {
if (reading == LOW) { //LOW
button[button_num].flag = true;
}
}
button[button_num].lastButtonState = reading;
}
void winBlink() {
unsigned long currentMillis = millis(); // record and store time
if (leftScore == winScore) {
if (currentMillis - blinkTime3 >= Period1) { // check periodms
for (int m = 0; m < NumPixels; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
}
if (currentMillis - blinkTime3 >= Period2) { // check periodms
blinkTime3 = currentMillis;
for (int m = 0; m < NumPixels; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 255));
pixels.show();
}
}
}
else if (rightScore == winScore) {
if (currentMillis - blinkTime3 >= Period1) { // check periodms
for (int m = 0; m < NumPixels; m ++) {
pixels.setPixelColor(m, pixels.Color(0, 0, 0));
pixels.show();
}
}
if (currentMillis - blinkTime3 >= Period2) { // check periodms
blinkTime3 = currentMillis;
for (int m = 0; m < NumPixels; m ++) {
pixels.setPixelColor(m, pixels.Color(255, 0, 0
pixels.show();
}
}
}
}
U8g2_Arduino-master
C/C++https://github.com/olikraus/U8g2_Arduino
No preview (download only).
Adafruit_NeoPixel-master
C/C++https://github.com/adafruit/Adafruit_NeoPixel/find/master
No preview (download only).
Comments