Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
silas_hansen
Published

Air Football

Fan of football but like to play air hockey? Air football is the perfect combination for you!

IntermediateFull instructions provided4,711
Air Football

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Line tracker - SEN-KY033LT
×2
Brushless Fan DC 12V - 3000 rpm
×1
Nextion NX4827T043 - 4.3” TFT LCD Intelligent Touch Display
Itead Nextion NX4827T043 - 4.3” TFT LCD Intelligent Touch Display
×1
Momentary switch DBWLI
×1
AA Batteries
AA Batteries
×14
Battery Holder, AA x 8
Battery Holder, AA x 8
×1
Battery Holder, AA x 6
Battery Holder, AA x 6
×1
WS2812 Addressable LED Strip
Digilent WS2812 Addressable LED Strip
×1
60W PCIe 12V 5A Power Supply
Digilent 60W PCIe 12V 5A Power Supply
×1

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Laser cutter (generic)
Laser cutter (generic)
Soldering iron (generic)
Soldering iron (generic)
Tape, Painters Tape
Tape, Painters Tape
Plier, Cutting
Plier, Cutting
Sticker printer

Story

Read more

Custom parts and enclosures

Technical Drawings

STL files for 3D print

SVG files for laser cut

Nextion Setup and Images

EPS-files for printing stickers

Schematics

Electrical circuit

The electrical components are connected in two separate circuits. One for the fan and one to provide the interaction with the Arduino, sensors, and actuators. Be aware that the shield in the schematic is different from the one I made, but it serves the same purpose of providing more 5V and GND pins.

Code

Air Football - Arduino IDE code

Arduino
// AIR FOOTBALL BY SILAS HANSEN
// CREATIVE DESIGN & TECHNOLOGY
// SAXION UNIVERSITY
// 30.01.2022

const int buttonPin = 8;                               // Integer to indicated which pin the button is connected to.
int buttonState = 0;                                   // Integer to store data from the button.
int scoreBlue = 0;                                     // Variable to count the score for the blue team.
int scoreRed = 0;                                      // Variable to count the score for the red team.
boolean addScoreBlue = false;                          // Boolean to trigger animation, blue lights and increase in score for the blue team.
boolean addScoreRed = false;                           // Boolean to trigger animation, red lights and increase in score for the red team.
int lineTrackerTriggeredBlue = 0;                      // Variable to display animation and blue light show first and then add the score afterwards.
int lineTrackerTriggeredRed = 0;                       // Variable to display animation and red light show first and then add the score afterwards.
#include <Adafruit_NeoPixel.h>                         // Including Adafruit library to control the NeoPixel.
int lightDelay = 10;                                   // Integer for length of delay in light shows. 
const int Pin = 7;                                     // Varible for the pin where the NeoPixel strip is connected to
const int NumberOfPixels = 56;                         // Variable for the number of pixels in the NeoPixel strip
Adafruit_NeoPixel pixels(NumberOfPixels, Pin, NEO_GRB + NEO_KHZ800); //The type of NeoPixel is defined.

void setup() {
  Serial.begin(9600);                                  // Initializes the serial monitor and Nextion display.
  attachInterrupt(0,addscoreblue,FALLING);             // Calls the function "addscoreblue" when signal from blue's line tracker is triggered.
  attachInterrupt(1,addscorered,FALLING);              // Calls the function "addscorered" when signal from red's line tracker is triggered.
  pinMode(buttonPin, INPUT_PULLUP);                    // Defining the button as an input.
  pixels.begin();                                      // Initialises the NeoPixel strip.
}

