Addressable LED's scrolling Letters in a 7x7 matrix
Moderators: adafruit_support_bill, adafruit

Addressable LED's scrolling Letters in a 7x7 matrix

by exinterfect on Mon Sep 19, 2011 11:54 am

Hi All,


First I'll apologize for the initial post with this request. I have been searching and could not find much on this. I need to take a 7x7 matrix of addressable LED's Like seen here:
http://www.adafruit.com/products/322
and have a message scroll across.

These are being run by an Arduino UNO and the code I have is modified from the BlipTronics libraries (which are really broken). At this time it reads a 7 band spectrum which dances to music. We also put in an "idle Screen" for when no sound is detected which runs through a series of patterns.

What I would like to achieve is to put in a method to scroll a message every 5 minutes or so nregardless of its current state, idle or reading music.

I will gladly go through and post the sketch here. I did not write it first off. A friend of mine did or rather fixed what was wrong with Bliptronics code. His birthday is this weekend and I want to toss in a message as a surprise. Hence why I didn't ask him..... If I could get a simple example of how to do this I can go from there. Code of the top of my head is not my forte.

Any help is appreciated.

Here is a simple pic of how the matrix is set up.
Image
exinterfect
 
Posts: 5
Joined: Mon Sep 19, 2011 9:31 am

Re: Addressable LED's scrolling Letters in a 7x7 matrix

by exinterfect on Mon Sep 19, 2011 11:55 am

And here is the sketch:

Code: Select all | TOGGLE FULL SIZE
#include <LEDPixels.h>

//Example to control RGB LED Modules with Spectrum Analyzer
//Bliptronics.com
//Ben Moyes 2010
//Use this as you wish, but please give credit, or at least buy some of my LEDs!
//


LEDPixels LP;  //Our LEDPixels library - see http://www.bliptronics.com/ArduinoCode/LEDPixels.zip

//For spectrum analyzer shield, these three pins are used.
//You can move pinds 4 and 5, but you must cut the trace on the shield and re-route from the 2 jumpers.
const int spectrumReset  = 5;
const int spectrumStrobe = 4;
const int spectrumAnalog = 0;  //0 for left channel, 1 for right.

const int ledClock = 12;
const int ledData  = 11;

//This holds the 15 bit RGB values for each LED.
//You'll need one for each LED, we're using 25 LEDs here.
//Note you've only got limited memory, so you can only control
//Several hundred LEDs on a normal arduino. Double that on a Duemilanove.

const int ledCount = 49;
int MyDisplay[ledCount];

byte bgColor[] = {0, 0, 31};

const int gridWidth = 7;
const int gridHeight = 7;

const int updateDelay = 30;

// Spectrum analyzer read values will be kept here.
int Spectrum[7];

void setup() {
    byte Counter;

    //Initialize the LEDPixels library.
    //            refresh delay, address of data, number of LEDs, clock pin, data pin.
    LP.initialize( 25, &MyDisplay[0], 49, ledClock, ledData );

    // Setup the grid in the LEDPixels library to the setFastxxx calls work
    LP.gridWidth = gridWidth;
    LP.gridHeight = gridHeight;

    //Setup pins to drive the spectrum analyzer.
    pinMode(spectrumReset, OUTPUT);
    pinMode(spectrumStrobe, OUTPUT);

    //Init spectrum analyzer
    digitalWrite(spectrumStrobe,LOW);
    delay(1);
    digitalWrite(spectrumReset,HIGH);
    delay(1);
    digitalWrite(spectrumStrobe,HIGH);
    delay(1);
    digitalWrite(spectrumStrobe,LOW);
    delay(1);
    digitalWrite(spectrumReset,LOW);
    delay(5);
    // Reading the analyzer now will read the lowest frequency.

    // Turn all LEDs off.
    LP.setRange( 0, ledCount - 1, LP.color(0, 0, 0));
    LP.show();                             //Write out display to LEDs

    Serial.begin(9600);
}

void loop() {

    //int Counter, Counter2, Counter3;

    //LP.setRange(0,48,LP.color(5,0,0));
    //LP.show();

    showSpectrum();
    delay(updateDelay);  //We wait here for a little while until all the values to the LEDs are written out.
    //This is being done in the background by an interrupt.
}

