Jump to content

4x16 (8x8) Button/Duo-LED programming example


TK.
 Share

Recommended Posts

...

What is the most efficient way to do this so that my rows go 0,1,2,3,4,5,6,7 instead of 0,2,4,6,1,3,5,7?

do you only want the row numbers changed on the lcd? that's pretty simple.

to get the pins and notes to map in that order is a little more involved,

but not too bad.  that is the way i think i will eventually go...

Link to comment
Share on other sites

to get the pins and notes to map in that order is a little more involved,

but not too bad.  that is the way i think i will eventually go...

I got this to work, I'm sure it could be done in a better way though. I just used a couple arrays to map the notes and the rows and it works for now.

Luke

Link to comment
Share on other sites

ok "soon" actually was soon in this case.

i haven't checked this into svn, (tk let me know if you want me to...)

but it is tested and working on my hardware.

i'm not sure "descramble" is the best choice for naming it, though...

here are the changes.

in main.h i added:

#define BLM_DESCRAMBLE_ROWS 1 //set this to 0 for 4x16 (like MB_Seq) and 1 for 8x8
the rest of the changes are in main.c in Global variables, i added:
#if BLM_DESCRAMBLE_ROWS
unsigned char blm_button_row_dscrmbl;
#endif
in DISPLAY_Tick(), i replaced   
MIOS_LCD_PrintBCD3(blm_button_row);:
with

#if BLM_DESCRAMBLE_ROWS
  MIOS_LCD_PrintBCD3(blm_button_row_dscrmbl);
#else
  MIOS_LCD_PrintBCD3(blm_button_row);
#endif
here is the entire MPROC_NotifyReceivedEvnt() which contains the scramble code: i also corrected an error in local vars where led_column and led_row were reversed...
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
  unsigned char led_column;
  unsigned char led_row;
  unsigned char evnt1Adj;
  unsigned char btnVal;

  // control the Duo-LEDs via Note On/Off Events
  // The colour is controlled with velocity value:
  // 0x00:       both LEDs off
  // 0x01..0x3f: green LED on
  // 0x40..0x5f: red LED on
  // 0x60..0x7f: both LEDs on

  // only MIDI note numbers from 0x00..0x3f are valid (-> 64 LEDs)

  evnt1Adj = (evnt1 - BLM_MIDI_STARTNOTE) & 0x7f;
  if( (evnt0 == 0x80 || evnt0 == 0x90) && (evnt1Adj < 0x40 ) ) {

    // derive LED column and row from note number
    
    led_column = evnt1Adj & 0x07;
#if BLM_DESCRAMBLE_ROWS
    //scramble the rows, NOTE: this method is not scalable
    blm_button_row_dscrmbl = evnt1Adj >> 3;
    led_row = blm_button_row_dscrmbl;

    led_row <<= 1;
    if(led_row & 0x08) {
      led_row &= 0x07;
      led_row++;
    }
#else
    led_row = evnt1Adj >> 3;
#endif

    // 90 xx 00 is the same like a note off event!
    // (-> http://www.borg.com/~jglatt/tech/midispec.htm)
    if( evnt0 == 0x80 || evnt2 == 0x00 ) 
    {
      // Note Off or velocity == 0x00: clear both LEDs
      blm_row_green[led_row] &= MIOS_HLP_GetBitANDMask(led_column);
      blm_row_red[led_row]   &= MIOS_HLP_GetBitANDMask(led_column);

      btnVal = 1;
    } 
    else 
    {
      btnVal = 0;

      if( evnt2 < 0x40 ) {
        // Velocity < 0x40: set green LED, clear red LED
        blm_row_green[led_row] |= MIOS_HLP_GetBitORMask(led_column);
        blm_row_red[led_row]   &= MIOS_HLP_GetBitANDMask(led_column);

      } else if( evnt2 < 0x60 ) {
        // Velocity < 0x60: clear green LED, set red LED
        blm_row_green[led_row] &= MIOS_HLP_GetBitANDMask(led_column);
        blm_row_red[led_row]   |= MIOS_HLP_GetBitORMask(led_column);
      } else {

        // Velocity >= 0x60: set both LEDs
        blm_row_green[led_row] |= MIOS_HLP_GetBitORMask(led_column);
        blm_row_red[led_row]   |= MIOS_HLP_GetBitORMask(led_column);
      }
    }

    // enable this code (turn #if 0 into #if 1) if midi notes should change the LCD display
    // disable it when LCD should only be affected via buttons
#if 1
    blm_button_row = led_row;
    blm_button_column = led_column;
    blm_button_value = btnVal;
    // request display update
    app_flags.DISPLAY_UPDATE_REQ = 1; 
#endif
  }
}

here is the entire BLM_NotifyToggle() which contains the descramble code:
void BLM_NotifyToggle(unsigned char pin, unsigned char value) __wparam
{
  unsigned char mask;
  unsigned char noteNumber;
  
#if BLM_DESCRAMBLE_ROWS
  //convert blm_button_row to blm_button_row_dscrmbl.  NOTE: this method is not scalable
  blm_button_row_dscrmbl = blm_button_row >> 1;
  if( 0x01 & blm_button_row ) //if row is odd number
    blm_button_row_dscrmbl |= 0x04; //
  noteNumber = ((blm_button_row_dscrmbl << 3) + blm_button_column + BLM_MIDI_STARTNOTE) & 0x7f;
#else
  noteNumber = (pin + BLM_MIDI_STARTNOTE) & 0x7f;
#endif
  
  // send pin number and value as Note On Event
  MIOS_MIDI_TxBufferPut(0x90);
  MIOS_MIDI_TxBufferPut(noteNumber);
  MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);

  // enable this code (turn #if 0 into #if 1) if buttons should change the LED colour directly
  // disable it when LEDs should only be controlled via MIDI
#if 1
  // cycle colour whenever button has been pressed (value == 0)
  if( !value ) {
    mask = MIOS_HLP_GetBitORMask(blm_button_column);
    if ( blm_row_green[blm_button_row] & mask )
       blm_row_red[blm_button_row] ^= mask;
    blm_row_green[blm_button_row] ^= mask;
  }
#endif
  // request display update
  app_flags.DISPLAY_UPDATE_REQ = 1;
}

Link to comment
Share on other sites

  • 1 month later...

has someone done something about RGB leds ?

How do you manage this part of the code :

/////////////////////////////////////////////////////////////////////////////
//  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
{
  unsigned char evnt1Adj;
  unsigned char led_column;
  unsigned char led_row;


  // control the Duo-LEDs via Note On/Off Events
  // The colour is controlled with velocity value:
  // 0x00:       both LEDs off
  // 0x01..0x3f: green LED on
  // 0x40..0x5f: red LED on
  // 0x60..0x7f: both LEDs on

  // only MIDI note numbers from 0x00..0x3f are valid (-> 64 LEDs)
  evnt1Adj = ((evnt1 - 24) & 0x7f);
  if( (evnt0 == 0x80 || evnt0 == 0x90) && (evnt1Adj < 0x40 ) ) {

    // derive LED column and row from note number
    led_column = evnt1Adj >> 3;
    led_row = evnt1Adj & 0x07;

    // 90 xx 00 is the same like a note off event!
    // (-> http://www.borg.com/~jglatt/tech/midispec.htm)
    if( evnt0 == 0x80 || evnt2 == 0x00 ) {

      // Note Off or velocity == 0x00: clear both LEDs
      blm_row_green[led_column] &= MIOS_HLP_GetBitANDMask(led_row);
      blm_row_red[led_column]   &= MIOS_HLP_GetBitANDMask(led_row);

    } else if( evnt2 < 0x40 ) {

      // Velocity < 0x40: set green LED, clear red LED
      blm_row_green[led_column] |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_red[led_column]   &= MIOS_HLP_GetBitANDMask(led_row);

    } else if( evnt2 < 0x60 ) {

      // Velocity < 0x60: clear green LED, set red LED
      blm_row_green[led_column] &= MIOS_HLP_GetBitANDMask(led_row);
      blm_row_red[led_column]   |= MIOS_HLP_GetBitORMask(led_row);

    } else {

      // Velocity >= 0x60: set both LEDs
      blm_row_green[led_column] |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_red[led_column]   |= MIOS_HLP_GetBitORMask(led_row);

    }
  }

}

and this one :
/////////////////////////////////////////////////////////////////////////////
// This function is NOT called by MIOS, but by the scan matrix handler
// in blm.asm, when a pin of the scan matrix has been toggled
// Note: in addition to "pin" and "value", the "blm_button_column" and
// "blm_button_row" are available as global variables (defined in blm.h)
/////////////////////////////////////////////////////////////////////////////
void BLM_NotifyToggle(unsigned char pin, unsigned char value) __wparam
{
  unsigned char mask;

  // send pin number and value as Note On Event
  MIOS_MIDI_TxBufferPut(0x90);
  MIOS_MIDI_TxBufferPut((pin + 24) & 0x7f);
  MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);


  // enable this code (turn #if 0 into #if 1) if buttons should change the LED colour directly
  // disable it when LEDs should only be controlled via MIDI
#if 1
  // cycle colour whenever button has been pressed (value == 0)
  if( !value ) {
      mask = MIOS_HLP_GetBitORMask(blm_button_column);
      if ( blm_row_green[blm_button_row] & mask )
        blm_row_red[blm_button_row] ^= mask;
        blm_row_green[blm_button_row] ^= mask;
        
      if ( blm_row_blue[blm_button_row] & mask )
        blm_row_red[blm_button_row] ^= mask;
        blm_row_blue[blm_button_row] ^= mask;
        
      if ( blm_row_red[blm_button_row] & mask )
        blm_row_blue[blm_button_row] ^= mask;
        blm_row_red[blm_button_row] ^= mask;
//        blm_row_blue[blm_button_row] ^= mask;
               
  }
/*
&= (Bitwise AND EQUALS) 
Performs a bitwise AND and sets the original value to the result.
^= (Bitwise Exclusive OR EQUALS) 
Performs a bitwise exclusive OR and sets the original value to the result.
|= (Bitwise OR EQUALS) 
Performs a bitwise OR and sets the original value to the result.  
*/

#endif

it is a bit complicted to understand for me  ???

Link to comment
Share on other sites

these are just example code for handling button presses and midi events.  you can do whatever you want there. 

the button handler just toggles thru the 4 possible (for 2 leds) led states.  if you want each button press to toggle thru the 8 possible led states for 3 leds, i can help out there, but i don't have hardware to test...

the midi handler just uses four ranges of note velocity to light the different led combos, so you would just use 8 velocity ranges instead...

edit* clarified (hopefully)...

Link to comment
Share on other sites

bugfight, thanks for your fast answer :)

i have understood the general goal of these 2 parts of the code (LED on corresponding to a certain velocity), and the cycling toggle function

I have tried some code but i have a problem caused by the Blue LED always on with the red or the blue ... ???

In the second part, I don't understand the deep function of "mask".

I have done the assembly of the sparkfun kits following the schematic of TK, and adding a third DOUT for the blue leds (like intellijel) ; i am also reusing the BLM.asm of intellijel as i have understood it manages well the 3 different colours.

If you have some time to make some code for the direct toggle of the colours by the buttons (if=1) I would be honored to test it.

For the moment, with this code, LEDs of the column cycle through the different colours, but not the LEDS of the pressed button ???

IMO, the best would be some explanations about the algo which is used : purpose of "mask", purpose of GetbitORMask, purpose of GetbitANDmask. It seems described by ASM lines in BLM.asm, unfortunatly it is rather complicated to me to understand it :( (i always had problem with Matrix in maths at university)

Thanks in advance to anybody who will demystify this ;)

Link to comment
Share on other sites

tk's docs describe the mask functions better than i could...

generally, we are using a mask to determine which bit in a byte to use for a column

ok, for starters i think this will toggle the blue correctly.  however if you are not using tk's blm example code, i think there may be an issue with the handler being called before blm_button_column being set (i vaguely remember sm_example doing this...)

also, you may want to switch red and green so the rgb values are in order...

anywayz you can try and see.

afterwards, i'll look at the midi handler.

  // enable this code (turn #if 0 into #if 1) if buttons should change the LED colour directly
  // disable it when LEDs should only be controlled via MIDI
#if 1
  // cycle colour whenever button has been pressed (value == 0)
  if( !value ) {
      mask = MIOS_HLP_GetBitORMask(blm_button_column);
      if ( blm_row_green[blm_button_row] & mask )
      {
           if ( blm_row_red[blm_button_row] & mask )
                 blm_row_blue[blm_button_row] ^= mask; //if red is changing to 0, toggle blue
           blm_row_red[blm_button_row] ^= mask; //if green is changing to 0, toggle red
      }
      blm_row_green[blm_button_row] ^= mask; //green toggles every time
  }
/*
&= (Bitwise AND EQUALS) 
Performs a bitwise AND and sets the original value to the result.
^= (Bitwise Exclusive OR EQUALS) 
Performs a bitwise exclusive OR and sets the original value to the result.
|= (Bitwise OR EQUALS) 
Performs a bitwise OR and sets the original value to the result.  
*/

