Jump to content

[solved/ keyword static and LUT] common anode matrix & ISR


protofuse

Recommended Posts

hello,

fortunately, I built my common anode matrix rgb led driver (THANKS TO LUCEM who detailed me all the process, and made me understand!)

- row (anodes) driver is SR + resistor 1k + transistor BC547 used as a switch to source 5V to rows..

- column (cathodes) driver is 3 ULN to sink current + 3 SR. (3 = one for each color)

I have a little problem now with the code (only the code, I guess)

When I basically turn pins high in Init(), it works very fine !

But the process has to be done in ISR via SR_Service_Prepare()

when I do that, no led are up...

1st SR is for ROW driver

2, 3, 4th are for RBG color COLUMN driver

here are the code involved:


/////////////////////////////////////////////////////////////////////////////

// Include files

/////////////////////////////////////////////////////////////////////////////


#include <cmios.h>

#include <pic18fregs.h>

#include <protodeck.h>

#include "main.h"


/////////////////////////////////////////////////////////////////////////////

// Global variables

/////////////////////////////////////////////////////////////////////////////


// status of application (see bitfield declaration in main.h)

app_flags_t app_flags;


/////////////////////////////////////////////////////////////////////////////

// Local variables

/////////////////////////////////////////////////////////////////////////////


// last ain/din/dout

unsigned char last_ain_pin;

unsigned char last_din_pin;

unsigned char last_dout_pin;



// we create a 2-dimensional array with 23 entries for mapping between potentiometers movements & events associated

// each entry consists of two bytes:

// o one for the first MIDI byte (MIDI status) => 0xb* means CC message for Channel *

// o a second for the second MIDI byte (=> CC number)

// The meaning of the bytes can be found in the MIDI spec

// (-> http://www.harmony-central.com/MIDI/Doc/table1.html)

// (-> http://www.harmony-central.com/MIDI/Doc/table2.html)

// (-> http://www.harmony-central.com/MIDI/Doc/table3.html)


const unsigned char pot_event_map[23][2] = {

//AIN 11

 // Pots 1-12 = drums controls pots => channel 10

 {0xb9, 0x01}, {0xb9, 0x02}, {0xb9, 0x03}, {0xb9, 0x04}, {0xb9, 0x05}, {0xb9, 0x06},

 {0xb9, 0x07}, {0xb9, 0x08}, {0xb9, 0x09}, {0xb9, 0x0A}, {0xb9, 0x0B}, {0xb9, 0x0C},


 // Pots 13-18 = EQ = channel 16

 {0xbF, 0x01}, {0xbF, 0x02}, {0xbF, 0x03}, {0xbF, 0x04}, {0xbF, 0x05}, {0xbF, 0x06},


 // Pot 19 = Master Volume = channel 16

 {0xbF, 0x07},


 // Pots 20-23 = multifunctionnal purpose pots = channel 16

 {0xbF, 0x08}, {0xbF, 0x09}, {0xbF, 0x10}, {0xbF, 0x0A},

 };



// we create a 2-dimensional array with 64 entries for mapping between switches push & events associated

// each entry consists of two bytes:

// o one for the first MIDI byte (MIDI status) => 0x9* means Note message for Channel *

// o a second for the second MIDI byte (=> Note number)

// This const is parsed lower by void DIN_NotifyToggle()

// The meaning of the bytes can be found in the MIDI spec

// (-> http://www.harmony-central.com/MIDI/Doc/table1.html)

// (-> http://www.harmony-central.com/MIDI/Doc/table2.html)

// (-> http://www.harmony-central.com/MIDI/Doc/table3.html)


