WU_HuiQiao
Published © GPL3+

Mini Table Tennis(Arduino Nano + WS2812B LED Strip Lights)

Mini Table Tennis is fun!

BeginnerFull instructions provided2 hours690

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
PTS 645 Series Switch
C&K Switches PTS 645 Series Switch
×2
WS2812 Addressable LED Strip
Digilent WS2812 Addressable LED Strip
×1
0.96" OLED 64x128 Display Module
ElectroPeak 0.96" OLED 64x128 Display Module
×1
Breadboard (generic)
Breadboard (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

10 Pc. Jumper Wire Kit, 5 cm Long
10 Pc. Jumper Wire Kit, 5 cm Long

Story

Read more

Schematics

Schematics

In Fritzing format

Code

Code

C/C++
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_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++
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
No preview (download only).

Credits

WU_HuiQiao
1 project • 8 followers
I like building things.
Contact

Comments

Please log in or sign up to comment.