Go Down

Topic: LED multiplexing using Arrays as Datastructure (Read 1 time) previous topic - next topic

GalaxG64

Oct 15, 2013, 05:36 pm Last Edit: Oct 15, 2013, 05:46 pm by GalaxG64 Reason: 1
Hi, I'm Alexander 19 and I am fairly new to arduino,
Ive built a working 4x5 led Matrix an a Breadboard, I have also written a very straight forward code to controll it
I would however like be able to add symbols ect. using a 2dimensional array structure. I however have no real Idea, how to read the arrays and print the data using Multiplexing.
I wanted to realize some projects for in house comunication so the displays would grow in the future and then the simple method of punching in each LED would be a lot of maybee unneccesary typing.
Im looking forward for your replys,
Thanks and have a nice day,
Alexander
this is my code so far:

Code: [Select]
int i;
int j;
#define  cycles 5000

      //reference 0,1,2,3
int spaltpins[] = {4,5,2,3};
      // reference 0,1,02,03,04
int zeilenpins[] = {8,9,10,11,12};

void setup()
{
 //pins mithilfe von Arrays deklarieren
 for(i=0;i<4;i++)
 {
   pinMode(spaltpins[i],OUTPUT);
 }
 for(i=0;i<5;i++)
 {
   pinMode(zeilenpins[i],OUTPUT);
 }
}
void led(int k, int l)
{
   digitalWrite(spaltpins[k],1);
   digitalWrite(zeilenpins[l],1);
   delayMicroseconds(5);
   digitalWrite(spaltpins[k],0);
   digitalWrite(zeilenpins[l],0);
   delayMicroseconds(5);
}
 
void loop()
{
 //H
 for(i=0;i<cycles;i++)
 {
   led(0,0);
   led(3,0);
   led(0,1);
   led(3,1);
   led(0,2);
   led(1,2);
   led(2,2);
   led(3,2);
   led(0,3);
   led(3,3);
   led(0,4);
   led(3,4);
 }
 delay(100);
 //A
 for(i=0;i<cycles;i++)
 {
   led(0,0);
   led(1,0);
   led(2,0);
   led(3,0);
   led(0,1);
   led(3,1);
   led(0,2);
   led(1,2);
   led(2,2);
   led(3,2);
   led(0,3);
   led(3,3);
   led(0,4);
   led(3,4);
 }
 delay(100);
 //L
 for(i=0;i<cycles+1500;i++)
 {
   led(0,0);
   led(0,1);
   led(0,2);
   led(0,3);
   led(0,4);
   led(1,4);
   led(2,4);
   led(3,4);    
 }
 
 delay(100);
 //L
 for(i=0;i<cycles+1500;i++)
 {
   led(0,0);
   led(0,1);
   led(0,2);
   led(0,3);
   led(0,4);
   led(1,4);
   led(2,4);
   led(3,4);    
 }
 delay(100);
 //O
 for(i=0;i<cycles;i++)
 {
   led(0,0);
   led(0,1);
   led(0,2);
   led(0,3);
   led(0,4);
   led(1,4);
   led(2,4);
   led(3,4);
   led(3,3);
   led(3,2);
   led(3,1);
   led(3,0);
   led(2,0);
   led(1,0);
 }
 delay(500);
 //D
 for(i=0;i<cycles+1000;i++)
 {
   led(0,0);
   led(0,1);
   led(0,2);
   led(0,3);
   led(0,4);
   led(1,0);
   led(2,1);
   led(3,2);
   led(2,3);
   led(1,4);
 }
 delay(100);
 //A
 for(i=0;i<cycles;i++)
 {
   led(0,0);
   led(1,0);
   led(2,0);
   led(3,0);
   led(0,1);
   led(3,1);
   led(0,2);
   led(1,2);
   led(2,2);
   led(3,2);
   led(0,3);
   led(3,3);
   led(0,4);
   led(3,4);
 }
 //V
 for(i=0;i<cycles;i++)
 {
   led(0,0);
   led(0,1);
   led(0,2);
   led(0,3);
   led(0,4);
   led(1,3);
   led(2,2);
   led(3,1);
   led(3,0);
 }
 delay(100);
 //I
 for(i=0;i<cycles+3000;i++)
 {
   led(1,1);
   led(1,2);
   led(1,3);
   led(1,4);
   led(1,0);
 }
 delay(100);
 //D
 for(i=0;i<cycles+1000;i++)
 {
   led(0,0);
   led(0,1);
   led(0,2);
   led(0,3);
   led(0,4);
   led(1,0);
   led(2,1);
   led(3,2);
   led(2,3);
   led(1,4);
 }
 delay(500);
}

CrossRoads

Wow, that seems like the long way to get there.

For your matrix, where you apparenty only lighting one LED at a time, I would go this route, make it blink without delay style, with one time period for how long an individual LED is to stay on, and a second time period for alternating between what is being displayed.

This might need some tweaking, I am making it up as I go here.
There are several arrays  being used, and some arrays within an array, so draw some pictures as you go to make this clearer ...

Code: [Select]

