To enjoy the fun of playing table tennis on a a small table with friends in a few minutes of free time, I build Mini Table Tennis.
In this project, the process of swinging the racket to serve the ball is replaced by pressing the serve buttons.
Demo of this Mini Table Tennis.
1 / 5 • Game start!
SOFTWARE:
Arduino IDE
HARDWARE:
Arduino Nano:
To randomlychoose one button from two serve buttons to serve first.
To judge which user scores in each round.
To accumulate the scores of two users respectively.
To compare the total scores of two users and judgethe final winner.
LCD screen:
The users can see who serves the ball first from the screen.
To display the scores of two users respectively.
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.
Two serve buttons.
The green buttons are ready-to-serve buttons.
Two ready-to-serve buttons.
The black button is the reset button, users can press the black button to clear their scores.
The reset button.
To start the game, two users should press the two ready-to-serve buttons (green button) at the same time, then the system will randomly chose one button from two serve buttons to serve first.
If we assume the system chooses the red button to serve first, when the user of the red button press the red button, the RGB strip will glow red immediately. And when the rear light of the RGB strip comes on, the front light would automatically goes out.
When the system chooses the red button as the first-serve button, If the user of the blue button serve earlier than the user of the red button, the LED light will not lit up. At this situation the user of the red button will earn 1 score automatically, and this round is over, then the system will automatically choose a button to serve first again.
When the system chooses the red button as the first-serve button, the user of the blue button will earn 1 score if the user of the blue button can press the blue button to serve at the same time as the middle light of the RGB strip glow red. Neither the early tee shot nor the late tee shot will score.
When one user scores 11 points, the user wins the game and the RGB strip will display the colour of the winner's serve button.
HOW TO BUILD THIS THING?
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.
Code to control the speed of the game on the Line 43.
/*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************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_NeoPixelpixels(NumPixels,ws2812Pin,NEO_GRB+NEO_KHZ800);U8G2_SSD1306_128X64_NONAME_1_SW_I2Cu8g2(U8G2_R0,/* clock=*/SCL,/* data=*/SDA,/* reset=*/U8X8_PIN_NONE);intleftScore=0;// Left scores intrightScore=0;// Right scores inti=0;// LEDs count of RGB strip from left part intj=10;// LEDs count of RGB strip from right part intrandomNumber;// To choose who serves first randomlyintStep_state=0x00;// To show which stage of the game intcolorNumber=0;// color variablelongblinkTime1=0;// Blink time variable longblinkTime2=0;longblinkTime3=0;longPeriod1=500;// Gap time before each blink longPeriod2=1000;// Speed of LEDs of RGB strip boolendingState=false;structButton{intlastButtonState=HIGH;// Innitialise booleanflag=false;// True-false status// Define long() longlastDebounceTime=0;// Record debounce variablelongdebounceDelay=50;// Debounce time variable is 50ms};Buttonbutton[5];// set up 3 new buttonsvoidsetup(){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();}voidloop(){switch(Step_state){case0x00:{// Statge is 0buttonFlag();// Reset button functionchooseServe();// Choose serve function}break;case0x01:{// Stage 1buttonFlag();// Reset button functionwaitingReady();// Wait for ready to serve button}break;case0x02:{// Stage 2buttonFlag();// Reset button function Screen();// Screen functionif(endingState==true){// If one user winnsStep_state=0x04;endingState=false;}else{Step_state=0x03;}}break;case0x03:{// Stage 3buttonFlag();// Reset button clear function score();// Score function }break;case0x04:{// Stage 4winBlink();// Blink RGB strip when one suer winsbuttonFlag();// Reset button to clear }break;default:break;}}voidchooseServe(){randomNumber=random(0,100);for(intm=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!");}elseif(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;}voidwaitingReady(){Serial.print(button[0].flag);Serial.print(",");Serial.println(button[4].flag);if(button[0].flag!=true){// if button1 doesnot downButton(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;}}voidScreen(){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 winsu8g2.setCursor(10,40);u8g2.print(leftScore);u8g2.drawStr(0,60,"Win !");// screen displaysendingState=true;}if(rightScore==winScore){// Right winsu8g2.setCursor(98,40);u8g2.print(rightScore);u8g2.drawStr(100,60,"Win !");// screen displaysendingState=true;}}while(u8g2.nextPage());}voidscore(){Button(leftServePin,1);Button(rightServePin,3);if(randomNumber%2==0){if((button[1].flag!=true)&&(button[3].flag==true)){leftScore++;for(intm=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(intm=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(intm=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(intm=0;m<5;m++){button[m].flag=false;}randomNumber=random(0,100);if(leftScore!=winScore){Step_state=0x00;}else{Step_state=0x02;}}elseif((button[1].flag==true)&&(button[3].flag==true)){if((i==5)&&(j==9)){rightScore++;for(intm=0;m<i;m++){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}for(intm=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(intm=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(intm=0;m<i;m++){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}for(intm=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(intm=0;m<5;m++){button[m].flag=false;}randomNumber=random(0,100);if(leftScore!=winScore){Step_state=0x00;}else{Step_state=0x02;}}}}}elseif(randomNumber%2==1){if((button[1].flag==true)&&(button[3].flag!=true)){rightScore++;for(intm=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(intm=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(intm=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(intm=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(intm=0;m<i;m++){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}for(intm=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(intm=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(intm=0;m<i;m++){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}for(intm=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(intm=0;m<5;m++){button[m].flag=false;}randomNumber=random(0,100);if(rightScore!=winScore){Step_state=0x00;}else{Step_state=0x02;}}}}}}voidbuttonFlag(){Button(buttonZeroPin,2);if(button[2].flag==true){for(intm=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;}}voidleftBlink(){unsignedlongcurrentMillis=millis();if(i<NumPixels){if(currentMillis-blinkTime1>=Period1){//period1msfor(intm=0;m<i;m++){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}}if(currentMillis-blinkTime1>=Period2){//period2msblinkTime1=currentMillis;i++;pixels.setPixelColor(i,pixels.Color(0,0,255));pixels.show();}}if(i==NumPixels){for(intm=0;m<NumPixels;m++){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}}}voidrightBlink(){unsignedlongcurrentMillis=millis();if(j>0){if(currentMillis-blinkTime2>=Period1){//periodmsfor(intm=10;m>j;m--){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}}if(currentMillis-blinkTime2>=Period2){//periodmsblinkTime2=currentMillis;j--;pixels.setPixelColor(j,pixels.Color(255,0,0));pixels.show();}}if(j==0){for(intm=0;m<NumPixels;m++){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}}}voidButton(intbutton_Pin,intbutton_num){intreading=digitalRead(button_Pin);if(reading!=button[button_num].lastButtonState){if(reading==LOW){//LOWbutton[button_num].flag=true;}}button[button_num].lastButtonState=reading;}voidwinBlink(){unsignedlongcurrentMillis=millis();// record and store time if(leftScore==winScore){if(currentMillis-blinkTime3>=Period1){// check periodmsfor(intm=0;m<NumPixels;m++){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}}if(currentMillis-blinkTime3>=Period2){// check periodmsblinkTime3=currentMillis;for(intm=0;m<NumPixels;m++){pixels.setPixelColor(m,pixels.Color(0,0,255));pixels.show();}}}elseif(rightScore==winScore){if(currentMillis-blinkTime3>=Period1){// check periodmsfor(intm=0;m<NumPixels;m++){pixels.setPixelColor(m,pixels.Color(0,0,0));pixels.show();}}if(currentMillis-blinkTime3>=Period2){// check periodmsblinkTime3=currentMillis;for(intm=0;m<NumPixels;m++){pixels.setPixelColor(m,pixels.Color(255,0,0pixels.show();}}}}
U8g2_Arduino-master
C/C++
Please download the ZIP library for the project from https://github.com/olikraus/U8g2_Arduino
No preview (download only).
Adafruit_NeoPixel-master
C/C++
Please download the ZIP library for the project from https://github.com/adafruit/Adafruit_NeoPixel/find/master
Comments
Please log in or sign up to comment.