const unsigned char button_event_map[64][2] = { //------- clip matrix control

 //-------- DIN11

 // Buttons 1-8 = tracks mute = channel 1-8

 {0x90, 0x01}, {0x91, 0x01}, {0x92, 0x01}, {0x93, 0x01},

 {0x94, 0x01}, {0x95, 0x01}, {0x96, 0x01}, {0x97, 0x01},

 // Buttons scenes 1 = 9-16 = channel 1-8

 {0x90, 0x02}, {0x91, 0x02}, {0x92, 0x02}, {0x93, 0x02},

 {0x94, 0x02}, {0x95, 0x02}, {0x96, 0x02}, {0x97, 0x02},

 // Buttons scenes 2 = 17-24 = channel 1-8

 {0x90, 0x03}, {0x91, 0x03}, {0x92, 0x03}, {0x93, 0x03},

 {0x94, 0x03}, {0x95, 0x03}, {0x96, 0x03}, {0x97, 0x03},

 // Buttons scenes 3 = 25-32 = channel 1-8

 {0x90, 0x04}, {0x91, 0x04}, {0x92, 0x04}, {0x93, 0x04},

 {0x94, 0x04}, {0x95, 0x04}, {0x96, 0x04}, {0x97, 0x04},

 //-------- DIN12

 // Buttons scenes 4 = 33-40 = channel 1-8

 {0x90, 0x05}, {0x91, 0x05}, {0x92, 0x05}, {0x93, 0x05},

 {0x94, 0x05}, {0x95, 0x05}, {0x96, 0x05}, {0x97, 0x05},

 // Buttons scenes 5 = 41-48 = channel 1-8

 {0x90, 0x06}, {0x91, 0x06}, {0x92, 0x06}, {0x93, 0x06},

 {0x94, 0x06}, {0x95, 0x06}, {0x96, 0x06}, {0x97, 0x06},

 // Buttons scenes 6 = 49-56 = channel 1-8

 {0x90, 0x07}, {0x91, 0x07}, {0x92, 0x07}, {0x93, 0x07},

 {0x94, 0x07}, {0x95, 0x07}, {0x96, 0x07}, {0x97, 0x07},

 // Buttons scenes control = 57-62 = CHANNEL 16

 {0x9F, 0x01}, {0x9F, 0x02}, {0x9F, 0x03}, {0x9F, 0x04},

 {0x9F, 0x05}, {0x9F, 0x06},

 // Buttons offset control = 63,64 = CHANNEL 16

 {0x9F, 0x07}, {0x9F, 0x08}

 };



static unsigned int clipButtons[8] = { 0,0,0,0,0,0,0,0 };



// we create a 2-dimensional array with 64 entries for led color storage for the clip matrix controller part

// each entry consists of 1 byte coded like that:

// 0x00 = OFF

// 0x10 = RED

// 0x20 = GREEN

// 0x40 = BLUE

// 0x30 = RED + GREEN = YELLOW

// 0x60= GREEN + BLUE = CYAN

// 0x50 = RED + BLUE = MAGENTA

// 0x70 = WHITE

// The meaning of the bytes can be found in the MIDI spec

// (-> http://www.harmony-central.com/MIDI/Doc/table1.html)

// (-> http://www.harmony-central.com/MIDI/Doc/table2.html)

// (-> http://www.harmony-central.com/MIDI/Doc/table3.html)

//

// structure is matrix[ROW][COLUMN]=COLOR

static unsigned char matrix[8][8] = {

		{0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10},

	 {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},

	 {0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30},

	 {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40},

	 {0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50},

	 {0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60},

	 {0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70},

	 {0x00,0x30,0x00,0x50,0x00,0x70,0x00,0x00}

 };



/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS after startup to initialize the

// application

/////////////////////////////////////////////////////////////////////////////

void Init(void) __wparam

{

 // configure the core1 as midibox-link FORWARD Point

 // see infos about midibox-link here: http://www.ucapps.de/midibox_link.html

 MIOS_MIDI_MergerSet(MIOS_MIDI_MERGER_MBLINK_EP);


 // set shift register update frequency

 MIOS_SRIO_UpdateFrqSet(1); // ms


 // we need to set at least one IO shift register pair

 MIOS_SRIO_NumberSet(NUMBER_OF_SRIO);


 // debouncing value for DINs

 MIOS_SRIO_DebounceSet(DIN_DEBOUNCE_VALUE);


 MIOS_SRIO_TS_SensitivitySet(DIN_TS_SENSITIVITY);


 // initialize the AIN driver

 MIOS_AIN_NumberSet(AIN_NUMBER_INPUTS);

#if AIN_MUXED_MODE

 MIOS_AIN_Muxed();

#else

 MIOS_AIN_UnMuxed();

#endif

 MIOS_AIN_DeadbandSet(AIN_DEADBAND);


// all pin of row driver low

	MIOS_DOUT_SRSet(0, 0);


}


/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS in the mainloop when nothing else is to do

/////////////////////////////////////////////////////////////////////////////

void Tick(void) __wparam

{

}


/////////////////////////////////////////////////////////////////////////////

// This function is periodically called by MIOS. The frequency has to be

// initialized with MIOS_Timer_Set

/////////////////////////////////////////////////////////////////////////////

void Timer(void) __wparam

{

}


//////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS when the display content should be

// initialized. Thats the case during startup and after a temporary message

// has been printed on the screen

/////////////////////////////////////////////////////////////////////////////

void DISPLAY_Init(void) __wparam

{

 // clear screen

 MIOS_LCD_Clear();


 // print static messages

 MIOS_LCD_CursorSet(0x00); // first line

 MIOS_LCD_PrintCString("1AIN DIN DOUT");

 MIOS_LCD_CursorSet(0x40); // second line

 MIOS_LCD_PrintCString("xx:xxx xxxx xxxx");


 // request display update

 app_flags.DISPLAY_UPDATE_REQ = 1;

}


/////////////////////////////////////////////////////////////////////////////

// This function is called in the mainloop when no temporary message is shown

// on screen. Print the realtime messages here

/////////////////////////////////////////////////////////////////////////////

void DISPLAY_Tick(void) __wparam

{

 // do nothing if no update has been requested

 if( !app_flags.DISPLAY_UPDATE_REQ )

 return;


 // clear request

 app_flags.DISPLAY_UPDATE_REQ = 0;


 // print status of AIN

 MIOS_LCD_CursorSet(0x40 + 0);

 MIOS_LCD_PrintBCD2(last_ain_pin + 1);

 MIOS_LCD_PrintChar(':');

 MIOS_LCD_PrintBCD3(MIOS_AIN_Pin7bitGet(last_ain_pin));


 // print status of DIN

 MIOS_LCD_CursorSet(0x40 + 7);

 MIOS_LCD_PrintBCD3(last_din_pin + 1);

 MIOS_LCD_PrintChar(MIOS_DIN_PinGet(last_din_pin) ? 'o' : '*');


 // print status of DOUT

 MIOS_LCD_CursorSet(0x40 + 12);

 MIOS_LCD_PrintBCD3(last_dout_pin + 1);

 MIOS_LCD_PrintChar(MIOS_DOUT_PinGet(last_dout_pin) ? '*' : 'o');

}


/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS when a MIDI byte has been received

/////////////////////////////////////////////////////////////////////////////

void MPROC_NotifyReceivedByte(unsigned char byte) __wparam

{

}


/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS when a complete MIDI event has been received

/////////////////////////////////////////////////////////////////////////////

void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam

{

	int channelIndex = evnt0;

	int noteIndex = evnt1;

	unsigned char value = evnt2;


	// _COLOR_OFF 			0x00	00000000

	// _COLOR_RED 			0x10	00010000

	// _COLOR_GREEN 		0x20	00100000

	// _COLOR_BLUE 			0x40	01000000

	// _COLOR_CYAN 			0x60	01100000

	// _COLOR_MAGENTA 		0x50	01010000

	// _COLOR_YELLOW 		0x30	00110000

	// _COLOR_WHITE 		0x70	01110000


	/*if (channelIndex >= 0 && channelIndex < 8)

	{

		if ( noteIndex > _NOTE_RECEIVE_OFFSET && noteIndex < _NOTE_RECEIVE_OFFSET +8 )

		{

			matrix[noteIndex-_NOTE_RECEIVE_OFFSET][channelIndex] = value ;

		}

	}*/

}


/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS when a MIDI event has been received

// which has been specified in the MIOS_MPROC_EVENT_TABLE

/////////////////////////////////////////////////////////////////////////////

