Jump to content

RGB version of BLM.asm I just need help with one section


Recommended Posts

I am going through the BLM.asm example under the C interface section but since this part is in assembly I thought it was appropriate to seek help here:

It looks pretty straightforward to modify in order to drive rgb leds.

Since the BLM is formed from two 4x8 led matrices (called L and R) I just needed to add an extra SR on each side. This affected small things like the which SRs are used for driving the cathods and I had to add some extra variables (and change some names) make the three sets of colors clear.

So each bank of 4x8 is formed from one SR (4 pins) driving the cathodes and then three SRs for red green and blue respectfully.

There is only one section of the code that I do not know what to do with (given my limited understanding of assembly code):

	;; store row*2 offset in IRQ_TMP1 to simplify the addressing of blm_row_green and blm_row_red array
	SET_BSR	blm_selected_column
	movf	blm_selected_column, W, BANKED
	rlf	WREG, W
	andlw	0x06
	movwf	IRQ_TMP1

In this section I am not sure what to change or add since there is an additional offset for the 3rd color.

The full modified BLM.asm code can be found here:

http://intellijel.com/blm.asm

http://intellijel.com/blm.h            ------> just the one array added for blue color

help is appreciated!

Link to comment
Share on other sites

Might look at the code for you in a bit, have no clue what that deos.... but maybe this will help:

	;; store row*2 offset in IRQ_TMP1 to simplify the addressing of blm_row_green and blm_row_red array
	SET_BSR	blm_selected_column
	movf	blm_selected_column, W, BANKED
	rlf	WREG, W
	andlw	0x06
	movwf	IRQ_TMP1
=
IRQ_TMP1 = ((blm_selected_column<<1)&0x06);

Link to comment
Share on other sites

Aha that makes sense!

My rgb leds are very low current (the max for any color is 0.6mA at the brightness I want). I could put 16 in a row and they would still draw only about 10.6mA while the 74HCT595 pins can supply at least 25mA.

However, I will be using a uln2003a to sink the current just in case.

So now that I know my LED currents are so low, would it not be easier for me to modify the hardware and software so that a single SR is used to drive 8 columns and then use 3 other SRs for a color each (to make an 8x8 matrix)

I would then move the button scanning matrix to a simmilar setup (one SR for the columns, 1 SR for the rows)

Link to comment
Share on other sites

wow, that's some efficient leds!

ref http://www.ucapps.de/mbhp/button_duoled_matrix.pdf

the supply side of the blm circuit (DEFAULT_SRM_DOUT_L1, DEFAULT_SRM_DOUT_L2) is no problem since each pin only supplies 1 led at a time.

DEFAULT_SRM_DOUT_CATHODES1 on the other hand sinks current for the whole row at once

(i mistakenly said 16 leds before, which is correct for duo leds but for rgb it will be 24)

to simply add a third led color, you would add DEFAULT_SRM_DOUT_L3...

(for the left side that is, the same applies to the right side)

Link to comment
Share on other sites

let's say all the red leds are ON in row 1. Wouldn't that mean that 4 leds are being driven by a single SR pin out?  (but each of the 4 pins on the Cathode SR is sinking a current)

However, if I had 8 LEDs in a column on, each SR would only drive one led but the Cathode SR would be sinking the current for 8 leds.

This is all assuming a 4x8 matrix

The max current a single pin on a Cathode SR would sink is when a whole column is lit up and all three colours are being used. If rgb this would be 24x Id (led current). ULN2003A can sink tons of current so this is not an issue.

As for efficient RGB leds, I just bought custom made, superbright RGB leds from china. They have flat tops and are diffused. Unfortunately I wish there was a little more plastic on the tops of them to help diffuse the colors better but I am fixing that putting a short plastic tube on each one and then putting a semi-translucent plastic where the holes will be on my front panel.

The red draws the most current at 0.6 mA with the brightness I want (and I get a smooth 180 degree viewing angle once it is appropriately diffused). The other colours draw 10x less!!

If you look at the code I posted above, I already added and changed the anode variable names to make it more readable for my application

DEFAULT_SRM_DOUT_RED1

DEFAULT_SRM_DOUT_BLU1

DEFAULT_SRM_DOUT_GRN1

I will actually be able to drive all the cathodes from one SR+uln2003a

so just 4 SRs in total will be used.

HOWEVER, I need a 8x16 matrix of leds so I need this code to drive two 4x16 matrices, not two 4x8 matrices

OR should I just have a second core do this?  I have no issue with chaining multiple cores but I have a feeling I may not need to.

Link to comment
Share on other sites

let's say all the red leds are ON in row 1. Wouldn't that mean that 4 leds are being driven by a single SR pin out?  (but each of the 4 pins on the Cathode SR is sinking a current)

yes but only one at a time, the code steps through sinking row 1, then row 2, etc...

...

The max current a single pin on a Cathode SR would sink is when a whole column is lit up and all three colours are being used. If rgb this would be 24x Id (led current). ULN2003A can sink tons of current so this is not an issue.

yes

As for efficient RGB leds, I just bought custom made, superbright RGB leds from china. They have flat tops and are diffused. Unfortunately I wish there was a little more plastic on the tops of them to help diffuse the colors better but I am fixing that putting a short plastic tube on each one and then putting a semi-translucent plastic where the holes will be on my front panel.

The red draws the most current at 0.6 mA with the brightness I want (and I get a smooth 180 degree viewing angle once it is appropriately diffused). The other colours draw 10x less!!

cool, you have link?

If you look at the code I posted above, ...

sorry, i'm not going to look thru all that code looking for changes.

if you have a specific issue, i will be happy to help if i can...

HOWEVER, I need a 8x16 matrix of leds so I need this code to drive two 4x16 matrices, not two 4x8 matrices

OR should I just have a second core do this?  I have no issue with chaining multiple cores but I have a feeling I may not need to.

i believe duping the code to get 8x16 is no problem for one core, except that you will have no douts for other uses...

Link to comment
Share on other sites

yes but only one at a time, the code steps through sinking row 1, then row 2, etc...

\

I know the button matrix is scanned but I didn't think the led matrix was as well. Looking at the code I think I see where that is happening.

So yeah that reduces the current load on the SRs for sure.

Link to comment
Share on other sites

If you are doing code modifications which should be re-used in future by other people, please start with the most recent code which is available in the MIOS repository

Otherwise, changes I already did for the blm module have to be redone for your module - this is very time consuming :-(

Best Regards, Thorsten.

Link to comment
Share on other sites

sure thing TK!

I looked in the repository and was pleased to see a driver for using the MAX7221! I will definitely be trying that out too (so much nicer for RGB leds to have a single resitor to set brightness and to have built in pwm and matrix scanning)

cheers,

  Danjel

Link to comment
Share on other sites

  • 3 months later...
  • 2 weeks later...
  • 2 months later...

ok guys

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

 #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 :
/////////////////////////////////////////////////////////////////////////////
//  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 led the green was driving the blue led and the blue led not connected (obvious it is as it can produce RGB light !)

Any ideas ? TK ?

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

4colors_blm_example_v1_2.zip

4colors_blm_example_v1_2.zip

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