RGB Panel Jumbotron
Contributors:
b_e_n
Teensy Code
The Teensy code is fairly long and involved, so we're just going to embed the whole thing here.
language:c
/*
* Further modified by Ben Leduc-Mills, standing on the shoulders of those mentioned below.
*
* Modified by Markus Lipp adding interleaved buffers, streaming, 32x32 & 24bit support
*
* Based on "_16x32_Matrix R3.0" by Creater Alex Medeiros, http://PenguinTech.tk
* Use code freely and distort its contents as much as you want, just remeber to thank the
* original creaters of the code by leaving their information in the header. :)
*/
//Define pins
const uint8_t
//PortC
APIN = 15, BPIN = 22, CPIN = 23, DPIN = 9,
CLOCKPIN = 10, LATCHPIN = 13, OEPIN = 11,
//PortD
R1PIN = 2, R2PIN = 8,
G1PIN = 14, G2PIN = 6,
B1PIN = 7, B2PIN = 20;
uint8_t pinTable[13] =
{
R1PIN, R2PIN, G1PIN, G2PIN, B1PIN, B2PIN,
APIN, BPIN, CPIN, DPIN, CLOCKPIN, LATCHPIN, OEPIN
};
//Addresses 1/8 rows Through a decoder
uint16_t const A = 1, B = 2, C = 4, D = 8;
//Acts like a 16 bit shift register
uint16_t const SCLK = 16;
uint16_t const LATCH = 32;
uint16_t const OE = 64;
//Decoder counter var
uint16_t const abcVar[16] =
{
0, A, B, A + B, C, C + A, C + B, A + B + C,
0 + D, A + D, B + D, A + B + D, C + D, C + A + D, C + B + D, A + B + C + D
};
//Data Lines for row 1 red and row 9 red, ect.
uint16_t const RED1 = 1, RED2 = 8;
uint16_t const GREEN1 = 2, GREEN2 = 16;
uint16_t const BLUE1 = 4, BLUE2 = 32;
const uint8_t SIZEX = 32;
const uint8_t SIZEY = 32;
//Here is where the data is all read
uint8_t interleavedBuffer[SIZEX*SIZEY * 4];
//BAM and interrupt variables
boolean actDisplay = false;
uint8_t rowN = 0;
uint16_t BAM;
uint8_t BAMMAX = 7; //now 24bit color! (0-7)
void setup()
{
for(uint8_t i = 0; i < 13; i++)
{
pinMode(pinTable[i], OUTPUT);
}
timerInit();
Serial.begin(250000);
}
uint8_t r, g, prevVal, val;
int dataPos = 0;
void loop()
{
if (Serial.available())
{
prevVal = val;
val = Serial.read();
if ( (prevVal == 192 && val == 192) || dataPos >= 4096)
{
dataPos = 0;
}
else
{
interleavedBuffer[dataPos++] = val;
}
}
}
IntervalTimer timer1;
#define BAMDUR 2
void timerInit()
{
BAM = 0;
timer1.begin(attackMatrix, BAMDUR);
}
//The updating matrix stuff happens here
//Each pair of rows is taken through its BAM cycle,
//then the rowNumber is increased and id done again
void attackMatrix()
{
uint16_t portData;
//sets up which BAM the matrix is on
if(BAM == 0)
{
timer1.begin(attackMatrix, BAMDUR); //code takes max 41 microsec to complete
}
if(BAM == 1)
{
timer1.begin(attackMatrix, BAMDUR * 2); //so 42 is a safe number
}
if(BAM == 2)
{
timer1.begin(attackMatrix, BAMDUR * 4);
}
if(BAM == 3)
{
timer1.begin(attackMatrix, BAMDUR * 8);
}
if(BAM == 4)
{
timer1.begin(attackMatrix, BAMDUR * 16);
}
if(BAM == 5)
{
timer1.begin(attackMatrix, BAMDUR * 32);
}
if(BAM == 6)
{
timer1.begin(attackMatrix, BAMDUR * 64);
}
if(BAM == 7)
{
timer1.begin(attackMatrix, BAMDUR * 128);
}
portData = 0; // Clear data to enter
portData |= (abcVar[rowN]) | OE; // abc, OE
portData &= ~ LATCH; //LATCH LOW
GPIOC_PDOR = portData; // Write to Port
uint8_t *start = &interleavedBuffer[rowN * SIZEX * 8 + ((7 - BAMMAX) + BAM) * 32];
for(uint8_t _x = 0; _x < 32; _x++)
{
GPIOD_PDOR = start[_x]; // Transfer data
GPIOC_PDOR |= SCLK;// Clock HIGH
GPIOC_PDOR &= ~ SCLK; // Clock LOW
}
GPIOC_PDOR |= LATCH;// Latch HIGH
GPIOC_PDOR &= ~ OE; // OE LOW, Displays line
if(BAM >= BAMMAX) //Checks the BAM cycle for next time.
{
if(rowN == 15)
{
rowN = 0;
}
else
{
rowN ++;
}
BAM = 0;
actDisplay = false;
}
else
{
BAM ++;
actDisplay = true;
}
}
Remember to have the board type (Teensy 3.1), USB Type (serial), and CPU Speed (96kHz overclock) set correctly under the 'Tools' menu in the Arduino IDE.