Jump to content

Help with LED matrix


noofny
 Share

Recommended Posts

bugfight - I can't thank you enough for taking the time to help out - have felt a bit lost with this one!

first i would suggest to use Tick() or Timer() to handle your testing instead of inlining it in Init() and using MIOS_Delay()

Good idea I'm familiar with that, will stay away from calling stuff in Init().

try all the permutations

Yeah did that over the weekend...even swapping the SR chips around for a spare set, etc. Doesn't seem to change anything.

you might also try connecting the doutx4 for both arrays, but not the first array itself

Do you mean try bypassing the darlingtons altogether?

if you want some suggestions on code efficiency, i can give some

I would really welcome and appreciate that...didn't want to ask...if you have the time PM me your suggestions/critiques/ideas.

Link to comment
Share on other sites

hello,

I contribute here as I worked on rgb led matrix too.

The only "problem" is the fact the cathods are linked... ground is common and if I sink the current on a line, it sinks from each cathode and blip blip blip: the three colors are light up together.

so transistors are here only for avoiding that!

but I guess everyone understood that, if it wasn't the case, I hope it is clearer for several

I just add it several links that could help:

1/ led spi interface from sparkfun

00760-02-L_i_ma.jpg

http://www.sparkfun.com/commerce/product_info.php?products_id=760 => especially the firmware code.

even if it is a spi between your core and the led driver, the matrix is connected via SR + a pretty ULN darlington arrays

watch this pdf

it shows a correct rgb led driver wired!

but this is incomplete without the wiring of the RGB led matrix involved

ATTENTION: the matrix is " as if it was" a common anode in this sparkfun example !

all the examples here are common cathode!

but the philosophy is the same watch it:

I thought you had to feed -v into the darlingon in's, but you feed in +v and it outputs -v. Still don't really understand how that happens but there's a lot of this going over my head - just glad it's sorted though.

currents have to be sinked by the darlington.

you saturate one transitor by sending +v to it

it closes the circuit between the corresponding line and the ground ... so yes: the current gets out the led cathode to the ... commuted ground :)

and you do it on a cycle.

so now, it is complete  ;)

2/ unsped & Devon Jones/Octinct (+ )

for those who don't know the octinct, it is a NICE and WORKING full* rgb monome clone arduino based.

http://unsped.blogspot.com/

Check the code it uses.

no darlington, ok, but 3 transistors: one for each color.

the cycle is:

for all lines

   for all color

       light up this led

the first link about that, that talks about darlington is : http://www.upwardnotnorthward.com/2008/01/my-first-project-full-colour-rgb-monome.html

3/ arduinome's playground about LEDs

http://www.arduino.cc/playground/Main/InterfacingWithHardware#Output => LEDS & Display (just added the unsped link, it hasn't been added ... what a omission!!!)

BTW, I began a project like noofny, I only designed things on visio and ordered 2 midibox 64 kits at Mike's shop.

If I can help about that, I could easily debug when I'll wire my matrixes...but I'm sure above links provide solutions, especially the first link that shows how the hardware has to be wired!

If you need help, just ask!!

Link to comment
Share on other sites

ok, first i think there was good reason to keep the same color leds anodes on a single sr...

as a result you are wasting a lot of bits in your color arrays, and cycles setting pins instead of

whole registers as a byte at once.

but aside from that, anywhere i see the same code (or similar code) repeated i look for a better way.

there are rare cases where you need to trade code efficiency for execution efficiency, but i don't think

these cases fall under that umbrella.

note that i haven't compiled these so it's likely there are some typos...

where you have:

		matrix_2[_MATRIX_SONG_COLUMN][0] = 0x30;
		matrix_2[_MATRIX_SONG_COLUMN][1] = 0x30;
		matrix_2[_MATRIX_SONG_COLUMN][2] = 0x30;
		matrix_2[_MATRIX_SONG_COLUMN][3] = 0x30;
		matrix_2[_MATRIX_SONG_COLUMN][4] = 0x30;
		matrix_2[_MATRIX_SONG_COLUMN][5] = 0x30;
		matrix_2[_MATRIX_SONG_COLUMN][6] = 0x30;
		matrix_2[_MATRIX_SONG_COLUMN][7] = 0x30;
		switch(evnt1-0x10)
		{
			case 0:	// SONG 1
				matrix_2[_MATRIX_SONG_COLUMN][evnt1-0x10] = evnt2;
				break;
			case 1:	// SONG 2
				matrix_2[_MATRIX_SONG_COLUMN][evnt1-0x10] = evnt2;
				break;
			case 2:	// SONG 3
				matrix_2[_MATRIX_SONG_COLUMN][evnt1-0x10] = evnt2;
				break;
			case 3:	// SONG 4
				matrix_2[_MATRIX_SONG_COLUMN][evnt1-0x10] = evnt2;
				break;
			case 4:	// SONG 5
				matrix_2[_MATRIX_SONG_COLUMN][evnt1-0x10] = evnt2;
				break;
			case 5:	// SONG 6
				matrix_2[_MATRIX_SONG_COLUMN][evnt1-0x10] = evnt2;
				break;
			case 6:	// SONG 7
				matrix_2[_MATRIX_SONG_COLUMN][evnt1-0x10] = evnt2;
				break;
			case 7:	// SONG 8
				matrix_2[_MATRIX_SONG_COLUMN][evnt1-0x10] = evnt2;
				break;

			default:
				//matrix_2[evnt1-0x10][evnt0-0x90] = evnt2;
				break;
		}