void MPROC_NotifyFoundEvent(unsigned entry, unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam

{

}


/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS when a MIDI event has not been completly

// received within 2 seconds

/////////////////////////////////////////////////////////////////////////////

void MPROC_NotifyTimeout(void) __wparam

{

}


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 => http://www.midibox.org/forum/index.php/topic,12786.0.html

	static unsigned char row;

 static unsigned char lastrow;

	unsigned int x; 							

	row = ++row & 0x07; 						// 8 cycle = 6.25% duty cycle


	MIOS_DOUT_PinSet0(lastrow); // row driver pin of last row on pulled OFF

	MIOS_DOUT_PinSet1(row);						// row driver pin #row ON


	for (x = 0; x < 8; x++)

	{

		DisplayLED(x , matrix[row][x]);			// for the row row, cycle all column

	}

 lastrow = row;

}


/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS after the shift register have been loaded

/////////////////////////////////////////////////////////////////////////////

void SR_Service_Finish(void) __wparam

{

}


/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS when an button has been toggled

// pin_value is 1 when button released, and 0 when button pressed

/////////////////////////////////////////////////////////////////////////////

void DIN_NotifyToggle(unsigned char pin, unsigned char pin_value) __wparam

{

 // a button has been pressed, send Note at channel 1

 // MIOS_MIDI_BeginStream();

 // MIOS_MIDI_TxBufferPut(0x90); // Note at channel 1

 // MIOS_MIDI_TxBufferPut(pin); // pin number corresponds to note number

 // MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // buttons are high-active

 // MIOS_MIDI_EndStream();


	unsigned char channel;

	unsigned char note;

	channel = button_event_map[pin][0];

	note = button_event_map[pin][1];



	if (pin_value == 0)

	{

		if (clipButtons[channel] != 0)

		{

			return;

		}

		clipButtons[channel] = 1;

	}

	else

	{

		clipButtons[channel] = 0;

	}



	MIOS_MIDI_BeginStream();

	MIOS_MIDI_TxBufferPut(channel); // first value from table = CHANNEL

	MIOS_MIDI_TxBufferPut(note); // second value from table = NOTE

	MIOS_MIDI_TxBufferPut(pin_value ? 0x00 : 0x7f); // 1

	MIOS_MIDI_EndStream();


 // notify display handler in DISPLAY_Tick() that DIN value has changed

 last_din_pin = pin;

 app_flags.DISPLAY_UPDATE_REQ = 1;

}


/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS when an encoder has been moved

// incrementer is positive when encoder has been turned clockwise, else

// it is negative

/////////////////////////////////////////////////////////////////////////////

void ENC_NotifyChange(unsigned char encoder, char incrementer) __wparam

{

}


/////////////////////////////////////////////////////////////////////////////

// This function is called by MIOS when a pot has been moved

/////////////////////////////////////////////////////////////////////////////

void AIN_NotifyChange(unsigned char pin, unsigned int pin_value) __wparam

{

 // // a pot has been moved, send CC#<pin-number> at channel 1

 // MIOS_MIDI_BeginStream();

 // MIOS_MIDI_TxBufferPut(0xb0); // CC at channel 1

 // MIOS_MIDI_TxBufferPut(pin); // pin number corresponds to CC number

 // MIOS_MIDI_TxBufferPut(MIOS_AIN_Pin7bitGet(pin)); // don't send 10bit pin_value, but 7bit value

 // MIOS_MIDI_EndStream();

 // send mapped CC value

 MIOS_MIDI_BeginStream();

 MIOS_MIDI_TxBufferPut(pot_event_map[pin][0]); // first value from table

 MIOS_MIDI_TxBufferPut(pot_event_map[pin][1]); // second value from table

 MIOS_MIDI_TxBufferPut(MIOS_AIN_Pin7bitGet(pin)); // 7bit pot value

 MIOS_MIDI_EndStream();


 // notify display handler in DISPLAY_Tick() that AIN value has changed

 last_ain_pin = pin;

 app_flags.DISPLAY_UPDATE_REQ = 1;

}


void ClearMatrix(void) __wparam

{

	unsigned int column = 0;

	unsigned int row = 0;

			for (row = 0; row < 8; row++)

			{

				for (column = 0; column < 8; column++)

				{

					matrix[row][column] = _COLOR_OFF;

				}

			}

}

Indeed, it is the same code used by noofny/mike with his common cathode matrix.

but the hardware matches this code too, no?

if someone could help me . . . :)

Edited by protofuse
  • Like 1
Link to comment
Share on other sites

I retested.

1) I tried 10ms and this code: a static light pattern for the led.

I only post Init() and SR_Service_Prepare() :

void Init(void) __wparam
{
  // configure the core1 as midibox-link FORWARD Point
  // see infos about midibox-link here: http://www.ucapps.de/midibox_link.html
  MIOS_MIDI_MergerSet(MIOS_MIDI_MERGER_MBLINK_EP);

  // set shift register update frequency
  MIOS_SRIO_UpdateFrqSet(10); // ms

  // we need to set at least one IO shift register pair
  MIOS_SRIO_NumberSet(NUMBER_OF_SRIO);

  // debouncing value for DINs
  MIOS_SRIO_DebounceSet(DIN_DEBOUNCE_VALUE);

  MIOS_SRIO_TS_SensitivitySet(DIN_TS_SENSITIVITY);

  // initialize the AIN driver
  MIOS_AIN_NumberSet(AIN_NUMBER_INPUTS);
#if AIN_MUXED_MODE
  MIOS_AIN_Muxed();
#else
  MIOS_AIN_UnMuxed();
#endif
  MIOS_AIN_DeadbandSet(AIN_DEADBAND);

	// all pin of row driver low
		MIOS_DOUT_SRSet(0, 0);
		MIOS_DOUT_SRSet(1, 0);
		MIOS_DOUT_SRSet(2, 0);
		MIOS_DOUT_SRSet(3, 0);


}
void SR_Service_Prepare(void) __wparam
{
		MIOS_DOUT_PinSet(2+8,	 0x01);
		MIOS_DOUT_PinSet(2+8+8,	 0x01);
		MIOS_DOUT_PinSet(2+8+8+8,0x01);

		MIOS_DOUT_PinSet(7+8,	 0x00);
		MIOS_DOUT_PinSet(7+8+8,	 0x01);
		MIOS_DOUT_PinSet(7+8+8+8,0x01);

}

ok it works!

no cycle, all hardcoded.

2) the same light pattern in init() and not in ISR

it works too.

but the code posted in the first post doesn't work anymore

any ideas?

even with update SR refresh is 1ms or 10ms ... etc.. all the same.

Link to comment
Share on other sites

with the following code, it works fine and fast (no flickering...etc)

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 => http://www.midibox.org/forum/index.php/topic,12786.0.html
	static unsigned char row;
	static unsigned char lastrow;
	unsigned int x;

	row = ++row & 0x07;						// 8 cycle = 6.25% duty cycle

	//MIOS_DOUT_SRSet(0, 0);
	MIOS_DOUT_PinSet0(lastrow);					// lastrow ON made OFF
	MIOS_DOUT_PinSet1(row);						// row driver pin #row ON

	for (x = 0; x < 8; x++)
	{
		//DisplayLED(x , matrix[row][x]);			// for the row row, cycle of all column
		MIOS_DOUT_PinSet(x+8+8,	 0x01);
		MIOS_DOUT_PinSet(x+8+8+8,0x01);
	}
	lastrow = row;
}
So I guess the problem comes from the DisplayLED() parser. Indeed, in the ISR, I'm calling this function to parse the following "lookup table" :
// we create a 2-dimensional array with 64 entries for led color storage for the clip matrix controller part
// each entry consists of 1 byte coded like that:
// 0x00 = OFF
// 0x10 = RED
// 0x20 = GREEN
// 0x40 = BLUE
// 0x30 = RED + GREEN =  YELLOW
// 0x60= GREEN + BLUE = CYAN
// 0x50 = RED + BLUE = MAGENTA
// 0x70 = WHITE
// The meaning of the bytes can be found in the MIDI spec
// (-> http://www.harmony-central.com/MIDI/Doc/table1.html)
// (-> http://www.harmony-central.com/MIDI/Doc/table2.html)
// (-> http://www.harmony-central.com/MIDI/Doc/table3.html)
//
// structure is matrix[ROW][COLUMN]=COLOR
static unsigned char matrix[8][8] = {
		  {0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10},
		  {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},
		  {0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30},
		  {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40},
		  {0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50},
		  {0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60},
		  {0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70},
		  {0x00,0x30,0x00,0x50,0x00,0x70,0x00,0x00}
  };