// Read 7 band equalizer.
void readSpectrum()
{
    // Band 0 = Lowest Frequencies.
    for(byte Band=0;Band < 7; Band++)
    {
        Spectrum[Band] = (analogRead(spectrumAnalog) + analogRead(spectrumAnalog) ) >> 1; //Read twice and take the average by dividing by 2
        digitalWrite(spectrumStrobe,HIGH);
        digitalWrite(spectrumStrobe,LOW);
    }
}

void showSpectrum()
{
    //Not I don't use any floating point numbers - all integers to keep it zippy.
    readSpectrum();
   
    // Some storage for what we are doing
    static unsigned int  Divisor = 80, ChangeTimer = 0, PullTimer = 0;
    static boolean Idle = false;
   
    byte Band, BarSize, MaxLevel;
    unsigned int works, Remainder;

    MaxLevel = 0;
    Idle = Divisor < 20;

    for(Band=0;Band<7;Band++)//We only graph the lowest 5 bands here, there is 2 more unused!
    {
        // We always need to determine the max-level
        works = Spectrum[Band]/Divisor;
        if(works > MaxLevel) {
            MaxLevel = works;
        }

        if(!Idle) {
            for(BarSize = 1; BarSize <= 7; BarSize++) 
            {
                if(works > BarSize) {
                    LP.setLEDFast(LP.Translate(Band,BarSize-1), BarSize*6, 31-(BarSize*7), 0);
                }
                else if (works == BarSize) {
                    LP.setLEDFast(LP.Translate(Band,BarSize-1), BarSize*7, 0, 0); //Was remainder
                }
                else {
                    // Background color
                    LP.setLEDFast(LP.Translate(Band,BarSize-1), bgColor[0], bgColor[1], bgColor[2]);
                }
            }
        }
    }

    if(Idle) {
        drawIdle();
    }

    LP.show();

    // Adjust the Divisor if levels are too high/low.
    // If  below 4 happens 20 times, then very slowly turn up.
    if (MaxLevel >= 7)
    {
        Divisor=Divisor+1;
        ChangeTimer=0;
        PullTimer=0;
        Serial.print("Adjusting Volume: ");
        Serial.println(Divisor, DEC);
    }
    else if(MaxLevel < 6)
    {
        if(Divisor > 0)
            if(ChangeTimer++ > 10 || PullTimer > 10)
            {
                Divisor--;
                ChangeTimer = 0;
                PullTimer++;

                // If we have been increasing the gain for a bit,
                // speed it up a little
                if(PullTimer > 15) {
                    Divisor--;
                }
               
                Serial.print("Adjusting Volume: ");
                Serial.println(Divisor, DEC);
            }
    }
    else
    {
        ChangeTimer=0;
    }
}

void drawIdle() {
    static unsigned int IdleTimer = 0, IdleDisplay = 3;
   
    IdleTimer++;
    if(IdleTimer > 250) {
        IdleDisplay++;
        IdleTimer = 0;
    }
   
    switch(IdleDisplay % 6) {
        case 0:
            drawBouncyBox();
            break;
        case 1:
            drawRandom();
            break;
        case 2:
            drawMovingLine();
            break;
        case 3:
            drawRainbowBox();
            break;
        case 4:
            drawRainbow();
            break;
        case 5:
            drawRainbowStraight();
            break;
    }
}

void drawRandom() {
    for(unsigned int i = 0; i < ledCount; ++i) {
        LP.setLEDFast(i, random(0, 31), random(0, 31), random(0, 31));
    }
}

void drawMovingLine() {
    static int Row = 0, Delta = 1;
   
    for(unsigned int i = 0; i < gridWidth; ++i) {
        if(i == Row) {
            LP.line(i, 0, i, gridHeight - 1, LP.color(0, 0, 31));
        } else {
            LP.line(i, 0, i, gridHeight - 1, LP.color(31, 0, 0));
        }
    }
   
    Row += Delta;
    if(Row == gridWidth - 1 || Row == 0) {
        Delta *= -1;
    }
}

void drawBouncyBox() {
    static int Row = 0, Delta = 1;

    for(byte x = 0; x <= 4; ++x) {
        if(x == Row) {
            LP.box(x, x, 6 - x, 6 - x, LP.color(0, 0, 31));
        }
        else {
            LP.box(x, x, 6 - x, 6 - x, LP.color(31, 0, 0));
        }
    }

    Row += Delta;
    if(Row == 4 || Row == 0) {
        Delta *= -1;
    }
}

void drawRainbowStraight() {
    static int base = 0;
    static float freq = .1;

    byte rr, gg, bb;
    for(byte i = 0; i < ledCount; ++i) {
        rr = sin(freq * (i + base)) * 15 + 15;
        gg = sin(freq * (i + base) + 2) * 15 + 15;
        bb = sin(freq * (i + base) + 4) * 15 + 15;
        LP.setLEDFast(i, rr, gg, bb);
    }
   
    base += 2;
}

void drawRainbowBox() {
    static float freq = .3;
    static int base = 0;

    byte rr, gg, bb;
    for(byte x = 0; x <= 4; ++x) {
        rr = sin(freq * (base + x)) * 15 + 15;
        gg = sin(freq * (base + x) + 2) * 15 + 15;
        bb = sin(freq * (base + x) + 4) * 15 + 15;
        LP.box(x, x, 6 - x, 6 - x, LP.color(rr, gg, bb));
    }
    ++base;
}

void drawRainbow() {
    static int base = 0;
   
    float freq = .1;
    byte rr, gg, bb;
    for(byte y = gridHeight; y > 0; --y) {
        for(byte x = 0; x < gridWidth; ++x) {
            rr = sin(freq * (base + x)) * 15 + 15;
            gg = sin(freq * (base + x) + 2) * 15 + 15;
            bb = sin(freq * (base + x) + 4) * 15 + 15;
            LP.setLEDFast(LP.Translate(x, y), rr, gg, bb);
        }
        freq += .1;
    }
    ++base;
}
exinterfect
 
Posts: 5
Joined: Mon Sep 19, 2011 9:31 am

Re: Addressable LED's scrolling Letters in a 7x7 matrix

by exinterfect on Mon Sep 19, 2011 11:57 am

exinterfect
 
Posts: 5
Joined: Mon Sep 19, 2011 9:31 am

Re: Addressable LED's scrolling Letters in a 7x7 matrix

by dfigravity on Thu Apr 26, 2012 6:30 pm

Did you end up having any luck with your scrolling message code? I currently have a similiar setup as you, except mine is only a 5x5 matrix. The code that you guys worked out is great, especially the byte bgColor[] line...I had been trying to find a way to change the background. I have also been trying to figure out how to change the colors of the LED's in each band...instead of red's at the bottoms and green's at the top, it might be cool to have purple, pink and white (bottom, middle, top respectively)...maybe even set up several EQ color schemes that you could change with a button. Anyway...I was just curious if you had made any more progress or had more insight into this library. Thanks and great work!
dfigravity
 
Posts: 1
Joined: Thu Apr 26, 2012 6:24 pm

Re: Addressable LED's scrolling Letters in a 7x7 matrix

by thejamie on Wed May 08, 2013 1:01 am

Hey folks.

Sorry to knock the dust off of this thread. I was handed a string of 40 of the LPD6803 20mm pixels and a Bliptronics Stereo Audio Analyzer v1.1 shield (uses the MSGEQ7) and would like to get something similar to this dancing EQ up and running. I would be really grateful for any help. I'm running an Uno. I have almost the exact same matrix set up as at pictured at the top, except it is only 5px high by 7.

I can get Adafruit's lpd6803 library and its strandtest example to run without any problems, so I know the lights & hardware are working. But this 7x7 matrix project is so close to what I would like my lights to do, I figured I'd try to make this sketch and the LEDPixels library work.

The first error I got kicked was regarding a missing Wprogram.h file or directory, which is apparently because this sketch is pre-Arduino 1.0 and was solved by dropping this #ifdef from PaintYourDragon into the LEDPixel header. https://github.com/adafruit/DHT-sensor-library/issues/1

But now the error I'm getting is this:
Code: Select all | TOGGLE FULL SIZE
sketch_may07a.ino: In function 'void setup()':
sketch_may07a:48: error: 'class LEDPixels' has no member named 'gridWidth'
sketch_may07a:49: error: 'class LEDPixels' has no member named 'gridHeight'


The sketch I am running is the exact same as above with the exception that I have changed the ledCount to 35 and the gridHeight to 5

Code: Select all | TOGGLE FULL SIZE
#include <LEDPixels.h>

//Example to control RGB LED Modules with Spectrum Analyzer
//Bliptronics.com
//Ben Moyes 2010
//Use this as you wish, but please give credit, or at least buy some of my LEDs!
//


LEDPixels LP;  //Our LEDPixels library - see http://www.bliptronics.com/ArduinoCode/LEDPixels.zip

//For spectrum analyzer shield, these three pins are used.
//You can move pinds 4 and 5, but you must cut the trace on the shield and re-route from the 2 jumpers.
const int spectrumReset  = 5;
const int spectrumStrobe = 4;
const int spectrumAnalog = 0;  //0 for left channel, 1 for right.

const int ledClock = 12;
const int ledData  = 11;

//This holds the 15 bit RGB values for each LED.
//You'll need one for each LED, we're using 25 LEDs here.
//Note you've only got limited memory, so you can only control
//Several hundred LEDs on a normal arduino. Double that on a Duemilanove.

const int ledCount = 35;
int MyDisplay[ledCount];

byte bgColor[] = {
  0, 0, 31};

const int gridWidth = 7;
const int gridHeight = 5;

const int updateDelay = 30;

// Spectrum analyzer read values will be kept here.
int Spectrum[7];

void setup() {
  byte Counter;

  //Initialize the LEDPixels library.
  //            refresh delay, address of data, number of LEDs, clock pin, data pin.
  LP.initialize( 25, &MyDisplay[0], 35, ledClock, ledData );

  // Setup the grid in the LEDPixels library to the setFastxxx calls work
  LP.gridWidth = gridWidth;
  LP.gridHeight = gridHeight;

  //Setup pins to drive the spectrum analyzer.
  pinMode(spectrumReset, OUTPUT);
  pinMode(spectrumStrobe, OUTPUT);

  //Init spectrum analyzer
  digitalWrite(spectrumStrobe,LOW);
  delay(1);
  digitalWrite(spectrumReset,HIGH);
  delay(1);
  digitalWrite(spectrumStrobe,HIGH);
  delay(1);
  digitalWrite(spectrumStrobe,LOW);
  delay(1);
  digitalWrite(spectrumReset,LOW);
  delay(5);
  // Reading the analyzer now will read the lowest frequency.

  // Turn all LEDs off.
  LP.setRange( 0, ledCount - 1, LP.color(0, 0, 0));
  LP.show();                             //Write out display to LEDs

  Serial.begin(9600);
}

void loop() {

  //int Counter, Counter2, Counter3;

  //LP.setRange(0,48,LP.color(5,0,0));
  //LP.show();

  showSpectrum();
  delay(updateDelay);  //We wait here for a little while until all the values to the LEDs are written out.
  //This is being done in the background by an interrupt.
}

// Read 7 band equalizer.
void readSpectrum()
{
  // Band 0 = Lowest Frequencies.
  for(byte Band=0;Band < 7; Band++)
  {
    Spectrum[Band] = (analogRead(spectrumAnalog) + analogRead(spectrumAnalog) ) >> 1; //Read twice and take the average by dividing by 2
    digitalWrite(spectrumStrobe,HIGH);
    digitalWrite(spectrumStrobe,LOW);
  }
}

void showSpectrum()
{
  //Not I don't use any floating point numbers - all integers to keep it zippy.
  readSpectrum();

  // Some storage for what we are doing
  static unsigned int  Divisor = 80, ChangeTimer = 0, PullTimer = 0;
  static boolean Idle = false;

  byte Band, BarSize, MaxLevel;
  unsigned int works, Remainder;

  MaxLevel = 0;
  Idle = Divisor < 20;

  for(Band=0;Band<7;Band++)//We only graph the lowest 5 bands here, there is 2 more unused!
  {
    // We always need to determine the max-level
    works = Spectrum[Band]/Divisor;
    if(works > MaxLevel) {
      MaxLevel = works;
    }

    if(!Idle) {
      for(BarSize = 1; BarSize <= 7; BarSize++) 
      {
        if(works > BarSize) {
          LP.setLEDFast(LP.Translate(Band,BarSize-1), BarSize*6, 31-(BarSize*7), 0);
        }
        else if (works == BarSize) {
          LP.setLEDFast(LP.Translate(Band,BarSize-1), BarSize*7, 0, 0); //Was remainder
        }
        else {
          // Background color
          LP.setLEDFast(LP.Translate(Band,BarSize-1), bgColor[0], bgColor[1], bgColor[2]);
        }
      }
    }
  }

  if(Idle) {
    drawIdle();
  }

  LP.show();

  // Adjust the Divisor if levels are too high/low.
  // If  below 4 happens 20 times, then very slowly turn up.
  if (MaxLevel >= 7)
  {
    Divisor=Divisor+1;
    ChangeTimer=0;
    PullTimer=0;
    Serial.print("Adjusting Volume: ");
    Serial.println(Divisor, DEC);
  }
  else if(MaxLevel < 6)
  {
    if(Divisor > 0)
      if(ChangeTimer++ > 10 || PullTimer > 10)
      {
        Divisor--;
        ChangeTimer = 0;
        PullTimer++;

        // If we have been increasing the gain for a bit,
        // speed it up a little
        if(PullTimer > 15) {
          Divisor--;
        }

        Serial.print("Adjusting Volume: ");
        Serial.println(Divisor, DEC);
      }
  }
  else
  {
    ChangeTimer=0;
  }
}