i would have:
		
	int i;
        unsigned char songIdx = evnt1-0x10;
        for(i=0; i<8; i++)
        {
            if(i == songIdx)
                matrix_2[_MATRIX_SONG_COLUMN][i] = evnt2
            else
                matrix_2[_MATRIX_SONG_COLUMN][i] = 0x30;
        }
where you have:
  
void DisplayLED(unsigned char column, unsigned char color) __wparam
{
	switch(color)
	{
		case 0x00:		//OFF
			MIOS_DOUT_PinSet(column+8,		0);
			MIOS_DOUT_PinSet(column+8+8,	0);
			MIOS_DOUT_PinSet(column+8+16,	0);
			break;
		case 0x10:		// RED
			MIOS_DOUT_PinSet(column+8,		1);
			MIOS_DOUT_PinSet(column+8+8,	0);
			MIOS_DOUT_PinSet(column+8+16,	0);
			break;
		case 0x20:		// GREEN
			MIOS_DOUT_PinSet(column+8,		0);
			MIOS_DOUT_PinSet(column+8+8,	1);
			MIOS_DOUT_PinSet(column+8+16,	0);
			break;
		case 0x30:		// BLUE
			MIOS_DOUT_PinSet(column+8,		0);
			MIOS_DOUT_PinSet(column+8+8,	0);
			MIOS_DOUT_PinSet(column+8+16,	1);
			break;
		case 0x40:		// CYAN
			MIOS_DOUT_PinSet(column+8,		0);
			MIOS_DOUT_PinSet(column+8+8,	1);
			MIOS_DOUT_PinSet(column+8+16,	1);
			break;
		case 0x50:		// MAGENTA
			MIOS_DOUT_PinSet(column+8,		1);
			MIOS_DOUT_PinSet(column+8+8,	0);
			MIOS_DOUT_PinSet(column+8+16,	1);
			break;
		case 0x60:		// YELLOW
			MIOS_DOUT_PinSet(column+8,		1);
			MIOS_DOUT_PinSet(column+8+8,	1);
			MIOS_DOUT_PinSet(column+8+16,	0);
			break;
		case 0x70:		// WHITE
			MIOS_DOUT_PinSet(column+8,		1);
			MIOS_DOUT_PinSet(column+8+8,	1);
			MIOS_DOUT_PinSet(column+8+16,	1);
			break;

		default:
			break;
	}
}     
i would have:
void DisplayLED(unsigned char column, unsigned char color) __wparam
{
	color >>= 4;
	MIOS_DOUT_PinSet(column+8,		(color & 0x01));
	color >>= 1;
	MIOS_DOUT_PinSet(column+8+8,	(color & 0x01));
	color >>= 1;
	MIOS_DOUT_PinSet(column+8+16,	(color & 0x01));
}
where you have:
void SR_Service_Prepare(void) __wparam
{
	static unsigned char row;
	static unsigned int x;
	row = ++row & 0x0F;
	MIOS_DOUT_SRSet(0, 0);
	MIOS_DOUT_SRSet(4, 0);
	switch(row)
	{
		case 0 :
		{
			MIOS_DOUT_PinSet1(row);
			MIOS_DOUT_PinSet1(row+32);
			for (x = 0; x < 8; x++)
			{
				DisplayLED(x,		matrix_1[row][x]);
				DisplayLED(x+32,	matrix_2[row][x]);
			}
			break;
		}
		case 1 :
		{
			MIOS_DOUT_PinSet1(row);
			MIOS_DOUT_PinSet1(row+32);
			for (x = 0; x < 8; x++)
			{
				DisplayLED(x,		matrix_1[row][x]);
				DisplayLED(x+32,	matrix_2[row][x]);
			}
			break;
		}
		case 2 :
		{
			MIOS_DOUT_PinSet1(row);
			MIOS_DOUT_PinSet1(row+32);
			for (x = 0; x < 8; x++)
			{
				DisplayLED(x,		matrix_1[row][x]);
				DisplayLED(x+32,	matrix_2[row][x]);
			}
			break;
		}
		case 3 :
		{
			MIOS_DOUT_PinSet1(row);
			MIOS_DOUT_PinSet1(row+32);
			for (x = 0; x < 8; x++)
			{
				DisplayLED(x,		matrix_1[row][x]);
				DisplayLED(x+32,	matrix_2[row][x]);
			}
			break;
		}
		case 4 :
		{
			MIOS_DOUT_PinSet1(row);
			MIOS_DOUT_PinSet1(row+32);
			for (x = 0; x < 8; x++)
			{
				DisplayLED(x,		matrix_1[row][x]);
				DisplayLED(x+32,	matrix_2[row][x]);
			}
			break;
		}
		case 5 :
		{
			MIOS_DOUT_PinSet1(row);
			MIOS_DOUT_PinSet1(row+32);
			for (x = 0; x < 8; x++)
			{
				DisplayLED(x,		matrix_1[row][x]);
				DisplayLED(x+32,	matrix_2[row][x]);
			}
			break;
		}
		case 6 :
		{
			MIOS_DOUT_PinSet1(row);
			MIOS_DOUT_PinSet1(row+32);
			for (x = 0; x < 8; x++)
			{
				DisplayLED(x,		matrix_1[row][x]);
				DisplayLED(x+32,	matrix_2[row][x]);
			}
			break;
		}
		case 7 :
		{
			MIOS_DOUT_PinSet1(row);
			MIOS_DOUT_PinSet1(row+32);
			for (x = 0; x < 8; x++)
			{
				DisplayLED(x,		matrix_1[row][x]);
				DisplayLED(x+32,	matrix_2[row][x]);
			}
			break;
		}
		default :
		{
			break;
		}
	}
}
i would have:
void SR_Service_Prepare(void) __wparam
{
	static unsigned char row;
	unsigned int x; //edit* just noticed, no reason for this to be static
	row = ++row & 0x07; //<-- here you were cycling 16 rows i think you meant 8, no?  
                        //this would have resulted in a 6.25% duty cycle (vs 12.5%).  
                        //note that the duomatrix uses a 25% duty cycle
	MIOS_DOUT_SRSet(MATRIX1_DOUT_START, 0);//<-- hardwire bad, napster good.  define constants 
	MIOS_DOUT_SRSet(MATRIX2_DOUT_START, 0);//    so you can move your matrix in the chain


	MIOS_DOUT_PinSet1(row + (MATRIX1_DOUT_START * 8));
	MIOS_DOUT_PinSet1(row + (MATRIX2_DOUT_START * 8));
	for (x = 0; x < 8; x++)
	{
		DisplayLED(x + (MATRIX1_DOUT_START * 8), matrix_1[row][x]);
		DisplayLED(x + (MATRIX2_DOUT_START * 8), matrix_2[row][x]);
	}
}

Link to comment
Share on other sites

bugfight, the code you made is to use with the first schematic from noofny or another (one of those in my link) ??

I found a mistake in the schematic, hope noofny didn't make it in the real world.

the "common" pin (pin 9 for the ULN2003 and 10 for the ULN2803) isn't linked to ... ground in our case.

personally, and probably, I'll do that:

rgbledsuln28003dout21.jpg

bugfight? what do you think about that and about the code we can use for it ?

by sending bytes from the CORE to the DOUTx4, we successively commute the rows of the matrix to the ground and light up colors in the line successively:

for line

    for color

        light up all led in the line with current color

the only question I have: does it flicker......................?

indeed, at a time, one color of a led in one line is up...

I'm afraid about that.

I have to dive more inside the midibox framework in order to figure out how timers are used ..

because: handle pots, buttons, and ... making so quick needed cycles... I guess it requires asynchronous stuff.. (thread..)

but i'm sure it already exists in this powerful framework

Link to comment
Share on other sites

as I'm just as the beginning of my project, I cannot test it by myself, but... I almost understood how it can work..

the schematic of noofny, with the verification and eventually fixed thing about the ground of pin 9 (or pin 10 with ULN28003) may work fine!

in order to avoid flickering, I guess we have to use an interrupt service routine.

it is a process called periodically AND independently of the main routine.

I read this a long time ago about interrupt and timer of arduino board (atmega8 controller)

As described here, we have to use the timer2 and a particular interrupt.

indeed, the timer 0 is the clock reference

timer1, timer2 takes timer0 as a reference

so, we can "hijack" timer2 for our use

/////////////////////////////////////////////////////////////////////////////
// This function is periodically called by MIOS. The frequency has to be
// initialized with MIOS_Timer_Set
/////////////////////////////////////////////////////////////////////////////
void Timer(void) __wparam
{
}

