Pages: [1]   Go Down
Author Topic: Need HELP WITH SPI LED MATRIX????  (Read 1132 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey,
What I want to do is display some scrolling text on an 8x8 LED Matrix.  The matrix is from sparkfun and has the RG serial backpack.  I'm not really sure how to hook the SPI header up to the arduino.  And I know very little about the software side of things.  This is a project that is supposed to be a christmas gift for my girlfriend.  any help would be appreciated!

Thanks,
Ttom
Logged

Chicago | IL
Offline Offline
Newbie
*
Karma: 0
Posts: 23
Arduino Nerd
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Did you figure this out? Recently went around in a few circles till I got it right - the code is a little rough - but have one working now with the RG and RGB Matrix...
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah I managed to get what I wanted out of it; I'm pretty happy with how it turned out.  I used some code I found online and changed the sprite values to display a heart animation.  I also hooked it up to a switch that runs the animation once when pressed.  It's 7:40 am here and I'm kind of in a rush to get to school but I'll try to remember to post the code when I get back.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's the code:

Marc Pesce wrote this code to serve as a animation for burning man (http://markpesce.com/wiki/index.php/Arduino_Burning_Man).  I modified the code to display a heart animation that is initiated with a push button.  Enjoy.



#include <stdlib.h>

// Try to talk to the LED matrix from SparkFun
// With code stolen from here and there.
// This in theory will work.  In practice, who knows?
// Copyright (C) 2006, Mark D. Pesce
// Licensed under the GNU General Public License
//
// As of 18 August 2006 all of this appears to be working quite merrily

#define RG        // If the two-color display is used
//#define RGB    // If the three-color display is used

// define wiring pins from Arduino to Sparkfun Serial Backback Controller for SPI communication
#define clock 10    // SPI Clock to backpack
#define cs 12      // SPI CS line to backpack - negative logic, FALSE enables, TRUE disables
#define dataIn 11    // SPI Data input line to backpack

// Timings for the waveforms - these are tested and seem to work fine.  Change them at your own risk
#define CS_PAUSE 500    // 500 microseconds to settle CS
#define SLOW_DOWN 10    // 20 microseconds minimum for each clock/data access
#define SLOWER_DOWN 9

// Defines for animation
#define FRAME_TIME 175// milliseconds per frame
#define FRAMES 24  // Number of frames used for animations

// Monochrome sprite stuff
#define SPRITE_SIZE 8  // A sprite is stored in 8 bytes

// And the display colors for the RG display
#define black 0
#define red 1
#define green 2
#ifdef RG    // Colors if RG display is used, nearest color maps onto available colors
#define amber 3
#define blue 2
#define cyan 2
#define magenta 1
#define white 3
#endif
#ifdef RGB    // Colors if the RGB display is used, it's odd since blue ought to be 4 but isn't.
#define blue 3
#define amber 4
#define cyan 5
#define magenta 6
#define white 7
#endif

// Sprites are single-bit-depth entities
// Eventually you'll be able to mix them, I reckon
// For the moment you can just write them to the display
static byte test_sprite[FRAMES][SPRITE_SIZE] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x00, 0x80, 0x80, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x40, 0xA0, 0x80, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x40, 0xA0, 0x90, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x40, 0xA8, 0x90, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x44, 0xA8, 0x90, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x44, 0xAA, 0x90, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x44, 0xAA, 0x92, 0x40, 0x20, 0x10, 0x00,
  0x00, 0x44, 0xAA, 0x92, 0x44, 0x20, 0x10, 0x00,
  0x00, 0x44, 0xAA, 0x92, 0x44, 0x28, 0x10, 0x00,
  0x00, 0x44, 0xAA, 0x92, 0x44, 0x38, 0x10, 0x00,
  0x00, 0x44, 0xAA, 0x92, 0x7C, 0x38, 0x10, 0x00,
  0x00, 0x44, 0xAA, 0xFE, 0x7C, 0x38, 0x10, 0x00,
  0x00, 0x44, 0xEE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
  0x00, 0x44, 0xEE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
  0x00, 0x44, 0xEE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
  0x00, 0x44, 0xEE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
  0x00, 0x44, 0xEE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
  0x00, 0x44, 0xEE, 0xFE, 0x7C, 0x38, 0x10, 0x00,
   };


// And the size of the LED matrix
#define DISPLAY_SIZE 64    // 8 x 8 matrix of LEDs

// Sprite Animation System Tokens
#define END  0x00    // Single byte token
#define LOOP 0x01    // Double-byte token, followed by loop point
#define PLAY 0x02    // Double-byte token, followed by array index into
#define COLOR 0x03   // Double-byte token, followed by color
#define REPEAT 0x04  // Double-byte token, followed by number of repetitions

// Variable definitions
byte display[DISPLAY_SIZE];
byte sprite_buffer[DISPLAY_SIZE];    // Used to build sprite-based displays of multiple sprites



// function that puts a byte of data to the display serial interface
void putByte(byte data)
{
  byte i = 8;
  byte mask;
  while(i > 0) {
    mask = 0x01 << (i - 1);  // get bitmask
    digitalWrite(clock, LOW);   // tick
    if (data & mask){        // choose bit
      digitalWrite(dataIn, HIGH); // send data 1
    }
    else{
      digitalWrite(dataIn, LOW);  // send data 0
    }
    delayMicroseconds(SLOWER_DOWN);  // Keep the clock pulses even length
    digitalWrite(clock, HIGH);  // tock
    delayMicroseconds(SLOW_DOWN);  // Keep clock pulses even length
    --i;                     // move to lesser bit
  }
  digitalWrite(clock, LOW);
}

// This function writes the contents of a color screen buffer to the display
// Just give it a pointer to the array
void push_buffer(byte array[]) {

  // First, we assert the CS, to tell the display we're writing to it.
  // We clear the other lines at the same time
  digitalWrite(cs, LOW);
  delayMicroseconds(CS_PAUSE);      // Per the matrix backpack PDF

  // Now send the entire array out to the device
  for (char j = 0; j < DISPLAY_SIZE; j++) {
    putByte(array[j]);
  }

  // Now we de-assert CS, the display will not accept more data from us
  // We also clear the other lines
  digitalWrite(cs, HIGH);
  delayMicroseconds(CS_PAUSE);      // Per the matrix backpack PDF

}

/*void fill_display(byte color) {
  fill(display, color);
  push_buffer(display);
}*/

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

// Fills the display with all the same color
// Pass black as the color to clear the display
void fill(byte* array, byte color) {
  for (byte j=0; j < DISPLAY_SIZE; j++) {
    array[j] = color;
  }
}

// Write a monochrome sprite to the sprite buffer
// Pass blank = true to overwrite buffer, or false to add it into the buffer
void draw_sprite(byte* theSprite, byte theColor, boolean blank) {

  // First we translate the sprite into the display buffer
  byte ptr = 0;
  for (byte j=0; j < SPRITE_SIZE; j++) {
    byte val = theSprite[j];
    byte i = 8;
    byte mask;
    while(i > 0) {
      mask = 0x01 << (i - 1);  // get bitmask
      if (val & mask){        // choose bit
        sprite_buffer[ptr] = theColor; // send 1
      }
      else{
        if (blank) sprite_buffer[ptr] = black;  // send 0
      }
      --i;                     // move to lesser bit
      ++ptr;                    //  And to next position in array
    }
  }
}

// Draw a sprite to the buffer and write it out to the display
/*void write_sprite(byte* theSprite, byte theColor) {
  draw_sprite(theSprite, theColor, true);
  push_buffer(sprite_buffer);
}*/

// This adds a sprite to the sprite buffer
// It will overwrite the sprite if overwrite is TRUE, otherwise not
/*void mux_sprite(byte* theSprite, byte color, boolean overwrite) {
 // First we translate the sprite into the display buffer
 byte ptr = 0;
 for (byte j=0; j < SPRITE_SIZE; j++) {
 byte val = theSprite[j];
 byte i = 8;
 byte mask;
 while(i > 0) {
 if ((sprite_buffer[ptr] != black) && (overwrite == false)) continue;    // Skip writing if there's data in there already
 mask = 0x01 << (i - 1);  // get bitmask
 if (val & mask){        // choose bit
 sprite_buffer[ptr] = theColor; // send 1
 }
 else{
 sprite_buffer[ptr] = black;  // send 0
 }
 --i;                     // move to lesser bit
 ++ptr;                    //  And to next position in array
 }
 }
 }*/

void white_noise(byte* array) {
  for (byte j=0; j < DISPLAY_SIZE; j++) {
    array[j] = rand() & 7;
  }
}

int ryanPin = 2;
int lusi;
int ledPin = 13;
void setup() {

  //Serial.begin(19200);

  // Setup the proper output pins
  pinMode(dataIn, OUTPUT);
  pinMode(clock, OUTPUT);
  pinMode(cs, OUTPUT);
  pinMode(ryanPin, INPUT);
  pinMode(ledPin, OUTPUT);
  
  srand(0x1234);    // Seed with the number of milliseconds since startup

  // And reset the display to a known startup pattern
  //fill_display(black);
}

#define SWITCH_LIST 3   // Number of elements we switch between



void loop() {
  lusi = digitalRead(ryanPin);
  if (lusi == LOW){
    digitalWrite(ledPin, HIGH);
      
  byte q;
  // We'll do one thing or another, based on a random value
  int switchVal = rand() % SWITCH_LIST;

  switch (switchVal) {

  
  case 1:
    // OK let's try to animate a burning man!
    for (q = 0; q < FRAMES; q++) {
      draw_sprite(test_sprite[q], red, true);
      push_buffer(sprite_buffer);
      delay(FRAME_TIME);
    }
    
    break;

  
  }

}
if (lusi == HIGH); {
  digitalWrite(ledPin, LOW);
  
   byte q;
  // We'll do one thing or another, based on a random value
  int switchVal = rand() % SWITCH_LIST;

  switch (switchVal) {

  
  case 1:
    // OK let's try to animate a burning man!
    for (q = 0; q <FRAMES; q--) {
      draw_sprite(test_sprite[q], red, true);
      push_buffer(sprite_buffer);
      delay(FRAME_TIME);
    }
    
    break;

  
  }

}
}
Logged

Chicago &#124; IL
Offline Offline
Newbie
*
Karma: 0
Posts: 23
Arduino Nerd
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Cool - I want to add some button controlls on the LED Text matrix that I did. I also took on the same Heart Animation thing, kinda used code I created in Flash for something similar and threw it in here. This just moves though animation frames in arrays. The only problem is that you can only hold so much data in the Arduino memory. It wouild die after about 9 or 10 frames. What also works to prevent that is using a temp Array as a buffer and just pass vaules based on a switch statment - so your never really holding all the data at once, just what you want to display....

My Heart Animation Code...
Code:

#define CHIPSELECT 10//Chip Select Line
#define SPICLOCK  13//Master Clock
#define DATAOUT 11//DataOut to DataIn on Backpack
#define DATAIN 12//DataIn from DataOut on Backpack

//simple array for data frames - you can use 0-3 for the color settings on the RG display or 0-7 for the RGB Matrixs//
int databuffer[4][8][8] ={
  
 {{0,0,1,1,0,1,1,0},
  {0,1,0,0,1,0,0,1},
  {0,1,0,0,0,0,0,1},
  {0,1,0,0,0,0,0,1},
  {0,0,1,0,0,0,1,0},
  {0,0,0,1,0,1,0,0},
  {0,0,0,0,1,0,0,0},
  {0,0,0,0,0,0,0,0}},
  
 {{0,0,0,0,0,0,0,0},
  {0,0,0,1,0,1,0,0},
  {0,0,1,0,1,0,1,0},
  {0,0,1,0,0,0,1,0},
  {0,0,0,1,0,1,0,0},
  {0,0,0,0,1,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},
  {0,0,0,1,0,1,0,0},
  {0,0,0,1,1,1,0,0},
  {0,0,0,0,1,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},
  {0,0,0,1,0,1,0,0},
  {0,0,1,0,1,0,1,0},
  {0,0,1,0,0,0,1,0},
  {0,0,0,1,0,1,0,0},
  {0,0,0,0,1,0,0,0},
  {0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0}}

  } ;

int z=0;

// SPI data load / transfer function - thanks Heather Dewey-Hagborg //
char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
}

