Paper prototypes:
Red LED flashlight:
LED streetlight
LED Wallet Light
LED / Photodiode IR transceiver
Device with LED notification on side
LED Pong
LED Bike Spoke Persistence of Vision Display
Desktop 3d POV display
LED-lit projector
Cup that lights up upon needing refill (checks force sensor for 1/3 full state)
Project - Pong on a LED matrix display
I implemented a working single player variant of Pong on a LED matrix display
This involved soldering 35 LEDs into a 7x5 matrix.
I wired the 7 columns to port B and the ground lines for each row to pins on ports C and D
I used code to turn on each row in sequence, while changing the column bits each time. I had a software framebuffer and updated the paddle/ball position every 100ms.
Initial testing (Space Invader!)
/*
Pong v. 0.01
Sam D'Amico
EE47 Lab 2
*/
#define WIDTH 7
#define HEIGHT 5
// The setup() method runs once, when the sketch starts
void setup() {
// initialize the LED pin as an output:
pinMode(21, INPUT);
pinMode(20, INPUT);
pinMode(19, INPUT);
DDRB = 0xFF;
DDRD = 0xFF;
DDRC = 0xFF;
//DDRF = 0x00;
// initialize the button pin as an input
//pinMode(buttonPin, INPUT);
}
char display[HEIGHT][WIDTH] = {{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0},
{0,0,0,0,0,0,0}};
char paddleX = 0, paddleY=0;
char ballX = 3, ballY = 3;
char ballVx = 1, ballVy = 1;
char lost = 0;
void movePaddle()
{
static long now = 0;
if((now+100) < millis())
{
display[paddleY][0] = 0;
display[paddleY+1][0] = 0;
if(paddleY > 0)
{
if(!digitalRead(21))
paddleY--;
} else paddleY = 0;
if(paddleY < (HEIGHT-2))
{
if(!digitalRead(20))
paddleY++;
} else paddleY = 3;
display[paddleY][0] = 1;
display[paddleY+1][0] = 1;
now = millis();
}
}
void moveBall()
{
static long now = 0;
if((now+100) < millis())
{
display[ballY][ballX] = 0;
ballX += ballVx;
ballY += ballVy;
if(ballX == (WIDTH-1)) ballVx*=-1;
if(ballX == 0)
if(ballY == paddleY || ballY == (paddleY+1)) ballVx*=-1;
else {
lost = 1;
return;
}
if(ballY == (HEIGHT-1)) ballVy*=-1;
if(ballY == 0) ballVy*=-1;
display[ballY][ballX] = 1;
now = millis();
}
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
// Start with all LEDs off, but the first row on (D0 low)
PORTB = 0x00;
PORTD = 0b1111110;
PORTC = 0xFF;
// draw the contents of the framebuffer
for(int i=0;i<HEIGHT;i++)
{
PORTB = 0x00;
for(int j=0;j<WIDTH;j++)
{
// this could be faster if I just used one byte and sent it straight to the port, but array access is easy
PORTB |= (display[i][j] << j);
}
// give time to render each row with basically no flicker
delay(1);
// since the row control is split between D0-3 and C6 (pin 9)
if(i < HEIGHT-2)
PORTD = ~(2 << i);
else {
PORTD = 0xFF;
digitalWrite(9, LOW);
}
}
// Reset the game if you press the start button after losing
if(!digitalRead(19))
{
lost = 0;
ballX = 3;
ballY = 3;
ballVx = 1;
ballVy = 1;
//delay(10000);
}
// Move the ball and paddle otherwise
if(!lost)
{
moveBall();
movePaddle();
}
}