unsigned char isn't probably the good type... am I right?

the result of (color & 0x01) seems to be 0 everytime ...(or something ^= 1) (where color = an element of the matrix[][] lookup table.

if someone could guide me, it would be very appreciated :)

Link to comment
Share on other sites

I don't know exactly what you're trying to achieve with this code, but it is quite certain that it can't work, since you're doing basically 0xn0 & 1 (where n i a number between 0 and F), and this is always equal to 0. In my opinion, the problem is not the type (unsigned char), which is quite fine, but either the values in your matrix or the "& 1" operation you're applying.

(to understand better this "0xn0 & 1" thing, consider that doing "& 1" is asking if the number is odd -impair in french-, and you're asking this of a number that is a multiple of 16, so no, it's never odd)

Link to comment
Share on other sites

My mistake, I hadn't noticed the shifting.

So I guess the code does pretty much what you say, i.e. you get 1 for every other row in your matrix.

Arrays of arrays are always a pain to manage. Could it be that you're accessing it wrongly? Have you tried inverting the elements and calling this instead?

DisplayLED(x , matrix[x][row]);

Link to comment
Share on other sites

unfortunately, I don't have any 18F452 to test if it is a processor type problem (it would be weird but when we test, we have to test ALL)

PROBLEM DATA

- I have a Lookup Table (LUT)  which I convert to 1-dimension (C ansi only specifies that and multi-dimensional array are weird - thanks lucem to be my spiritual code guide)

// 0x00 = OFF
// 0x10 = RED
// 0x20 = GREEN
// 0x40 = BLUE
// 0x30 = RED + GREEN =  YELLOW
// 0x60= GREEN + BLUE = CYAN
// 0x50 = RED + BLUE = MAGENTA
// 0x70 = WHITE
static unsigned char matrix[64] = {
		   0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
		   0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
		   0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,
		   0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
		   0x50,0x50,0x50,0x50,0x50,0x50,0x50,0x50,
		   0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,
		   0x70,0x70,0x70,0x70,0x70,0x70,0x70,0x70,
		   0x00,0x30,0x00,0x50,0x00,0x70,0x00,0x00
  };
- I have a function to parse this LUT : DisplayLED()
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
}
- I have a SR_Service_Prepare() that called cyclically the LUT parser:
void SR_Service_Prepare(void) __wparam
{
	// HELPED BY BUGFIGHT => http://www.midibox.org/forum/index.php/topic,12786.0.html
	static unsigned char row;
	static unsigned char lastrow;
	unsigned int x;

	row = ++row & 0x07;	// 8 cycle = 6.25% duty cycle

	MIOS_DOUT_PinSet0(lastrow);    // lastrow OFF
	MIOS_DOUT_PinSet1(row);        // current row ON

	for (x = 0; x < 8; x++)
	{
		DisplayLED(x , matrix[x+row*8]);    // for the row row, cycle of all column
	}
	lastrow = row;
}

TEST RESULTS

this code doesn't light up any led.

if I replace DisplayLED(x , matrix[x+row*8]); in the ISR by DisplayLED(x , 0x10);, all the matrix is RED, without any flickering, and it is beautiful :)

Of course, if I replace it by 0x20, or 0x50 etc ... it works fine with the correct color !

CONCLUSION

the LUT parser doesn't work and I really don't know why !!!

I have no warning at the compilation state. nothing strange appears.

I tried to force unsigned char cast but it is all the same.

Is it a function call problem? a type problem? a curse problem ? ;)

How could I make it working?

I add one question:should I recompile the 18F4620 libs for sdcc ?

Link to comment
Share on other sites

common anode matrix rgb led driver ...

- row (anodes) driver is SR + resistor 1k + transistor BC547 used as a switch to source 5V to rows..

OK, so I have no time to read the code, and I'm feeling more like a hardware guy this week anyway.

But the above statement has a problem..

A "common anode" LED matrix requires some sort of driver to supply +5 volts to each row(or column, if you turn it sideways) This will be more current than a PIC pin (or DOUT pin) can usually handle. so far, so good.