void clearDisplay() {
   for (int i=0;i<8;i++) for (int j=0;j<8;j++)
    { spi_transfer( 0 ); }
    delay(50);  
}

void setup()
{
  byte clr;
  pinMode(DATAOUT,OUTPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(CHIPSELECT,OUTPUT);
  digitalWrite(CHIPSELECT,HIGH); //disable device

  SPCR = B01010001;             //SPI Registers
  SPSR = SPSR & B11111110;      //make sure the speed is 125KHz

  clr=SPSR;
  clr=SPDR;
  delay(10);
  clearDisplay();
}

void loop()            
{
    int z=0;
    //loop though frames #4 //
    for (int z=0;z<4;z++) {
    delay(100);                    
    digitalWrite(CHIPSELECT,LOW); // enable the ChipSelect
    delayMicroseconds(500);

       for (int i=0;i<8;i++) {
       for (int j=0;j<8;j++) {
       spi_transfer( databuffer[z][i][j] );        
       }
       }

    digitalWrite(CHIPSELECT,HIGH); // disable the ChipSelect
    delayMicroseconds(500);
    
    }
      
    delay(100);
}


I'll try to clean up the Text Matrix code I have too - that is set to use two LED Matrix's so its easy to modify for more or less...

Here is the youtube link tot he dual matrix scroller!


smiley
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 60
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for posting that info. I now have a working RGB Matrix with Backpack! You're right about running out of memory after about 8 frames. Have you come up with code that would solve the problem yet?

Also, please post your code for the two Led Matrix's?

Thanks in advance.
Logged

Pages: [1]   Go Up
Jump to: