Help with homemade 4x4 led matrix

OK, first off, my knowledge of the arduino is fairly basic - i've experimented successfully with lots of simple things like leds and ldrs and pots and switches and solenoids and relays and transistors and have a reasonable understanding of circuits from high school physics, but i've just left school so that's where my knowledge ends.

The only programming knowledge I have is stuff i've taught myself, which is the main reason my projects have all been so basic.

I'm trying to control an LED matrix with the aim of eventually making a music visualizer. I made my own 4x4 on a breadboard, but I can only get a whole row or column to light up. The problem is, I don't really understand arrays well enough to use them, so I thought I'd experiment by naming the 8 pins i was using row1-4 and column1-4, and then writing them LOW or HIGH. However, all I can achieve through this (and i've tried A LOT of variations) is lighting up an entire row or column.

I adapted this: arduino(dot)cc/playground/Main/DirectDriveLEDMatrix

but the circuit diagram confused me. I assumed that the anodes of a row and the cathodes of a column would all be connected together(or vice versa), and then the row or column would be connected to a pin. This is how I wired my breadboard, but in the circuit diagram it looks like row is connected to every column, and every column to every row.

What I'm asking is, is it my matrix or my programming (or both) that are flawed?

Your description is a bit confusing can you post a schematic of what you think you are making and also the code so we can assess it.
In the mean time look at the matrix schematic here:-
http://www.thebox.myzen.co.uk/Hardware/Econo_Monome.html
For an idea of how you need to wire one up.
The trick is to only output one row at a time as high (anode) and put the cathodes low for the LEDs you want to light up on that row.

That schematic definitely helps: all the other ones I have seen just showed a completely joined up grid, while that one clearly shows that rows and columns are not connected to each other.

Ok, I got it working(sort of). I switched my board round so the rows were anodes and now I can get one LED to light up.

Here's the code I'm using:

int column1 = 9;
int column2 = 10;
int column3 = 11;
int column4 = 12;
int row1 = 2;
int row2 = 3;
int row3 = 4;
int row4 = 5;
 
 void resetLed(){
  digitalWrite(row1, LOW);
  digitalWrite(row2, LOW);
  digitalWrite(row3, LOW);
  digitalWrite(row4, LOW);
  digitalWrite(column1, HIGH);
  digitalWrite(column2, HIGH);
  digitalWrite(column3, HIGH);
  digitalWrite(column4, HIGH);
    }
  
void setup()
{
  pinMode(column1, OUTPUT);
  pinMode(column2, OUTPUT);
  pinMode(column3, OUTPUT);
  pinMode(column4, OUTPUT);
  
  pinMode(row1, OUTPUT);
  pinMode(row2, OUTPUT);
  pinMode(row3, OUTPUT);
  pinMode(row4, OUTPUT);
  
 
}

void loop(){
  resetLed();
  digitalWrite(row4, HIGH);
  digitalWrite(column4, LOW);
  delay(1000);

  
  
}

Any combination of row and column works fine, but if i try for example:

  resetLed();
  digitalWrite(row4, HIGH);
  digitalWrite(column3, LOW);
  digitalWrite(column4, LOW);
  delay(1000);

then I only get one LED lighting up.

then I only get one LED lighting up.

Which LED is it? the one on column 3 or 4?

Have you made all the pins outputs in the setup part of the code?

This may or may not be helpful, but are all of your LEDs the same? If I'm understanding this correctly, when multiple LEDs are turned on they are connected in parallel.. If two LEDs are connected in parallel and aren't identical, both may not illuminate. This is because of varying forward voltages. Aside from that, I don't know what the problem could be.

Matrices can be are very confusing!! :o

Have you made all the pins outputs in the setup part of the code?

I don't want to seem like a jerk, but it's right there in the code he posted. :wink:

Haha this is quite embarrasing, while trying to find a good example of what wasn't working I realised what I was doing wrong and I think i've got everything working fine? I wasn't resetting the LEDs at the end of the loop so when i tried to scroll them they flickered without coming on, but I seem to have got them working perfectly.

Thanks for your help, you pointed me in the right direction very effectively.

PS can anyone link me to a good resource for learning about how to use arrays - either specifically with matrices or in general? I understand enough about them to see that manually writing the columns and rows high and low is very inefficient, but when I look at the 8x8 examples on the site it's really daunting because there's alot going on I can't follow.

OH and another question - is it possible to make like an X shape? I can make the rows or columns scroll but if i wanted a diagonal line with coordinates (1,4), (2,3), (3,2), (4,1), how could I do that without turning on all rows and columns?

turn on individual leds one at a time, do it fast enough your eye wont notice

Congrats on solving the problem on your own! That is the most rewarding thing in electronics/programming, IMHO.

how could I do that without turning on all rows and columns?

It's called multiplexing. OOOoooOoOOoo fancy word! Just means you have to operate only sections of the matrix at a time. In your case, I think, you would want to split the 4x4 into 4 2x2 matrices and turn them on and off very rapidly. There is an IC that is great for this(up to 8x8 matrix or up to 8digits of seven segment display). It is called MAX7218. It is only for either CC or CA. I can't remember. The caveat here, is the price. Typically about $9 for the component. There is a library for arduino that utilizes this chip.

In regards to arrays.. Try the arduino site. The information found here will obviously be most compatible with the arduino IDE(or whatever)..
http://www.arduino.cc/en/Reference/Array
Having learned programming for the first time with the arduino(mostly from reading through /reference) I can appreciate how daunting it can be. If you have any specific examples of things you'd like to accomplish with your code, I'd be glad to try and explain how to do it with arrays.

There is an IC that is great for this(up to 8x8 matrix or up to 8digits of seven segment display). It is called MAX7218.

Ah I see, I've seen that on a lot of the pages I was looking at to learn about matrices, but had no idea what it did, so I'd been avoiding it. it still looks a bit beyond my programming capability to be honest : /

wow thanks, i hadn't thought to look for it here funnily enough, that definitely seems like the best place to start.

I wish I had some relevant questions to ask for help with, but I'm sort of at a stage where I don't even know what I need it for. I thought all I needed to control a matrix was an understanding of arrays but if I need an IC to do anything really interesting then understanding that is probably more inportant.

well you dont NEED that IC, you really dont need any IC, I think its easier from the software side with extra hardware (for instance if I was using a shift register on a 4x4 matrix, its alot easier to "shiftOut()" a string of data than dealing with 16 individual pins)

I would wrap up what you have now, experiment with software to see what you can really do with it, and then you will be more knoledgeable about where you want to take it next

you may have all your fun and see something that interest's you even more, and try to lean that

as long as your learning and having fun doing it is all that matters

Osgeld is absolutely right... You don't need that IC. It just simplifies the programming significantly and frees up your precious pins. It would be good for you to learn how to do it in software, but definitely not starting out too big. Your 4x4 matrix should be manageable to right code for.

Arrays are pretty nifty. They can really make your code much shorter. I don't know if they are more efficient than how you would normally do things, though(in terms of speed/memory).

Actually P_Wood, there is something I'm quite intereseted in - just to understand how it works - with regard to arrays(i think).

I've been using this example lots to help me:
http://www.arduino.cc/playground/Main/DirectDriveLEDMatrix

and I managed to change my code to incorporate an array instead of long lists of digitalWrite() etc.

what I'm interested in though is where in that code letters are defined with ones and zeroes(eg #define H{}) - but i can't quite follow how it's done. Does it need a library to be included or is it happening without?

Here's my setup:

int pins[10] = {2,3,4,5,8,9,10,11,12,13};
int cols[6] = {pins[4], pins[5], pins[6], pins[7], pins[8], pins[9]};
int rows[4] = {pins[0], pins[1], pins[2], pins[3]};
int count = 0;

