Create a gist now

Instantly share code, notes, and snippets.

#include "WProgram.h"
void UpdateDMD();
void Bounce();
void SetAllDots(byte value);
void SetDot(byte col, byte row, byte value);
void FrameToSerial();
#define pinDisplayEnable 3 // DMD pin 1
#define pinRowData 4 // One pin 3
#define pinRowClock 5 // DMD pin 5
#define pinColLatch 6 // DMD pin 7
#define pinDotClock 13 // DMD pin 9
#define pinDotData 11 // DMD pin 11
#define pinSPISlaveSelect 10 // SPI slave select, unused
#define pinSPIIn 12 // SPI MISO, unused
#define rowCount 32
#define colCount 128
#define bytesPerRow (colCount / 8)
#define frameSize 512 // 4096/4
byte frame[frameSize] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0xe0, 0x00, 0xee, 0x00,
0x00, 0x0c, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xc0, 0x00, 0x60, 0x00, 0x66, 0x00,
0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, 0x00, 0x60, 0x00, 0x66, 0x00,
0x00, 0x18, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x38, 0x66, 0x00, 0x60, 0x00, 0x66, 0x00,
0x00, 0x30, 0x40, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x38, 0x66, 0x00, 0x60, 0x00, 0x66, 0x00,
0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x38, 0x66, 0x00, 0x60, 0x00, 0x66, 0x00,
0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, 0x00, 0x60, 0x00, 0x66, 0x00,
0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x38, 0x60, 0x00, 0x60, 0x00, 0x66, 0x00,
0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x38, 0xc0, 0x00, 0x60, 0x00, 0x66, 0x00,
0x00, 0x70, 0x01, 0x81, 0xce, 0x63, 0x9e, 0x38, 0x00, 0x3f, 0x8e, 0xee, 0x6c, 0x38, 0x66, 0x00,
0x00, 0x70, 0xe2, 0x62, 0x66, 0xe6, 0x46, 0x6c, 0x00, 0x38, 0x06, 0x7e, 0x76, 0x6c, 0x66, 0x00,
0x00, 0x70, 0x66, 0x26, 0x27, 0xf6, 0x66, 0x66, 0x00, 0x38, 0x06, 0x63, 0x63, 0x66, 0x66, 0x00,
0x00, 0x70, 0x64, 0x34, 0x36, 0x74, 0x66, 0x66, 0x00, 0x38, 0x06, 0x63, 0x63, 0x66, 0x66, 0x00,
0x00, 0x70, 0x64, 0x34, 0x36, 0x2c, 0x66, 0x06, 0x00, 0x38, 0x06, 0x63, 0x63, 0x06, 0x66, 0x00,
0x00, 0x30, 0x6c, 0x3c, 0x36, 0x0c, 0x66, 0x36, 0x00, 0x38, 0x06, 0x63, 0x63, 0x36, 0x66, 0x00,
0x00, 0x30, 0x6f, 0xfc, 0x36, 0x06, 0x66, 0x7e, 0x00, 0x38, 0x06, 0x63, 0x63, 0x7e, 0x66, 0x00,
0x00, 0x30, 0x6c, 0x0c, 0x36, 0x06, 0x66, 0x46, 0x00, 0x38, 0x06, 0x63, 0x63, 0x46, 0x66, 0x00,
0x00, 0x38, 0x6c, 0x0c, 0x36, 0x02, 0xc6, 0xc6, 0x00, 0x38, 0x06, 0x63, 0x63, 0xc6, 0x66, 0x00,
0x00, 0x18, 0x64, 0x04, 0x36, 0x03, 0x86, 0xc6, 0x00, 0x38, 0x06, 0x63, 0x63, 0xc6, 0x66, 0x00,
0x00, 0x18, 0x44, 0x04, 0x36, 0x02, 0x06, 0x46, 0x00, 0x38, 0x06, 0x63, 0x63, 0x46, 0x66, 0x00,
0x00, 0x0c, 0xc6, 0x26, 0x26, 0x07, 0x06, 0x6e, 0x00, 0x38, 0x06, 0x63, 0x72, 0x6e, 0x66, 0x00,
0x00, 0x07, 0x83, 0xc3, 0xce, 0x07, 0x8e, 0x7e, 0x00, 0x7c, 0x0e, 0xe7, 0xfe, 0x7e, 0xee, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int clr; // temp variable for SPI I/O.
unsigned long t0;
int posX = 0;
int posY = 5;
int directionX = 3;
int directionY = 1;
void setup() {
pinMode(pinDotClock, OUTPUT);
pinMode(pinColLatch, OUTPUT);
pinMode(pinDotData, OUTPUT);
pinMode(pinRowData, OUTPUT);
pinMode(pinRowClock, OUTPUT);
pinMode(pinDisplayEnable, OUTPUT);
pinMode(pinSPIIn, INPUT);
pinMode(pinSPISlaveSelect, OUTPUT);
digitalWrite(pinSPISlaveSelect, HIGH);
digitalWrite(pinDisplayEnable, LOW);
digitalWrite(pinRowData, LOW);
digitalWrite(pinRowClock, HIGH); // Normal state is HIGH.
digitalWrite(pinDotClock, LOW);
digitalWrite(pinDotData, LOW);
digitalWrite(pinColLatch, LOW);
//SetAllDots(LOW);
// SPCR = 01010000
//interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
//sample on leading edge of clk,system clock/4 rate (fastest)
SPCR = (1<<SPE)|(1<<MSTR);//|0x3; // slowest
clr=SPSR;
clr=SPDR;
delay(10);
Serial.begin(9600);
Serial.println("Booted.");
// Fill in some dot data.
for(int row = 0; row < rowCount; row++) {
for(int col = 0; col < colCount; col++) {
if(row == 0 || row == 31) SetDot(col, row, HIGH);
}
}
// FrameToSerial();
t0 = millis();
}
unsigned long t1;
int frames = 0;
void loop() {
//SetAllDots((millis() / 10) % 2);
//SetAllDots(HIGH);
//while(millis() > 1000) { digitalWrite(pinDisplayEnable, LOW); } // stop after 10 seconds
if((frames % 2) == 0) {
Bounce();
}
// Cheesy row clear.
for(int i = 0; i < 128; i++) {
//SetDot(i, 16, LOW);
}
// SetDot(((millis()/100) % 128), 16, HIGH);
UpdateDMD();
frames++;
/*
t1 = millis();
if((t1 - t0) > 10000) {
Serial.print(frames/10, DEC);
Serial.println("Hz");
digitalWrite(pinDisplayEnable, LOW);
while(1);
}
*/
//Serial.print(".");
}
void UpdateDMD() {
for(int row = 0; row < rowCount; row++) {
delayMicroseconds(100);
// Program the new data for this row.
for(int index = 0; index < bytesPerRow; index++) {
if(row >= 1 && row < 31 && index > 0 && index < 15 && !(row == posY && index == (posX/8))) {
if((frames % 3) == 0) {
SPDR = frame[row * bytesPerRow + index];
} else {
SPDR = 0;
}
} else {
SPDR = frame[row * bytesPerRow + index];
}
while (!(SPSR & (1<<SPIF)));
}
digitalWrite(pinColLatch, HIGH); // Latch in the row of data we just wrote.
digitalWrite(pinColLatch, LOW);
digitalWrite(pinDisplayEnable, LOW); // Turn off the display while we latch in the this row.
if(row == 0) { // For some reason
digitalWrite(pinRowData, HIGH); // row data high on row 0
} else {
digitalWrite(pinRowData, LOW);
}
digitalWrite(pinRowClock, LOW); // Advance the row pointer.
delayMicroseconds(1); // Minimum 1us dip
digitalWrite(pinRowClock, HIGH);
digitalWrite(pinDisplayEnable, HIGH); // Turn on the display now that the column outputs are latched.
}
}
int leftLast = 0;
int rightLast = 0;
void Bounce() {
int oldX = posX;
int oldY = posY;
posX += directionX;
posY += directionY;
if(posX < 1 || posX >= colCount-1) {
// hit a side wall
if(directionX < 0) {
leftLast = posY;
} else {
rightLast = posY;
}
directionX = -directionX;
//directionY = -directionY;
posX = oldX;
}
if(posY < 1 || posY >= rowCount-1) {
// hit a top/bottom wall
//directionX = -directionX;
directionY = -directionY;
posY = oldY;
}
// Turn off the old dot, turn on the new one.
SetDot(oldX, oldY, LOW);
SetDot(posX, posY, HIGH);
// Paddles
for(int y = 1; y < rowCount-1; y++) {
SetDot(0, y, LOW);
SetDot(127, y, LOW);
}
int paddleY = min(26, max(0, posY));
int paddleX = 0;
if(directionX > 0) {
paddleX = 127;
for(int y = 0; y < 5; y++) {
SetDot(0, y + leftLast, HIGH);
}
} else {
for(int y = 0; y < 5; y++) {
SetDot(127, y + rightLast, HIGH);
}
}
for(int y = 0; y < 5; y++) {
SetDot(paddleX, y + paddleY, HIGH);
}
//Serial.print(posX, DEC);
//Serial.print(", ");
//Serial.println(posY, DEC);
}
void SetAllDots(byte value) {
if(value == LOW) {
value = 0;
} else {
value = 0xff;
}
for(int i = 0; i < frameSize; i++) {
frame[i] = value;
}
}
void SetDot(byte col, byte row, byte value) {
int byteIndex = row * bytesPerRow + (col / 8);
byte colBit = 1 << (7 - (col % 8));
byte masked = frame[byteIndex] & ~colBit;
if(!value) {
colBit = 0;
}
frame[byteIndex] = masked | colBit;
}
void FrameToSerial() {
for(int i = 0; i < frameSize; i++) {
if((i % bytesPerRow) == 0) {
Serial.println();
}
for(int bit = 7; bit >= 0; bit--) {
Serial.print((frame[i] >> bit) & 1, HEX);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment