Can you really have complete control over an LED matrix with multiplexing?

Forgive me if this question has been answered before, but I have searched and have either not found it,
or understood it when I did see it.

So I have built a 4x4 array and have wired it up with common rows and coloumns so it can be controlled
with only 8 inputs. It works, but I don't understand how I can generate certain patterns. I understand
how controlling a single LED works, and rows and blocks, but not certain arrangements. Take the following:

X = LED OFF 0 = LED ON

C1 C2 C3 C4

A1 X X X X

A2 X X X X

A3 X 0 X 0

A4 X X 0 X

What is illogical to me is how could coordinate A3,C3 be off. If column C3 is activated in order
to light the led at A4,C3, and A3 is activated to light the leds at A3,C2 and A3,C4, would A3,C3 not be lit? Thanks.

-Sathi

Have a read of this, there are some animated examples of how this works.
http://www.thebox.myzen.co.uk/Workshop/LED_Matrix.html

That makes perfect sense. Thank you, great tutorial!

So my 4x4 array is actually composed of common anode rgb leds. I only hooked up the blue ones so I can understand
how this works without the added complexity of color. But I have been wondering all along how I would get more
than 7 colors since the entire row would share the pwm and I would not be able to control the color of an led individually. Now that I have read this tutorial, it makes sense how I can do this since I only have to worry about one column at a time.

I hooked the 4x4 up to a 74HC595 as a learning process. I've been searching for a good explanation on how to
simulate pwm over a 74HC595 but it is confusing to me so far. Do you know of a tutorial on that as good as the last one?

In general I am finding working with the shift register kind of confusing. In the example you gave me, the walking bit is represented by the actual pins of the arduino stored in an array and incremented. That is easy for me to understand. But since I am both sourcing and sinking on the same 74HC595 I am having difficulty conceptualizing a function such as:

turnOnLed(2,3) and it converting that input into a byte of 01001101. I know what I want to convert it to, just not the method. Any suggestions on what I need to read up on? I have looked at bitwise operations, but am having trouble understanding how to use it to get the right values where the sinking and sourcing values are contained in the same byte. I actually find the 8x8 array easier to understand because with two 74HC595, the byte is not shared. Thanks for your help.

One way to control the brightness of each LED is to use a LED driver chip like the TLC5940. You can use one of these and multiplex it as well.
While this is not a tutorial it is a project I did making an RGB 4 X 4 matrix.
http://www.thebox.myzen.co.uk/Hardware/Mini_Monome.html

Thanks for the great link. I've been able to work out a function that will refresh one row at a time. Now if I wanted to control this as an RGB array, and have full color control over each LED, would one LED have to be refreshed at a time, instead of one row at a time? I can't think of another way to do it.

In case anyone is interested, here is the function I came up with. writeMatrix takes 4 parameters. The number of times you want to repeat the pattern, the speed that the pattern will play, the pattern as an array, and the size of the array. This will update a shift register to control the LEDs.

//Pin connected to latch pin (ST_CP) of 74HC595
const int latchPin = 8;
//Pin connected to clock pin (SH_CP) of 74HC595
const int clockPin = 12;
//Pin connected to Data in (DS) of 74HC595
const int dataPin = 11;

int squareChase [ ] = {       
                         B00001111,                     
                         B00001001,
                         B00001001,
                         B00001111,
                        
                         B00000000,                     
                         B00000110,
                         B00000110,
                         B00000000
                 
        
      };
      
      int lineChaseH [ ] = {       
                         B00001111,                     
                         B00000000, 
                         B00000000, 
                         B00000000, 
                        
                         B00000000,                     
                         B00001111, 
                         B00000000, 
                         B00000000,
                         
                         B00000000,                     
                         B00000000, 
                         B00001111,  
                         B00000000,
                         
                         B00000000,                     
                         B00000000, 
                         B00000000, 
                         B00001111  
      };
      
 int walkPattern [] = {B11100000,
                       B11010000,
                       B10110000,
                       B01110000
 };
 
                        
long int refreshTime = 10; // time in milliseconds between refresh
long int patternRefresh;

int rayCount = 0;

void setup() {
  //Set pins for shift register
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);  
  pinMode(clockPin, OUTPUT);

}

void loop() {
           
       writeMatrix(10,170,lineChaseH,sizeof(lineChaseH)/sizeof(int));
     writeMatrix(10,170,squareChase,sizeof(squareChase)/sizeof(int));  

} // end of the loop


void writeMatrix(int repetitions, long int patternSpeed, int *patternArray, int raySize) {
  
  repetitionCounter = 0;
  
  while(repetitions > repetitionCounter) {
        if(millis() >= patternRefresh){

  patternRefresh = millis() + patternSpeed;

   rayCount = rayCount + 4;
    }
  
    if(rayCount == raySize) {
    rayCount = 0;
    repetitionCounter++;
    }
  
  for(int i = 0; i < 4; i++) {
    digitalWrite(latchPin, LOW);

byte byteToSend = patternArray[rayCount + i] | walkPattern[i];
   
   
    shiftOut(dataPin, clockPin, MSBFIRST, byteToSend);
   
     digitalWrite(latchPin, HIGH);
    
  }
  }
}

Now if I wanted to control this as an RGB array, and have full color control over each LED, would one LED have to be refreshed at a time, instead of one row at a time?

No you have to do it one row at a time otherwise your multiplexing ratio would be too great.
That is why you use chips like the TLC5940.
You could use the shiftPWM library but that does not address the LEDs in a matrix, although you can physically wires them up like that. Google Code Archive - Long-term storage for Google Code Project Hosting.