void drawIdle() {
  static unsigned int IdleTimer = 0, IdleDisplay = 3;

  IdleTimer++;
  if(IdleTimer > 250) {
    IdleDisplay++;
    IdleTimer = 0;
  }

  switch(IdleDisplay % 6) {
  case 0:
    drawBouncyBox();
    break;
  case 1:
    drawRandom();
    break;
  case 2:
    drawMovingLine();
    break;
  case 3:
    drawRainbowBox();
    break;
  case 4:
    drawRainbow();
    break;
  case 5:
    drawRainbowStraight();
    break;
  }
}

void drawRandom() {
  for(unsigned int i = 0; i < ledCount; ++i) {
    LP.setLEDFast(i, random(0, 31), random(0, 31), random(0, 31));
  }
}

void drawMovingLine() {
  static int Row = 0, Delta = 1;

  for(unsigned int i = 0; i < gridWidth; ++i) {
    if(i == Row) {
      LP.line(i, 0, i, gridHeight - 1, LP.color(0, 0, 31));
    }
    else {
      LP.line(i, 0, i, gridHeight - 1, LP.color(31, 0, 0));
    }
  }

  Row += Delta;
  if(Row == gridWidth - 1 || Row == 0) {
    Delta *= -1;
  }
}

void drawBouncyBox() {
  static int Row = 0, Delta = 1;

  for(byte x = 0; x <= 4; ++x) {
    if(x == Row) {
      LP.box(x, x, 6 - x, 6 - x, LP.color(0, 0, 31));
    }
    else {
      LP.box(x, x, 6 - x, 6 - x, LP.color(31, 0, 0));
    }
  }

  Row += Delta;
  if(Row == 4 || Row == 0) {
    Delta *= -1;
  }
}

void drawRainbowStraight() {
  static int base = 0;
  static float freq = .1;

  byte rr, gg, bb;
  for(byte i = 0; i < ledCount; ++i) {
    rr = sin(freq * (i + base)) * 15 + 15;
    gg = sin(freq * (i + base) + 2) * 15 + 15;
    bb = sin(freq * (i + base) + 4) * 15 + 15;
    LP.setLEDFast(i, rr, gg, bb);
  }

  base += 2;
}

void drawRainbowBox() {
  static float freq = .3;
  static int base = 0;

  byte rr, gg, bb;
  for(byte x = 0; x <= 4; ++x) {
    rr = sin(freq * (base + x)) * 15 + 15;
    gg = sin(freq * (base + x) + 2) * 15 + 15;
    bb = sin(freq * (base + x) + 4) * 15 + 15;
    LP.box(x, x, 6 - x, 6 - x, LP.color(rr, gg, bb));
  }
  ++base;
}

void drawRainbow() {
  static int base = 0;

  float freq = .1;
  byte rr, gg, bb;
  for(byte y = gridHeight; y > 0; --y) {
    for(byte x = 0; x < gridWidth; ++x) {
      rr = sin(freq * (base + x)) * 15 + 15;
      gg = sin(freq * (base + x) + 2) * 15 + 15;
      bb = sin(freq * (base + x) + 4) * 15 + 15;
      LP.setLEDFast(LP.Translate(x, y), rr, gg, bb);
    }
    freq += .1;
  }
  ++base;
}


Please let me know if there is some update or resource somewhere that I've managed to miss that answers my question. My apologies if that is the case. Thanks!
thejamie
 
Posts: 2
Joined: Wed Jan 13, 2010 1:19 pm

Re: Addressable LED's scrolling Letters in a 7x7 matrix

by adafruit_support_rick on Wed May 08, 2013 10:42 am

Well, the error is pretty self-explanatory. The bliptronics LEDPixel library doesn't define any members named gridWidth or gridHeight. Either your sketch is written for an older version of the library, or you've got an obsolete version of the library installed.

Does bliptronics have any sort of customer support? You really ought to ask them first. If they're of no help, come back and we'll see what we can figure out.

adafruit_support_rick
 
Posts: 13772
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY