Bouncing Ball with Paddle

Keep the ball bouncing in the display using the controls to move the paddle


Small Breadboard


Male To Male Wire


InventrKits HERO

The HERO is a derivative of “Arduino UNO R3 Reference design” we just changed up a few things to make it our own. If you’re curious about what goes into our HERO board we published the open-source hardware files on our GitHub.


Push button switches

The switches came with one of the HERO board kits


DollaTek 1.5inch OLED Display Module I2C IIC SPI Serial 128x128 Color OLED LCD Display Module for Arduino



This is a continuation of my Bouncing Ball project.  I used a different display this time.  A 128×128 color OLED.  I’m also using a Arduino nano, but this will work with an UNO as well.

Use the left and right buttons to move the paddle to keep the ball bouncing.

The display used is: DollaTek 1.5inch OLED Display Module I2C IIC SPI Serial 128×128 Color OLED LCD Display Module for Arduino





Leave a Reply

Your email address will not be published. Required fields are marked *

#include <Ucglib.h> //#define DEBUG Ucglib_SSD1351_18x128x128_HWSPI ucg(/*cd=*/ 9, /*cs=*/ 10, /*reset=*/ 8); // dimensions of display int width; int height; // position of ball and paddle double ballX; double ballY; int paddleX; // direction of ball int xDir = 1; int yDir = 1; // slope will negate when a wall is hit double slope; double yIntercept; #define ballRadius 2 #define paddleWidth 15 #define paddleHeight 4 #define paddleY height-paddleHeight-5 #define paddleSpeed 2 #define leftButtonPin 2 #define rightButtonPin 3 void setup() { #ifdef DEBUG Serial.begin(9600); #endif pinMode(leftButtonPin, INPUT_PULLUP); pinMode(rightButtonPin, INPUT_PULLUP); randomSeed(analogRead(0)); ucg.begin(UCG_FONT_MODE_TRANSPARENT); ucg.powerDown(); ucg.clearScreen(); ucg.powerUp(); width = ucg.getWidth(); height = ucg.getHeight(); // randomize starting position for ball ballX = random(ballRadius+1, width-ballRadius-1); ballY = random(ballRadius+1, paddleY-ballRadius-1); slope = -random(20, 500) / 100.0; yIntercept = ballY – ballX * slope; // start paddle underneath ball paddleX = round(ballX) – paddleWidth / 2; if (paddleX < 1) paddleX = 1; else if (paddleX > (width-paddleWidth-1)) paddleX = width-paddleWidth-1; // draw border ucg.setColor (255, 255, 255); ucg.drawFrame (0, 0, width, height); } void loop() { // read buttons int left = digitalRead(leftButtonPin); int right = digitalRead(rightButtonPin); #ifdef DEBUG Serial.print(“X=”); Serial.print(ballX); Serial.print(” Y=”); Serial.print(ballY); Serial.print(” slope=”); Serial.print(slope); Serial.print(” Y Intercept=”); Serial.print(yIntercept); Serial.print(” paddle=”); Serial.print(paddle); Serial.println(); #endif // if ball goes past the paddle, draw red border and loop forever, game over if (ballY >= height-ballRadius-2) { ucg.setColor (255, 0, 0); ucg.drawFrame (0, 0, width, height); while (true) {} } // erase ball in last position ucg.setColor (0, 0, 0); ucg.drawDisc (round(min(max(ballX, ballRadius+1), width-ballRadius-2)), round(min(max(ballY, ballRadius+1), height-ballRadius-2)), ballRadius, UCG_DRAW_ALL); // if one of the buttons was pressed, move the paddle if ((left == LOW) || (right == LOW)) { // paddle moved so erase old one ucg.drawBox(paddleX, paddleY, paddleWidth, paddleHeight); if (left == LOW) { paddleX -= paddleSpeed; if (paddleX < 1) paddleX = 1; } else if (right == LOW) { paddleX += paddleSpeed; if (paddleX > (width-paddleWidth-1)) paddleX = width-paddleWidth-1; } } // if the ball hits the left or right side of the screen, bounce if ((ballX <= ballRadius+1) || (ballX >= width-ballRadius-2)) { xDir = -xDir; slope = -slope; yIntercept = ballY – (ballX * slope); } // if the ball hits the top of the screen or the top of the paddle, bounce if ((ballY <= ballRadius+1) || ((ballY >= paddleY-ballRadius-2) && ((paddleX <= ballX) && (ballX <= paddleX+paddleWidth)))) //(ballY >= height-ballRadius-2)) { yDir = -yDir; slope = -slope; yIntercept = ballY – (ballX * slope); } // calculate next position of ball ballX += xDir; // ballY += yDir; ballY = slope * ballX + yIntercept; // this prevents weird bug with ball and paddle interaction if ((ballY >= paddleY-ballRadius-2) && ((paddleX <= ballX) && (ballX <= paddleX+paddleWidth))) ballY = paddleY-ballRadius-2; // draw the paddle ucg.setColor (255, 255, 255); ucg.drawBox(paddleX, paddleY, paddleWidth, paddleHeight); // draw ball ucg.setColor (0, 0, 255); ucg.drawDisc (round(min(max(ballX, ballRadius+1), width-ballRadius-2)), round(min(max(ballY, ballRadius+1), height-ballRadius-2)), ballRadius, UCG_DRAW_ALL); }
Leave a comment
Stefano Nicolini


Leave a comment
Share on whatsapp
Share on facebook
Share on twitter
Share on linkedin
Share on reddit
Share on pinterest
Share on email


I cascaded four SN74HC595 shift registers to control 32 LEDs on 4 registers using 3 wires. I am adding a I2C 20×4 LCD screen to display the register and led values. I might add a standard 16×2 LCD screen to show up it is done.
A simple light meter. It’s not calibrated to any meaningful scale, but the digital readout shows a higher number the brighter is the light falling on the photoresistor.