//-- Control int SPEED = 2500; int LEDpin = 13; int ButtonPin = 12; char* msg[] = { " BABY ON BOARD ", " WICHITA STATE UNIVERSITY ", " HELP ", " OUT OF GAS", " NEXT MESSAGE ", " LAST MESSAGE " }; int NumOfMessages = 4; int MessageLength; int MessageSelect = 0; //-- Columns (Negative Cathodes) -- int latchPin1 = 2; //Arduino pin connected to Green 10 RCK of TPIC6C595 int clockPin1 = 3; //Arduino pin connected to Yellow 15 SRCK of TPIC6C595 int dataPin1 = 4; //Arduino pin connected to Blue 2 SER IN of TPIC6C595 //-- Rows (Positive Anodes) -- int latchPin2 = 5; //Arduino pinn connected to Green Latch 12 ST_CP / RCK of 74HC595 int clockPin2 = 6; //Arduino pin connected to Yellow Clock 11 SH_CP / SCK of 74HC595 int dataPin2 = 7; //Arduino pin connected to Blue Data 14 DS / SI of 74HC595 //=== B I T M A P === //Bits in this array represents one LED of the matrix // 8 is # of rows, 7 is # of LED matrix we have byte bitmap[8][3]; // Change the 7 to however many matrices you want to use. int numZones = sizeof(bitmap) / 8; // I will refer to each group of 8 columns (represented by one matrix) as a Zone. int maxZoneIndex = numZones-1; int numCols = numZones * 8; //=== F O N T === byte alphabets[][5] = { {0,0,0,0,0}, {63, 72, 136, 72, 63}, {255, 145, 145, 145, 110}, {126, 129, 129, 129, 129}, {255, 129, 129, 66, 60}, {255, 145, 145, 145, 129}, {255, 144, 144, 144, 128}, {60, 66, 129, 137, 142}, {255, 8, 8, 8, 255}, {0, 129, 255, 129, 0}, {2, 129, 129, 254, 128}, {255, 8, 20, 34, 65}, {255, 1, 1, 1, 1}, {255, 64, 32, 64, 255}, {255, 64, 32, 16, 255}, {126, 129, 129, 129, 126}, {127, 144, 144, 144, 96}, {126, 129, 132, 130, 125}, {127, 152, 148, 146, 97}, {97, 145, 145, 145, 142}, {128, 128, 255, 128, 128}, {254, 1, 1, 1, 254}, {252, 2, 1, 2, 252}, {255, 2, 4, 2, 255}, {129, 66, 60, 66, 129}, {224, 16, 31, 16, 224}, {131, 133, 137, 145, 225}, }; //=== S E T U P === void setup() { Serial.begin(9600); pinMode(latchPin1, OUTPUT); pinMode(clockPin1, OUTPUT); pinMode(dataPin1, OUTPUT); pinMode(LEDpin, OUTPUT); pinMode(12 , INPUT); digitalWrite(12 , HIGH); //turn on pull up for button pinMode(latchPin2, OUTPUT); pinMode(clockPin2, OUTPUT); pinMode(dataPin2, OUTPUT); //-- Clear bitmap -- for (int row = 0; row < 8; row++) { for (int zone = 0; zone <= maxZoneIndex; zone++) { bitmap[row][zone] = 0; } } } //=== F U N C T I O N S === // This routine takes whatever we've setup in the bitmap array and display it on the matrix void RefreshDisplay() { for (int row = 0; row < 8; row++) { int rowbit = 1 << row; digitalWrite(latchPin2, LOW); //Hold latchPin LOW for as long as we're transmitting data shiftOut(dataPin2, clockPin2, MSBFIRST, ~rowbit); //Transmit data //-- Start sending column bytes -- digitalWrite(latchPin1, LOW); //Hold latchPin LOW for as long as we're transmitting data //-- Shift out to each matrix (zone is 8 columns represented by one matrix) // for (int zone = maxZoneIndex; zone >= 0; zone--) { for (int zone = 0; zone <= maxZoneIndex; zone++) { shiftOut(dataPin1, clockPin1, LSBFIRST, bitmap[row][zone]); } //-- Done sending Column bytes, flip both latches at once to eliminate flicker digitalWrite(latchPin1, HIGH); //Return the latch pin high to signal chip that it no longer needs to listen for information digitalWrite(latchPin2, HIGH); //Return the latch pin high to signal chip that it no longer needs to listen for information //-- Wait a little bit to let humans see what we've pushed out onto the matrix -- delayMicroseconds(SPEED); } } // Converts row and colum to actual bitmap bit and turn it off/on void Plot(int col, int row, bool isOn) { int zone = col / 8; int colBitIndex = col % 8; byte colBit = 1 << colBitIndex; if (isOn) bitmap[row][zone] = bitmap[row][zone] | colBit; else bitmap[row][zone] = bitmap[row][zone] & (~colBit); } // Plot each character of the message one column at a time, updated the display, shift bitmap left. void AlphabetSoup() { SPEED = 2500; for (int charIndex=0; charIndex < (MessageLength); charIndex++) { int alphabetIndex = (*(msg[MessageSelect] + charIndex) - '@'); if (alphabetIndex < 0) alphabetIndex=0; //-- Draw one character of the message -- // Each character is only 5 columns wide, but I loop two more times to create 2 pixel space betwen characters for (int col = 0; col < 7; col++) { if (digitalRead(ButtonPin)==1){ // if the button is pushed digitalWrite(LEDpin, HIGH); while (digitalRead(ButtonPin) == 1){ delay(100); } digitalWrite(LEDpin, LOW); ++MessageSelect; SPEED = 1; } digitalWrite(LEDpin , !(digitalRead(LEDpin))); for (int row = 0; row < 8; row++) { // Set the pixel to what the alphabet say for columns 0 thru 4, but always leave columns 5 and 6 blank. bool isOn = 0; if (col<5) isOn = bitRead( alphabets[alphabetIndex][col], 7-row ) == 1; Plot( numCols-1, row, isOn); // We ALWAYS draw on the rightmost column, the shift loop below will scroll it leftward. } //-- The more times you repeat this loop, the slower we would scroll -- for (int refreshCount=0; refreshCount < 5; refreshCount++) RefreshDisplay(); //-- Shift the bitmap one column to left -- for (int row=0; row<8; row++) { for (int zone=0; zone < numZones; zone++) { // This right shift would show as a left scroll on display because leftmost column is represented by least significant bit of the byte. bitmap[row][zone] = bitmap[row][zone] >> 1; // Roll over lowest bit from the next zone as highest bit of this zone. if (zone < maxZoneIndex) bitWrite(bitmap[row][zone], 7, bitRead(bitmap[row][zone+1],0)); } } } } } //=== L O O P === void loop() { String txtMsg = msg[MessageSelect]; int x = txtMsg.length(); MessageLength = txtMsg.length(); SPEED = 2500; if (MessageSelect > (NumOfMessages - 1)){ MessageSelect = 0; } Serial.print(MessageSelect ,DEC); Serial.print(" "); Serial.print(MessageLength,DEC); Serial.print(" "); Serial.println(msg[MessageSelect]); AlphabetSoup(); /* if (Serial.available() > 0) { AlphabetSoup(Serial.read()); } */ }