I'd like to put inside this Timer(void) function the cycle we talked about above.

pratically, it should work like that:

main functions => handle button (via DIN SRs) + handle pots (via AIN SRs)

interrupt called functions => handle RGB Leds matrix (called via an interrupt)

why shouldn't we OVERload the Timer(void) function ?

it is easy: when it will be called, the system ONLY care of what it will be inside this function.. it means: no functions from the main thread works!!

...thus it is called i n t e r r u p t... pretty and cool name and ... indeed the appropriated name ;)

basically, it means: no pots handling, no buttons handling during the interrupt time (= the driving leds matrix time)

I'll code something asap.

but as I said, I cannot test it.

so, probably, we'll work with noofny (one in France, the other in Australia...!)

but the solution is near... and others had done it before (example: the monodeck II)

Link to comment
Share on other sites

bugfight, USER_SR_Service_Prepare is an ISR too... (sorrrrrry!)

so probably, your code works like that and works with efficiency ... :)

noofny, I guess it could be useful to make one core drives one matrix, and the other one the other matrix

because of overloading risk of ISR..

experts, what do you think about that?

Link to comment
Share on other sites

sorry have been away from the project for a few days...needed a break....thanks bugfight and julian for your posts. Had a quick look over the code changes and think I understand them all so will be refactoring the code tonight and will post the results.

Apart from that - so long as I dont try light up all the LED's as white things are working so at least it's not a show stopper!

Link to comment
Share on other sites

have implemented all the advised changes and not only does everything still work but things seem to be working better...not yet tested lighting up both matrix's full tho...has been a good learning task.

bugfight - thanks so much mate - I owe you a beer - what do you drink?

8)

Link to comment
Share on other sites

  • 2 weeks later...

indeed...

the loard resistor are already on the lines ("before" the leds..) so ... it doesn't require another one

I'll use a 2803 (18 pins..) so I have to re-check that to directly put it on the DOUTx4 module..

I think I'll do a thing like mike/noofny: DSC01314.JPG

not sure yet :)

Link to comment
Share on other sites

  • 2 months later...
  • 2 months later...

hello,

6 months after, I'm almost ok with my deck.

I use the same code that the one of noofny, but I don't have 2 DOUT on the same core: I have one DOUT on each core.

I made a modification and I'm using smashTV DOUT with 4 SR, 3 resistor arrays + 1 ULN2803.

The ULN2803 pin9 is clamped to GND, the pin 10 isn't connected to nothing (the mistake is here ....????)

I attached the main.c & main.h of the core 1 but I did the same thing for led handling for the core 2.

The code of noofny works fine for his 2 DOUT chained, I altered it to make it working with my solo DOUT...

BUT it doesn't work!

the code part to look at are :

void DisplayLED(unsigned char column, unsigned char color) __wparam
{
	color >>= 4;
	MIOS_DOUT_PinSet(column+8,		(color & 0x01));  	// RED
	color >>= 1;
	MIOS_DOUT_PinSet(column+8+8,	(color & 0x01)); 	// BLUE
	color >>= 1;
	MIOS_DOUT_PinSet(column+8+8+8,	(color & 0x01));	// GREEN
}
/////////////////////////////////////////////////////////////////////////////
// This function is called by MIOS before the shift register are loaded
/////////////////////////////////////////////////////////////////////////////
void SR_Service_Prepare(void) __wparam
{
	// HELPED BY BUGFIGHT ON MIDIBOX - http://www.midibox.org/forum/index.php/topic,12786.0.html
	static unsigned char row;
	unsigned int x; 							//edit* just noticed, no reason for this to be static
	row = ++row & 0x07; 						//<-- here you were cycling 16 rows i think you meant 8, no?
												//this would have resulted in a 6.25% duty cycle (vs 12.5%).
												//note that the duomatrix uses a 25% duty cycle
	MIOS_DOUT_SRSet(_MATRIX_DOUT_START, 0);	//<-- hardwire bad, napster good.  define constants
											//    so you can move your matrix in the chain
	MIOS_DOUT_PinSet1(row);

	for (x = 0; x < 8; x++)
	{
		DisplayLED(x , matrix[row][x]);
	}
}

could someone help me a bit?

all the best,

main.c

main.h

main.c

main.h

Link to comment
Share on other sites

no problem.

it shouldn't be a code problem.

my matrix isn't common cathode... but common anode.

thanks besthongkong ! I ordered common cathode, you sent common anode...

if I wasn't a newbie, of course I'd check it before soldering but ...

btw, thanks to lucem. he detailed me how I can make it works with darlington and BC547 too...

I guess it will work ... tomorrow!

all the best

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...