Jump to content

[how-to// TK!] blinking led


protofuse
 Share

Recommended Posts

I'd like to make some led blinking.

the most efficient way : doing that in the firmware (and not with an artificial note-on note-off message from the software interface to the device via midi......)

I searched, I looked for that: http://www.midibox.o...index.php/topic,8456.msg60753.html#msg60753

1st question: can I mix asm and C naturally? I'm not sure. if yes, how I could put that in my code?

2nd question: how should I code that? I mean, should I use a particular value of a midi note on byte (velocity=xx) to make the led blinking?

my matrix coding is:

// we create a 1-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[COLUMN + 8*ROW]=COLOR

static unsigned char matrix[64] = {

		0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,

		0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,

		0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,

		0x50,0x10,0x10,0x10,0x10,0x10,0x10,0x10,

		0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,

		0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,

		0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,

		0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10

};

it is the lookup table parsed every SRIO cycle.

I could use another matrix as a kind of masking blinking state.

if value is 0, the led is solid state

if value is 1, the led is blinking (OFF/COLOR/OFF/COLOR etc etc)

how could I do that?

Edited by protofuse
Link to comment
Share on other sites

Hi protofuse,

1st question: can I mix asm and C naturally? I'm not sure. if yes, how I could put that in my code?

you can use plain asm code within your C code (though you cannot add C code to an asm-based project) :

http://www.midibox.org/dokuwiki/doku.php?id=how_to_mix_c_and_asm

2nd question: how should I code that? I mean, should I use a particular value of a midi note on byte (velocity=xx) to make the led blinking?

the most useful tip in the thread you mentioned came from mess:

if you want the timer to do this

*first step is to initialise the timer, call  MIOS_TIMER_Init

(see http://www.ucapps.de/mios_fun.html for more info on how to use this function)

*next put your blink code in USER_Timer

do you have experience with assembler coding?

otherwise it would be easier to do this in C

refer to the MIOS C function reference to learn how to switch your pins on and off. It should be fairly simple :-)

best,

Michael

Link to comment
Share on other sites

I have little problem with

- definition of LX_xxx

- some "opcode" give error ( rgoto ...)

- Symbol not previously defined (MIOS_DOUT_PinSet1) and for other call

and, I don't know how I can use it with my code.

I mean: I have a matrix[] that stores led state (off and colors)

I think about another array: matrixBlinkState[] where 0=solid, 1=blinking

if matrix[x] != 0x00 && matrixBlinkState[x] == 0x01 =======> blinking!

how could I do that using this timer, which, I suppose, makes the blinking rate ?

Link to comment
Share on other sites

It is neither required to use a timer, nor to program this in assembly code.

Just use the SR_Service_Prepare() hook, which is called each mS before the shift registers are loaded.

Inside this hook, use a counter (a global variable), whenever it reaches a certain value (e.g. 200 for a 200 mS delay), apply an inversion pattern on all DOUT bits which should flash.

Step by step (in the hope that it's understandable):

define a global variable somewhere in the header of your application:


// 8bit variable (range: 0..255)
unsigned char flash_ctr;
[/code] And insert following code into the ServicePrepare hook:
[code]
void SR_Service_Prepare(void) __wparam
{
 if( ++flash_ctr >= 200 ) {
   flash_ctr = 0;

   MIOS_DOUT_SRSet(0, MIOS_DOUT_SRGet(0) ^ 0x01);
 }
}
This will:   - read the 8bit value of the first shift register (#0)   - XOR the value with 0x01 (means: first DOUT pin will be toggled)   - write back the value into the first shift register   - this will be done each 200 mS Examples for XOR patterns: 0x01: will toggle 1st LED 0x02: will toggle 2nd LED 0x04: will toggle 3rd LED 0x08: will toggle 4th LED 0x10: will toggle 5th LED 0x20: will toggle 6th LED 0x40: will toggle 7th LED 0x80: will toggle 8th LED To toggle multiple LEDs, just OR the values, e.g.: (0x01 | 0x80): will toggle the 1st and 8th LED The brackets are important!!! Or if you got practice, just write this into a single value without OR operation: 0x55: will toggle 1st, 3rd, 5th and 7th LED Ok, now you want to make the flash pattern variable and control it from another MIDI device. Define another global variable:

unsigned char flash_pattern;
[/code] (initialize it with 0x00 in the Init() hook) Modify the SR_Service_Prepare() hook the following way:
[code]
void SR_Service_Prepare(void) __wparam
{
 if( ++flash_ctr >= 200 ) {
   flash_ctr = 0;

   MIOS_DOUT_SRSet(0, MIOS_DOUT_SRGet(0) ^ flash_pattern);
 }
}
Thats all. Now you can set a specific bit of the 8bit pattern (e.g. from the MPROC_NotifyReceivedEvnt() hook when a certain MIDI event has been received) with:

 // it is assumed that dout_pin is in the range of 0..7
 flash_pattern |= MIOS_HLP_GetBitORMask(dout_pin);
[/code] and you can clear it with:
[code]
 flash_pattern &= MIOS_HLP_GetBitANDMask(dout_pin);
Next step: you want to flash more than 8 LEDs - it's time to use an array, e.g.:

// prepared for all 128 DOUT pins
unsigned char flash_pattern[16];
[/code] (initialize all array elements with 0x00 in the Init() hook) Modify the SR_Service_Prepare() hook the following way:
[code]
void SR_Service_Prepare(void) __wparam
{
 unsigned char sr;

 if( ++flash_ctr >= 200 ) {
   flash_ctr = 0;

   for(sr=0; sr<16; ++sr)
     MIOS_DOUT_SRSet(sr, MIOS_DOUT_SRGet(sr) ^ flash_pattern[sr]);
 }
}
Setting/clearing a specific bit will require following code:

 // it is assumed that dout_pin is in the range of 0..127
 flash_pattern[dout_pin >> 3) |= MIOS_HLP_GetBitORMask(dout_pin);
[/code] and you can clear it with:
[code]
 flash_pattern[dout_pin >> 3] &= MIOS_HLP_GetBitANDMask(dout_pin);

Have fun by doing some more experiments! :)

Best Regards, Thorsten.

Link to comment
Share on other sites

Thorsten,

I'm including this code before making my 1st test.

Indeed, I'd like to control it with another midi device.

I'm a little bit stuck cause I'm using RGB led.

Could you help me?

I'm using a lookup table:

static unsigned char matrix[64] ;
I feed it with MPROC_NotifyReceivedEvnt() function:
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
	int channelIndex = evnt0-0x90;
	int noteIndex = evnt1;
	unsigned char value = evnt2;
	matrix[8*(noteIndex - 1 - _NOTE_MATRIX_OFFSET)+channelIndex] = value; //-1 cause note begin at 1 and row at 0
}
I read it with SR_Service_Prepare()
void SR_Service_Prepare(void) __wparam
{
	static unsigned int row;
	static unsigned int lastrow;
	unsigned int x;

	row = ++row & 0x07;				// row cycling
	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]);	// displaying the led (x,row)
	}
	lastrow = row;
}
and the parsing function is DisplayLED:
void DisplayLED(unsigned int 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);  // GREEN
	color >>= 1;
	MIOS_DOUT_PinSet(column+8+8+8,	color & 0x01); // BLUE
}

