[how-to// TK!] blinking led

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?

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 :slight_smile:

best,

Michael

hello michael,

no prob for switch on & off.

I’ll try to do that and post it if I succeed :slight_smile:

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 != 0x00 && matrixBlinkState == 0x01 =======> blinking!

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

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;  
  
 &nbsp; &nbsp;for(sr=0; sr\<16; ++sr)  
 &nbsp; &nbsp; &nbsp;MIOS\_DOUT\_SRSet(sr, MIOS\_DOUT\_SRGet(sr) ^ flash\_pattern[sr]);  
 &nbsp;}  
}  

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]  
 &nbsp;flash\_pattern[dout\_pin \>\> 3] &= MIOS\_HLP\_GetBitANDMask(dout\_pin);  

Have fun by doing some more experiments! :slight_smile:

Best Regards, Thorsten.

Thorsten…

what a big and precise answer!

I’ll test it as soon as I had my AIN/Pots problem solved!

I’ll put it in the protodeck post.

of course, I have to thank you a lot for me … and for us!

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?

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;
}