void loop() {
  for(int i=0; i<28; i++) {                            // For loop to manage one half of the LED strip.
    pixels.setPixelColor(i, pixels.Color(0, 0, 255));  // Half of the LED's is set to blue.
    pixels.show();}                                    // Send the updated pixel colors to the hardware.
    
  for(int i=28; i<NumberOfPixels; i++) {               // For loop to manage the other half of the LED strip.
    pixels.setPixelColor(i, pixels.Color(255, 0, 0));  // Sets the other half of LED's to red. 
    pixels.show();}                                    // Send the updated pixel colors to the hardware.
    
  if (addScoreBlue==true){                             // If the blue team scores, the following code is executed.
    lineTrackerTriggeredBlue++;                         
      if(lineTrackerTriggeredBlue == 1){               // When the puck covers the line tracker, the animation and blue light show are displayed.
        dynamicPixelsBlue();                           // Function to display the blue light show is called.
        Serial.print("page 1");                        // The page number is send to the Nextion display.
        Serial.write(0xff);                            // When something is send to a Nextion display, these three lines need to be called.
        Serial.write(0xff);
        Serial.write(0xff);
        delay(5000);                                   // Delay to let the animation play for 5 secs.
        Serial.print("page 0");                        // The page number is send to the Nextion display to display the scoreboard again.
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);}
      if(lineTrackerTriggeredBlue == 2){               // When is removed from the goal, the score is added in the Nextion display.
        scoreBlue = scoreBlue + 1;
        lineTrackerTriggeredBlue = 0;}                 // Resets the value, so code above can be repeated if blue team scores again.
  }
  addScoreBlue = false;                                // Sets the boolean to false again, so code above can be repeated if blue team scores again.
  Serial.print("n0.val=");                             // Defines that the following variable is a number.
  Serial.print(scoreBlue);                             // The variable of the blue team's score is send to the display.
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  
  if (addScoreRed==true){                              // If the red team scores, the following code is executed.
    lineTrackerTriggeredRed++;
      if(lineTrackerTriggeredRed == 1){                // When the puck covers the line tracker, the animation and red light show are displayed.
        dynamicPixelsRed();                            // Function to display the red light show is called.
        Serial.print("page 1");                        // The page number is send to the Nextion display.
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
        delay(5000);                                   // Delay to let the animation play for 5 secs.
        Serial.print("page 0");                        // The page number is send to the Nextion display to display the scoreboard again.
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);}  
      if(lineTrackerTriggeredRed == 2){                // When is removed from the goal, the score is added in the Nextion display.
        scoreRed = scoreRed + 1;
        lineTrackerTriggeredRed = 0;}                  // Resets the value, so code above can be repeated if red team scores again.
  }
  addScoreRed = false;                                 // Sets the boolean to false again, so code above can be repeated if red team scores again.
  Serial.print("n1.val=");                             // Defines that the following variable is a number.
  Serial.print(scoreRed);                              // The variable of the red team's score is send to the display.
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
  
  buttonState = digitalRead(buttonPin);                // The Arduino recieves data from the button and sets it as buttonState. 
  resetScore();                                        // Calls a function that detect if score needs to be resetted.
  WhoWins();                                           // Calls a function to detect if one of the players won the game.
}

void addscoreblue(){                                   // Function that is called when blue team scores.
  addScoreBlue = true;}                                // Sets boolean to true, so statement in loop is triggered.

void addscorered(){                                    // Function that is called when red team scores.
  addScoreRed = true;}                                 // Sets boolean to true, so statement in loop is triggered.

void resetScore(){                                     // Function to reset the score if the button is pressed.
 if (buttonState == LOW) {
  scoreRed = 0;
  scoreBlue = 0;}
}

void resetScoreAfterWin(){                             // Function to reset score when one of the players won the game. 
  scoreRed = 0;
  scoreBlue = 0;}

void dynamicPixelsBlue() {                             // Function to make a light show when blue team scores.
  pixels.clear();                                      // Turns off all LED's, so it's ready for the following light pattern.
  for(int i=0; i<NumberOfPixels; i++) {                // For loop to make wave effect with 10 pixels.
    pixels.setPixelColor(i, pixels.Color(0, 0, 255));  // Pixel i is set to blue.
    pixels.setPixelColor(i-10, pixels.Color(0, 0, 0)); // The pixel that is 10 behind of pixel i is turned off.
    pixels.show();                                     // Send the updated pixel colors to the hardware.
    delay(lightDelay);}                                // Pause before next pass through loop
    
  for(int i=56; i>0; i--) {                            // For loop to make wave effect with 10 pixels but in the other direction than above.
    pixels.setPixelColor(i, pixels.Color(0, 0, 255));  // Pixel i is set to blue.
    pixels.setPixelColor(i+10, pixels.Color(0, 0, 0)); // The pixel that is 10 infront of pixel i is turned off.
    pixels.show();                                     // Send the updated pixel colors to the hardware.
    delay(lightDelay);}                                // Pause before next pass through loop
    
  for(int i=0; i<NumberOfPixels; i++){                 // For loop to turn on all pixels.
    pixels.setPixelColor(i, pixels.Color(0, 0, 255));} // Sets all pixels to blue. 
    pixels.show();                                     // Send the updated pixel colors to the hardware.
    delay(lightDelay+200);                             // Keeps all LED's on for 210 millisecs. 
    
  for(int i=0; i<NumberOfPixels; i++){                 // For loop to turn off all pixels.
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));}   // Sets all pixels to no color (off).
    pixels.show();                                     // Send the updated pixel colors to the hardware.
    delay(lightDelay+200);                             // Keeps all LED's off for 210 millisecs.
    
  for(int i=0; i<NumberOfPixels; i++){                 // For loop to turn on all pixels.
    pixels.setPixelColor(i, pixels.Color(0, 0, 255));} // Sets all pixels to blue.
    pixels.show();                                     // Send the updated pixel colors to the hardware.
    delay(lightDelay+200);                             // Keeps all LED's on for 210 millisecs.
    
  for(int i=0; i<NumberOfPixels; i++){                 // For loop to turn off all pixels.
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));}   // Sets all pixels to no color (off).
    pixels.show();                                     // Send the updated pixel colors to the hardware.
    delay(lightDelay+200);                             // Keeps all LED's off for 210 millisecs.
}

void dynamicPixelsRed() {                              // Exactly same function and structure as the blue light show, but the color is instead red.
  pixels.clear(); 
  for(int i=0; i<NumberOfPixels; i++) { 
    pixels.setPixelColor(i, pixels.Color(255, 0, 0));
    pixels.setPixelColor(i-10, pixels.Color(0, 0, 0)); 
    pixels.show();   
    delay(lightDelay);} 
    
  for(int i=56; i>0; i--) { 
    pixels.setPixelColor(i, pixels.Color(255, 0, 0));
    pixels.setPixelColor(i+10, pixels.Color(0, 0, 0));
    pixels.show();   
    delay(lightDelay);} 
    
  for(int i=0; i<NumberOfPixels; i++){
    pixels.setPixelColor(i, pixels.Color(255, 0, 0));}
    pixels.show();   
    delay(lightDelay+200);
    
  for(int i=0; i<NumberOfPixels; i++){
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));}
    pixels.show();   
    delay(lightDelay+200);
    
  for(int i=0; i<NumberOfPixels; i++){
    pixels.setPixelColor(i, pixels.Color(255, 0, 0));} 
    pixels.show();   
    delay(lightDelay+200);
    
  for(int i=0; i<NumberOfPixels; i++){
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));}
    pixels.show();   
    delay(lightDelay+200);
}

void WhoWins(){                                        // Function to display winner animation.
  if(scoreBlue==3){                                    // If blue team scores three goals, the blue winner animation is displayed.
    resetScoreAfterWin();                              // Calls function to reset score.
    Serial.print("page 2");                            // The page number is send to the Nextion display.
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);
    delay(5000);                                       // Delay to let the animation play for 5 secs.
    Serial.print("page 0");                            // The page number is send to the Nextion display to display the scoreboard again.
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);}
    
  if(scoreRed==3){                                     // If red team scores three goals, the blue winner animation is displayed.
    resetScoreAfterWin();
    Serial.print("page 3");                            // The page number is send to the Nextion display.
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);
    delay(5000);                                       // Delay to let the animation play for 5 secs.
    Serial.print("page 0");                            // The page number is send to the Nextion display to display the scoreboard again.
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff);}
}

Credits

silas_hansen
1 project • 3 followers

Comments