LED Strip PONG
Step 1 - Build the Project
The code behind Pong is straightforward: "Did the ball collide with the paddle at a given time?". In this program, the code is checking: "Did the player press the button at the right time to 'strike' the ball?".
Step 2 - Upload the Code
Step 3 - Read the Walkthrough
First include the LEDStrip library. This library gives you access to a new set of commands (called methods) that make using the LED Strip easier. Without including the library, the Arduino software won’t recognize the new methods.
Next, create an integer variable called numPixels. Its value should be equal to the number of LEDs on your strip.
The middlePixel variable is an integer based on your numPixels variable. Integers truncate (cut off) all decimal places, so if you have 15 pixels, 15/2 will be an integer value of 7.
The integer variable named color holds a value from -1 to 300.
Each player has a color that flashes when they score a point. Set those color values with p1Color and p2Color.
The variable timer is a ‘long’ variable type. It takes up more program space than an int, but a long can hold very large numbers. Because long is counting milliseconds, it will quickly grow very large. The value of long is set equal to the value of millis(). Millis() is a function that automatically starts counting up when your program starts running.
The next four variables are boolean variables. They can only have one of two states: true or false. You’re using them here to mark that an event has happened. Since there are only two possibilities (the event happened or it did not), bool is best.
Your pixel variable holds the number of the active pixel that the code is modifying.
The ballDelay variable holds the amount of time (in milliseconds) that the program waits before moving the pixel and checking whether a player has hit the ball.
The Direction variable tells whether the pixel is moving toward the tip of the strip or toward the base. A -1 means the pixel is moving toward the base of the strip.
To tell the library the name & attributes of your LED Strip, you create an object. In this case, the object is called ‘strip’ and it has ‘numPixel’ pixels, the data pin is number 11, and the clock pin is number 12 on your carrier board.
In the setup() section, you set both players’ buttons as INPUT_PULLUP pin mode. The button will now send a LOW signal to Maker Board when the button is pressed.
In the loop, there are only 3 lines of code that are guaranteed to run every loop: the digitalRead of the buttons and the strip.draw() command. Everything else depends on the players, so there are many if statements. Because there are two players, many of the statements are duplicated.
The first two if statements check “was the button pressed and was the pixel in the correct position?”. The && is an AND statement, so both statements have to be true before the code inside the if statement runs. If both of those things are true, then the player’s hit variable becomes true.
Next is a series of nested if statements. These statements are only checked if the statement they are nested inside is true. Here you’ll see the value of indentation and the way curly braces are placed.
If millis (the automatic counter) minus the timer variable, then timer and millis() are set equal. This has the effect of creating a 250 millisecond timer without using a delay.
For the next if statement, three conditions have to be true before the if statement executes. First, player1 must have pressed their button. Second, the pixel must be at the base of the strip. Third, player1 must not have triggered the p1Early variable by holding the button. Only when all of those things are true, the pixel will change color, change direction, and reset the p1Hit variable to false.
The else if statement checks the alternative outcomes when pixel == 0. If player1 didn’t swing soon enough or (||) player 1 swung too early, the pixel is set to the middle, and the pixel direction is changed.
Then, the else if statement flashes the entire strip the color of the p2 team for 1 second to indicate p2 has scored a point. The p1Hit variable is reset for the next round.
The next if-else if statements are repeating the same checks as above for player 2.
All of the checks for the swings are only useful if the pixel is at either end of the strip. Otherwise, the code just keeps the pixel moving. The speed at which the pixel moves is determined by the ballDelay variable. The lower that variable, the faster the ball moves. Here, strip.setPixel() clears the previous pixel and then updates the pixel’s position by “Direction”. That could mean the pixel is moving up or down the strip, depending on whether Direction is positive or negative.
The order of the next statements in the code is very important. The pixel has just been moved one spot. Now you will immediately ask the question “Did the pixel just move to the end of the strip while the button was pressed?”. If that is true, then player1 was holding the button down when the pixel moved on to the end of the strip and they swung too early! The ‘p1Early’ variable is set to true so that next time through the loop, p1Early will mean they miss the ball.
The same check occurs for p2. If neither player has swung early at this point, the Early variables are set to false.
Now that pixel has a new position, it will be updated to the color of the player who has to hit the ball next.
Finally you’ve completed the if loop. The strip.draw() command will display the new pixel and color.
Whoa! That’s a lot of code. Remember all of this code runs with each loop. If your ballDelay variable is 250, the loop runs 4 times per second.