void resetLed(){
//sets up the columns

  for (int i = 0; i <= 5; i++) {
    digitalWrite(cols[i], HIGH);
  }
//sets up the rows
  for (int i = 0; i <= 3; i++) {
    digitalWrite(rows[i], LOW);
    
  }
}


    
    void heart(){
      resetLed();
      for(count=0;count<150;count++){
      digitalWrite(rows[0], HIGH);
      digitalWrite(cols[1], LOW);
      digitalWrite(cols[3], LOW);
      delay(0.1);
      resetLed();
      digitalWrite(rows[1], HIGH);
      digitalWrite(cols[0], LOW);
      digitalWrite(cols[2], LOW);
      digitalWrite(cols[4], LOW);
      delay(0.1);
      resetLed();
      digitalWrite(rows[2], HIGH);
      digitalWrite(cols[1], LOW);
      digitalWrite(cols[3], LOW);
      delay(0.1);    
      resetLed();
      digitalWrite(rows[3], HIGH);
      digitalWrite(cols[2], LOW);
      delay(0.1);
      resetLed();
      }
      count == 0;
    }   
    

void setup(){
//sets up the pins as outputs
  for (int i = 0; i <=11 ; i++) {
    pinMode(pins[i], OUTPUT);
  }
  

}

void loop(){


  resetLed();

  heart();
  resetLed();
  delay(50);

  }

Assuming that I understand it completely, I think you need to be careful when using "#define". For example: If you did "#define a b", you would make "a" contain the value "b" anywhere you see the letter "a" in the sketch. So you should be careful not to use a value that could show up unintentionally in the sketch. Straight from the arduino reference page:

In general, the const keyword is preferred for defining constants and should be used instead of #define.

Any way. When looking at this code you should know that the keywords "HIGH" and "LOW" are of type int and therefor can be represented by a 1 or a 0.

#define H { \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}  \
}

Here "H" is defined as an 8x8 array of 1's and 0's. You should also notice that the formatting is to make it look like the LED matrix.

You can see that the way the author set it up visualizes the state of the LEDs for ease of programming. I'd recommend following that idea.

As for the code I posted, I should say that you cannot address that array directly. You need to do it the way the author did:

const int numPatterns = 6;

byte patterns[numPatterns][8][8] = {
  H,E,L,L,O,SPACE           //here he puts the defined 'images' into a: numPatterns x 8 x 8 array
};                     //or I could say there are 6 patterns, each 8 by 8 in size


for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[i][j] = patterns[pattern][i][j];
    }
  }

For more details on that, you'd need someone more knowledgeable than myself.

[edit]I'll be back on in about an hour. Then I will work on your code with you. We'll simplify the Heart displaying code and in the process you'll probably learn how it works and how to do it yourself.[/edit]

Got my 4x4 wired up.. Well pretty much.

yeah i can see how #define could go wrong, i'll bear that in mind thanks.

what I don't understand is how the 1's and 0's in brackets are translated to high rows/low columns.

is byte patterns[numPatterns][8][8] a three dimensional array?

also, to display the heart, I extended my matrix to 4x6, although I think 4x5 is all i really need at the moment, to give me an axis of symmetry.

what I don't understand is how the 1's and 0's in brackets are translated to high rows/low columns.

Whenever you see the keywords "HIGH" or "LOW" they mean exactly the same thing as 1 and 0. According to arduino.cc, HIGH and LOW are of type int. So LOW is 0 and HIGH is anything above 0. If you had the code: digitalWrite(pin, HIGH); you could replace the "HIGH" with a 1 and nothing would change.. As for how he changes a 1 to a high row AND a low column.. I don't really know. It's easy to set the row to what it needs to be, but when you want the columns to do the opposite it gets difficult. I was playing with some code I wrote from scratch to display characters. I gained a greater appreciation of how hard it is to do.

is byte patterns[numPatterns][8][8] a three dimensional array?

Yes. The reason numPatterns is there is because the author wanted it to be more versatile so it would be easier to add patterns. The array can be thought of as numPatterns of 8x8's. So six 8x8 arrays. However you wanna think about it.