could you help me?

Link to comment
Share on other sites

ok TK.

I think I have the right code (I'm doing a pause at work, so I cannot test right now)

I define these before Init()

unsigned char matrixBlinkingState[64] ;
unsigned char flash_ctr;
I fill these matrixBlinkingState with 0x00 in Init() cause nothing blinks at the beginning
unsigned int index;
for (index = 0; index < 8; index++)
{
	matrixBlinkingState[index] = 0x00 ;
}

DisplayLED hasn't been changed.
/////////////////////////////////////////////////////////////////////////////
// This function is called by SR_Service_Prepare, decompose color component and UP the right rgb pins
/////////////////////////////////////////////////////////////////////////////
void DisplayLED(unsigned int column, unsigned char color) __wparam
{
	color >>= 4;
	MIOS_DOUT_PinSet(column+8,		(unsigned char)(color & 0x01));  // RED
	color >>= 1;
	MIOS_DOUT_PinSet(column+8+8,	(unsigned char)(color & 0x01)); // BLUE
	color >>= 1;
	MIOS_DOUT_PinSet(column+8+8+8,	(unsigned char)(color & 0x01));	// GREEN
}
I put the counter incrementation outside of the for loop in order to keep it consistent... the if/test can really be improved I'll do it asap with bitmask etc as you did.. but I have to figure out how I can do that in my case.
void SR_Service_Prepare(void) __wparam
{
	static unsigned int row;
	static unsigned int lastrow;
	unsigned int x;

	row = ++row & 0x07;						// row cycling
	MIOS_DOUT_PinSet0(lastrow);				// lastrow OFF
	MIOS_DOUT_PinSet1(row);					// current row ON

	for (x = 0; x < 8; x++)
	{
		if( flash_ctr >= 200 ) {
			flash_ctr = 0;
			if (matrixBlinkingState[x+row*8] == 0x00) DisplayLED(x , matrix[x+row*8]);	// displaying the led (x,row)
			else DisplayLED(x , 0x00);			// OFF this led cause it blinks
		}
	}
	lastrow = row;
	flash_ctr++;
}
I control blinking state with velocity: 0x7E means solid state, 0x7F means blink state.
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
	int channelIndex = evnt0-0x90;
	int noteIndex = evnt1;
	unsigned char value = evnt2;

	if (value != 0x7E || value != 0x7F)
		matrix[8*(noteIndex - 1 - _NOTE_MATRIX_OFFSET)+channelIndex] = value; //-1 cause note begin at 1 and row at 0

	else if (value == 0x7F) // value = 0x7F means blinking state ON
		matrixBlinkingState[8*(noteIndex - 1 - _NOTE_MATRIX_OFFSET)+channelIndex] = 0x01;

	else (value == 0x7E) // value = 0x7E means blinking state OFF
		matrixBlinkingState[8*(noteIndex - 1 - _NOTE_MATRIX_OFFSET)+channelIndex] = 0x00;
}

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...