#endif

Link to comment
Share on other sites

I still have troubles with this appli 

Now the toggling of LED is OK thanks to bugfight and the removing 0xf0 for sink drivers (i don't have transistors on my PCB) :

Code:

#if 1
  // cycle colour whenever button has been pressed (value == 0)
  if( !value ) {
      mask = MIOS_HLP_GetBitORMask(blm_button_column);
      if ( blm_row_green[blm_button_row] & mask )
      {
           if ( blm_row_red[blm_button_row] & mask )
                 blm_row_blue[blm_button_row] ^= mask; //if red is changing to 0, toggle blue
           blm_row_red[blm_button_row] ^= mask; //if green is changing to 0, toggle red
      }
      blm_row_green[blm_button_row] ^= mask; //green toggles every time
  }
/*
3 states cycle : red->blue->white->NA

      mask = MIOS_HLP_GetBitORMask(blm_button_column);
      if ( blm_row_red[blm_button_row] & mask )
      {
           if ( blm_row_green[blm_button_row] & mask )
                blm_row_blue[blm_button_row] ^= mask; //if red is changing to 0, toggle blue
                blm_row_green[blm_button_row] ^= mask; //if green is changing to 0, toggle red
      }
      blm_row_red[blm_button_row] ^= mask; //green toggles every time
  }
  */
I have done the management of LEDs by MIDI messages, and it works, except for the BLUE LED : 
Code:
/////////////////////////////////////////////////////////////////////////////
//  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
{
  unsigned char evnt1Adj;
  unsigned char led_column;
  unsigned char led_row;

  // control the Duo-LEDs via Note On/Off Events
  // The colour is controlled with velocity value:
  // 0     : all LEDs off
  // 01-10 : green LED on
  // 11-20 : red LED on
  // 21-30 : blue LED on
  // 31-40 : red+green LED on (= yellow)
  // 41-50 : green+blue LED on (= turquoise)
  // 51-60 : blue+red LED on (= purple)
  // 61-127 : all LEDs on (= white)
  // CLEAR  &=   AND
  // SET    |=   OR

  // only MIDI note numbers from 0x00..0x3f are valid (-> 64 LEDs)
  evnt1Adj = ((evnt1 - 24) & 0x7f);
  if( (evnt0 == 0x80 || evnt0 == 0x90) && (evnt1Adj < 0x40 ) ) {
    // derive LED column and row from note number
    led_column = evnt1Adj >> 3;
    led_row = evnt1Adj & 0x07;

    // 90 xx 00 is the same like a note off event!
    // (-> http://www.borg.com/~jglatt/tech/midispec.htm)
    if( evnt0 == 0x80 || evnt2 == 0x00 ) {
    
      // Note Off or velocity == 0x00: clear all LEDs
      blm_row_green[led_column] &= MIOS_HLP_GetBitANDMask(led_row);
      blm_row_red[led_column]   &= MIOS_HLP_GetBitANDMask(led_row);
      blm_row_blue[led_column]  &= MIOS_HLP_GetBitANDMask(led_row);
      
    } else if( evnt2 < 10 ) { // GREEN

      // Velocity < 10: set green LED, clear red LED, clear blue LED
      blm_row_green[led_column] |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_red[led_column]   &= MIOS_HLP_GetBitANDMask(led_row);
      blm_row_blue[led_column]  &= MIOS_HLP_GetBitANDMask(led_row);
      
    } else if( evnt2 < 20 ) { // RED

      // Velocity < 20: clear green LED, set red LED, clear blue led
      blm_row_green[led_column] &= MIOS_HLP_GetBitANDMask(led_row);
      blm_row_red[led_column]   |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_blue[led_column]  &= MIOS_HLP_GetBitANDMask(led_row);

    } else if( evnt2 < 30 ) { // BLUE

      // Velocity < 30 : clear green LED, clear red LED, set blue led
      blm_row_red[led_column]   &= MIOS_HLP_GetBitANDMask(led_row);
      blm_row_green[led_column] &= MIOS_HLP_GetBitANDMask(led_row);
      blm_row_blue[led_column]  |= MIOS_HLP_GetBitORMask(led_row);

    } else if( evnt2 < 40 ) { // YELLOW = R+G

      // Velocity < 40 : set green LED, set red LED, clear blue led
      blm_row_green[led_column]  |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_red[led_column]    |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_blue[led_column]   &= MIOS_HLP_GetBitANDMask(led_row);

    } else if( evnt2 < 50 ) { // turquoise = G+B

      // Velocity < 50 : set green LED, set blue LED, clear red led
      blm_row_green[led_column] |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_blue[led_column]  |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_red[led_column]   &= MIOS_HLP_GetBitANDMask(led_row);
      
    } else if( evnt2 < 60 ) { // PURPLE = R+B

      // Velocity < 60 : set blue LED, set red LED, clear green led
      blm_row_blue[led_column]  |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_red[led_column]   |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_green[led_column] &= MIOS_HLP_GetBitANDMask(led_row);
            
    } else {

      // Velocity >= 61: set RGB LEDs
      blm_row_green[led_column] |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_red[led_column]   |= MIOS_HLP_GetBitORMask(led_row);
      blm_row_blue[led_column]  |= MIOS_HLP_GetBitORMask(led_row);

    }
  }

The behaviour is very strange :

when it is supposed to be only GREEN, it lights up BLUE+GREEN

when supposed only BLUE, nothing lights up

when supposed RED+GREEN, it is R+G+B

when supposed R+B, it is only RED

LEDs used are these with common cathode http://cgi.ebay.fr/ws/eBayISAPI.dll?ViewItem&item=230254668750&_trksid=p3907.m32&_trkparms=tab%3DWatching

It seems the green led was driving the blue led and the blue led not connected (obvious it is, as it can produce RGB light !)

Any ideas ?

MIOS32 drives RGB, but I don't have yet the mios32 PCB ...

stryd_edit: Just added the code tag

4colors_blm_example_v1_2.zip

4colors_blm_example_v1_2.zip

Link to comment
Share on other sites

on button press and on midi note :

when it is supposed to be green, i have blue+green,

when supposed to be blue, i have nothing,

when supposed to be red+green, i have blue+green+red !

it is very frustrating

The behaviour is as if the 74HC595 managing the blue leds (SR3, if i count starting at 1) had the same behaviour as the 74HC595 managing the green one (SR2). That's why i have thought to a software issue, especially in BLM.asm.

I will check once again that i am well connected reading the schematic ... but I am sure i am as the good RGB led (meaning the 34th when midi note 34 received) lights up.

I am curious to know if it worked for Intellijel

thanks for your help mr bugfight

Link to comment
Share on other sites

PROBLEM SOLVED ! they was a mistake on 1 line of BLM.asm !!!

it was :

	;; output value of "Blue LED row" depending on current column
	lfsr	FSR2, _blm_row_green

	;; left side
	movf	IRQ_TMP1, W
	movff	PLUSW2, MIOS_PARAMETER1
#if DEFAULT_SRM_DOUT_BLU1
	movlw	DEFAULT_SRM_DOUT_BLU1 - 1
	call	MIOS_DOUT_SRSet
#endif

	;; right side
	incf	IRQ_TMP1, W
	movff	PLUSW2, MIOS_PARAMETER1
#if DEFAULT_SRM_DOUT_BLU2
	movlw	DEFAULT_SRM_DOUT_BLU2 - 1
	call	MIOS_DOUT_SRSet
#endif
IT MUST BE :
	;; output value of "Blue LED row" depending on current column
	lfsr	FSR2, _blm_row_blue

	;; left side
	movf	IRQ_TMP1, W
	movff	PLUSW2, MIOS_PARAMETER1
#if DEFAULT_SRM_DOUT_BLU1
	movlw	DEFAULT_SRM_DOUT_BLU1 - 1
	call	MIOS_DOUT_SRSet
#endif

	;; right side
	incf	IRQ_TMP1, W
	movff	PLUSW2, MIOS_PARAMETER1
#if DEFAULT_SRM_DOUT_BLU2
	movlw	DEFAULT_SRM_DOUT_BLU2 - 1
	call	MIOS_DOUT_SRSet
#endif

lfsr FSR2, _blm_row_green

IS FALSE;WRITE lfsr FSR2, _blm_row_blue

Ah ah ! I had well observed the problem : blue was acting like green, logical when you see the code

Now everything works :) toggling and midi notes ;) thanks to bugfight for helping me.

I'll be back in 2 weeks when my super seq-control surface will be ready !!

4colors_RGB_blm_example_v1_2.zip

blm.asm

4colors_RGB_blm_example_v1_2.zip

blm.asm

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