byte anodeCount = 0;
byte anodeArray[] = {2,3,4,5,}; // or whatever you had for anode pins - assumes An colums
byte maxAnode = 4; // 4 anodes, indexed 0-1-2-3
byte cathodeCount = 0;
byte cathodeArray[] = {6,7,8,9,10,}; // or whatever you had for cathode pins - assumes Ca rows
byte maxCathode = 5; // 5 cathodes, indexed 0-1-2-3-4
byte dataArray[5]; // 5 bytes of info to display
byte maskArray[] = {0x01, 0x02, 0x04, 0x08,};  // my clever (lazy?) contribution
byte fontArray[] = { // array of font information, every 5 bytes is a new character
// fontArray[0] to [4] are character 0, [5] to [9] are character 1, etc.
Bxxxx1111,  // 0 - replace x's with 0s, used here to show digits more clearly
Bxxxx1001,
Bxxxx1001,
Bxxxx1001,
Bxxxx1111,

Bxxxx0010,
Bxxxx0110,
Bxxxx0010,
Bxxxx0010,
Bxxxx0111,

//etc

Bxxxx1111, // 9 with lower tail
Bxxxx1001,
Bxxxx1111,
Bxxxx0001,
Bxxxx0111,
}


void loop(){
currentTime = micros();

// LED refresh
elapsedRefreshTime = currentTime - nextRefreshTime;

// time to turn off the prior LED, and select the next LED to be turned on
if (elapsedRefreshTime >= ledDisplayTime){  // like 500uS per LED
nextRefreshTime = nextRefresahTime + ledDisplayTime; //  next time to make a change
digitalWrite (anodeArray[anodeCount], LOW); // turn off current LED
digitalWrite (cathodeArray[cathodeCount], HIGH); // turn off current LED

// now a loop with-in a loop, but not done as for:loop since it is broken up by time
// so the count of where is kept instead
anodeCount = anodeCount +1;
if (anodeCount == maxAnode){  // reset count, increment cathode
anodeCount = 0;
cathodeCount = cathodeCount +1;
if (cathodeCount == maxCathode){ // reset count
cathodeCount = 0;
  }
}
// now turn on next LED - assumes that the lower 4 bits of 5 bytes represent the data
// data to represent a 0 for example: B0x0F, B0x09, B0x09, B0x09, B0x0F
// Bxxxx1111 
// Bxxxx1001
// Bxxxx1001
// Bxxxx1001
// Bxxxx1111

// now mask the array data and write the anode high or low as needed
// anodeCount tells you which bit - 0,1,2,3 to mask for
// cathodeCount tells you which row pin to turn on of dataArray[] (0 to 4)
// anodeArray tells you which anode column pin to turn on

// intersection of anode Column & cathode Row is the LED that will turn on

if ( (maskArray[anodeCount] & dataArray[cathodeCount] ) ==1){
digitalWrite (anodeArray[anodeCount], HIGH);
}
digitalWrite (cathodeArray[cathodeCount], LOW);
} // end display multiplex time check

//
// now do other stuff that will update dataArray[] = button pushes, serial data, another time check (2 seconds, 5 seconds, whatever) to update the array with new data, etc.
//
elapsedDigitTime = currentTime - nextDigitTime;
if (elapsedDigitTime >= digitDisplayTime){ // like 1 second,  2 seconds
nextDigitTime = nextDigitTime + digitDisplayTime; // next time to make a change
digitCount = digitCount +1;
if (digitCount == 4){ // say you had 4 time digits you were displaying, 10:27 for example
  digitCount = 0;
  }
// so timeArray[] = {1,0,2,7,}; // you would update this once a minute for example
dataArray[0] = fontArray[timeArray[digitCount*5]]); // so for character 1, byte 5 of fontArray is used
dataArray[1] = fontArray[timeArray[digitCount*5+1]]); // byte 6
dataArray[2] = fontArray[timeArray[digitCount*5+2]]); // byte 7
dataArray[3] = fontArray[timeArray[digitCount*5+3]]); // byte 8
dataArray[4] = fontArray[timeArray[digitCount*5+4]]); // byte 9
// character 0 would use 0,1,2,3,4
// character 7 would use 35,36,37,38,39
// Guess you could say this is another way to look at a 2 dimensional array
} // end character change time check

} // end loop

Unfortunately I am not home to compile & test this.
It is left as an exercse to add the pin definitions, define the rest of the array information, etc.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

GalaxG64

Ok, Thanks a lot I'll need some time to get a grasp on that code. We will se how far I get. I'll ask questions on my way, when something is unclear.
Again thanks a lot,
 

GalaxG64

Hi again, I've worked through the code and wanted to say thanks a lot for the support. and yes, that is a way to look at 2D arrays.
what do the hexdec numbers in maskArray[] do, i kinda dont get that?
Thanks again,
Alexander

CrossRoads

this line

if ( (maskArray[anodeCount] & dataArray[cathodeCount] ) ==1){

should have been

if ( (maskArray[anodeCount] & dataArray[cathodeCount] ) >=1){

So say you this byte you are working on displaying: 0bxxxx1001

first pass thru maskArray[0] = 0b00000001, and 00000001 & xxxx1001 = 00000001, so turn on that LED
2ndm 3rd pass you 0b00000010, 0b00000100, with xxxx1001 will both = 0, so those LEDs stay off
4th pass, mask[3] = 0b00001000 & xxxx1001 = 00001000, which is >= 1, so turn on that LED.
Make sense? I used to try and shift a 1 across a byte for the mask, but this turned out to be much simpler.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up