In the case (rough example) of an 8X8 RGB matrix, up to 24 LEDs in each row(column) may be lit at once, requiring maybe 20 ma X 24 = 480 ma (1/2 amp). So you'll certainly need a driver there.

My problem.. you said "BC547", which seems to be a NPN transistor. Since it is supplying the + side, I would expect a PNP transistor there, unless you're playing some weird biasing tricks.

Normally, (a truly dangerous word around here) NPN transistors provide a switch on the LOW side of the circuit, and a PNP is a "high side" switch. Or simplified, NPN is negative, and PNP is positive.

So either you quoted the wrong number, or I'm confused, or we just found the problem in hardware!

Hey, I could be all wrong here.. but it might be worth checking out.

Have Fun,

LyleHaze

Link to comment
Share on other sites

lylehaze, here is the diagram attached.

we discussed with lucem about that, as I didn't use BC547 before...

I rewrite: without using the Lookup table, all (seems) to work fine.

I mean: I can light up x,y led, I can "choose" the color etc.

So, considering that, could it be a NPN/PNP problem?

I mean, if it was, nothing wouldn't work no?

5761_1489d8624bc0a0673f172ff10524cc49595

Edited by protofuse
Link to comment
Share on other sites

The BC547 will work okay here, because the necessary voltage drop from base to emitter of apprix. .7V does not pose a problem, as in the collector-emitter track

about the same voltage is lost even in switch mode; so, one can expect to deliver about 4.3V to the resistor / LED combination, which is even enough for blue LEDs.

I really think there is a problem with his software, but unfortunately I haven't had time yet to look into it.

Link to comment
Share on other sites

Ok.

thanks lucem for your confirmation.

as I wrote, indeed, if I replace the DisplayLED() call by directly MIOS_DOUT_PinSet() correclty feeded by SR pin values, I see blue, red, green, red +blue etc etc

all is fine, stable, no flickering.

no strange current problem etc etc!

the problem is the parsing of my unsigned char lookup table  ??? ??? ??? ??? ??? ??? ??? ??? ???

I'm stuck ...

Link to comment
Share on other sites

With

static unsigned char matrix[64] = ...
your LUT will be located in RAM (the keyword "static" will make the variable local, it doesn't lead to a constant). So far I remember, RAM areas won't be preloaded automatically by the SDCC wrapper. But using (expensive) RAM isn't the right choice anyhow, it's better to store the table in flash. This should be the case if you are writing:
const unsigned char matrix[64] = ...

Best Regards, Thorsten.

Link to comment
Share on other sites

I have to add something:

noofny/mike and I use a very similar code (mine is inspired by his one)

here on his site: http://www.noofny.net/files/ain64_din128_dout128_v2b_CORE_1.zip, we can find the code for one of his core.

- his LUT is static

- he uses the ISR to display led by calling DisplayLED() function

and it works fine for him.

I'm really stuck.

I'd like to test things, but I don't know what to test now.

should I rebuild my toolchain?

should I rebuild processor specific *.lib?

should I burn all ?  :o :o

Link to comment
Share on other sites

- his LUT is static

- he uses the ISR to display led by calling DisplayLED() function

and it works fine for him.

Yes, because his array is preloaded with zeroes:

static unsigned int clipButtons[8] = { 0,0,0,0,0,0,0,0 };

and this is the default state after MIOS reset.

As already assumed, an array located in RAM won't be preloaded.

There are two solutions:

- either you preload it inside your application from a const table to your RAM table (thats a simple for-i loop in the Init() hook!)

- or you search for code in the internet (or SDCC repository) which is doing the copy operation from the C startup routine (I saw something like this in the past, but don't remember where)

Anyhow, I think that the first option should give you a working result in 1 minute!

should I burn all ?  :o :o

Haha! ;)

Best Regards, Thorsten.

Link to comment
Share on other sites

I guess it isn't a bug, but a thing to know/learn.

I only booted and waited for light... the matrix was initialized with 0, and never been modified cause I just waited for ...

const are loaded.

static aren't.

If I had tested by sending midi notes, the protodeck would have answer by lighting up led...

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...
×
×
  • Create New...