Jump to content

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


TK.
 Share

Recommended Posts

blm_example is now available at http://www.ucapps.de/mios_download.html

I used this small application during the development of the Button/Duo-LED hardware for MIDIbox SEQ V3 in order to check different wiring options. The driver (blm.asm) is mainly based on sm_simple.asm of the sm_c_example1.

Today I added a debouncing option as requested by bugfight

I would like to highlight again, that the hardware as shown in http://www.ucapps.de/mbhp/button_duoled_matrix.pdf needs to be improved for high current LEDs. I don't see this as my task.

Newbies: there are no premade PCBs available, and manual wiring on vero boards requires advanced soldering experiences!

Pictures: http://www.midibox.org/midibox_seq_blm_ext/

From the README.txt

[tt]

Button/Duo-LED Example

===============================================================================

Copyright 2008 Thorsten Klose (tk@midibox.org)

Licensed for personal non-commercial use only.

All other rights reserved.

===============================================================================

A precompiled binary is already part of this package:

  o project.hex (can be loaded into MIOS Studio)

  o project.syx (can be loaded into any SysEx upload tool)

Following tools are required to recompile the code:

  o SDCC v2.5.0

  o gputils

  o perl

The details are described under http://www.ucapps.de/mios_c.html

===============================================================================

Required hardware:

  o one MBHP_CORE module

  o one DINX2 module (or DINX4) and two DOUTX4 modules

    or dedicated board for BLM matrix as specified under:

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

===============================================================================

This program demonstrates the so called "BLM" driver (-> blm.c)

This driver handles a 4x16 Button/Duo-LED scan matrix of up to 64 buttons and 64 Duo-LEDs

by using the circuit documented under:

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

The hardware was originally used for MIDIbox SEQ V3, but could also be useful for

other projects.

Note that the buttons/LEDs can be easily arranged to a 8x8 matrix w/o software modifications.

Please note also, that the shift register assignments in blm.c (DEFAULT_*) need to be adapted

to your hardware. The setup used in this example is prepared for connecting the

DIN/DOUT chain directly to the MBHP_CORE module (there are no additional DINX4 or DOUTX4

modules between the BLM and the core like on the MBSEQ V3 hardware).

The function "BLM_NotifyToggle()" in main.c is called when a button has been

pressed or released. LEDs are accessible from the blm_row_green[8] and

blm_row_red[8] array.

By default, this application sends Note Events from Number 0 (C -1) to 63 (E 4)

and it receives the same numbers to control the LEDs:

  Velocity 0x00 (or Note off): green and red LED off

  Velocity 0x01..0x3f:        green LED on, red LED off

  Velocity 0x40..0x5f:        green LED off, red LED on

  Velocity 0x60..0x7f:        both LEDs on

Optionally some code can be enabled in the BLM_NotifyToggle function

(located in main.c) to cycle the LED colour with the appr. buttons.

Buttons can be debounced with a definable delay (-> blm_button_debounce_delay)

The resulting delay is calculated as <value> * 4 mS

The Init() function in main.c sets the value to 20 (-> 20*4 mS = 80 mS)

If you want to experiment with different delays, you could (temporary)

control it with a CC event from MPROC_NotifyReceivedEvnt() function in

main.c with following code:

  if( evnt0 == 0xb0 && evnt1 == 16 ) { // control debounce delay with CC#16 over Channel #1

    blm_button_debounce_delay = evnt2;

  }

Don't forget to remove this change, so that a common MIDI application

isn't able to modify the value unintentionally.

===============================================================================

Description about the most important files:

  - mios_wrapper\mios_wrapper.asm and mios_wrapper\mios_tables.inc:

    The MIOS wrapper code and MIOS specific configuration tables

  - pic18f452.c: exports PIC18F452 specific SFRs

  - main.c: the main program with all MIOS hooks

  - blm.asm: the assembly optimized scan matrix code

There are additional .h files for all .c files which contain

general definitions and the declaration of global functions/variables

These .h files must be included into the program parts which

get use of these globals

===============================================================================

[/tt]

Best Regards, Thorsten.

Link to comment
Share on other sites

blm_example is now available...

...

Today I added a debouncing option as requested by bugfight

woohoo! thanks, i'll check this out this weekend...

I would like to highlight again, that the hardware as shown in http://www.ucapps.de/mbhp/button_duoled_matrix.pdf needs to be improved for high current LEDs. I don't see this as my task.

did you not like my attempt at this? 

http://www.midibox.org/forum/index.php/topic,10004.msg74201.html#msg74201

is something more necessary?

seems to work well...

Link to comment
Share on other sites

just had first glance at new project example.

here is how i did the led toggle function:

		unsigned char mask = MIOS_HLP_GetBitORMask( pin ); //ex 0b00000001, 0b00000010
		unsigned char idx = (pin >> 3) & 0x07;
		if (BLM_LED_states1[idx] & mask)
			BLM_LED_states2[idx] ^= mask; //states2 bit is toggled if states1 bit is 1
		BLM_LED_states1[idx] ^= mask; //states1 is always toggled

i think it's more efficient, no?

not that it matters much in a test program...

Link to comment
Share on other sites

i think inserting this directive will work to implement the switch for

current sinking transistors on the led rows:

...

#define BLM_INVERT_LED_CATHODES  1 ; 1 if sinking transistors are used on the led cathodes, 0 if not

...

BLM_PrepareCol

...

;; select next DOUT/DIN column

movf blm_selected_column, W, BANKED ; (* see note below)

call MIOS_HLP_GetBitANDMask ; (inverted 1 of 8 code)

andlw 0x0f

#if BLM_INVERT_LED_CATHODES

xorlw 0x0F

#endif

movwf MIOS_PARAMETER1

Link to comment
Share on other sites

ok, i've tested the app.  the debounce function works great. thanks again.

it turns out i may have my led cathodes wired to the opposite 4 pins as you,

because i had to move the code to invert the pins as follows.  i'm holding out

a slim hope that the comment is just backwards, since this would require a

re-rout of the pcb:

;; select next DOUT/DIN column

movf blm_selected_column, W, BANKED ; (* see note below)

call MIOS_HLP_GetBitANDMask ; (inverted 1 of 8 code)

andlw 0x0f

movwf MIOS_PARAMETER1

;; duplicate the 4 selection lines for button matrix ;should this line read dupe for the leds??

#if BLM_INVERT_LED_CATHODES

xorlw  0x0f

#endif

swapf WREG, W

iorwf MIOS_PARAMETER1, F

Link to comment
Share on other sites

here's the (now tested) simplified toggling func in place

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);
  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
  if (!value)
  {
      mask = MIOS_HLP_GetBitORMask(pin);
      if ( blm_row_green[blm_button_column] & mask )
         blm_row_red[blm_button_column] ^= mask;
      blm_row_green[blm_button_column] ^= mask;
  }
#endif

  // request display update
  app_flags.DISPLAY_UPDATE_REQ = 1;
}

Link to comment
Share on other sites

Thank you!

I added the inversion parameter the following way to blm.asm:


; set an inversion mask for the DOUT shift registers if sink drivers (transistors)
; have been added to the cathode lines
; Settings: 0x00 - no sink drivers
;           0xf0 - sink drivers connected to D0..D3
;           0x0f - sink drivers connected to D4..D7
#define DEFAULT_SRM_CATHODES_INV_MASK   0x00
[/code]

The cathodes of your LEDs are connected correctly - DOUT registers are mirrored, this might be confusing...

I will consider to add sink drivers to my own hardware as well. They are not really required (as I'm using low-power LEDs), but it makes sense to be "source code compatible" with other solutions.

I also added your optimied LED toggling code.

-> blm_example_v1_1 in the MIOS download section.

Best Regards, Thorsten.

Link to comment
Share on other sites

Thank you!

no, thank you!

new version loaded and tested.

I added the inversion parameter the following way to blm.asm:

...

The cathodes of your LEDs are connected correctly - DOUT registers are mirrored, this might be confusing...

this is clearly better, more easily configured and keeps timing the same.

note that i used 0xF0 for the mask.

I will consider to add sink drivers to my own hardware as well. They are not really required (as I'm using low-power LEDs), but it makes sense to be "source code compatible" with other solutions.

originally i used  BC847AMTF because the specs matched up with bc547,

but i had an issue with the leds dimming as more were added

(this only really showed up on the last 5 or so of 16)

so i changed to a darlington transistor. 

i used MMBTA14, which is smd version of MPSA14

I also added your optimied LED toggling code.

-> blm_example_v1_1 in the MIOS download section.

Best Regards, Thorsten.

coolness.

Link to comment
Share on other sites

i wasn't paying attention to the column and row numbers.

now that i did, i noticed a few things:

  - column and row are reversed (i think there was a provision for swapping them in the old code)

  - column alternates between sides while row is always 0-7 so if set up for seq (4x16)

    going left to right and top to bottom sequentially you get (col,row)

    (0,0)...(0,7) (1,0)...(1,7)

    (2,0)...(2,7) (3,0)...(3,7)

    (4,0)...(4,7) (5,0)...(5,7)

    (6,0)...(6,7) (7,0)...(7,7)

    for 8x8 monome style you get

    (0,0)...(0,7)

    (2,0)...(2,7)

    (4,0)...(4,7)

    (6,0)...(6,7)

    (1,0)...(1,7)

    (3,0)...(3,7)

    (5,0)...(5,7)

    (7,0)...(7,7)

Link to comment
Share on other sites

note that i used 0xF0 for the mask.

Me too, it is matching with the schematic (D0 is bit 7, D1 is bit 6, etc...)

column and row are reversed (i think there was a provision for swapping them in the old code)

Ooops, you are right!

I fixed this in version blm_example_v1_2 (-> see MIOS download section)

Column alternates between sides while row is always 0-7 so if set up for seq (4x16)

    going left to right and top to bottom sequentially you get (col,row)

For the 4x16 matrix (which I own) this scrambling is better.

Therefore I guess it's only a documentation issue - I added your input to the README.txt file

The processing routines in main.c (or in the host software) can easily map the column/row numbers to the "physical layout" if desired.

Best Regards, Thorsten.

Link to comment
Share on other sites

with the column and row no longer swapped, the "scrambling" should now read

  4x16:

  (0,0)(1,0)(2,0)(3,0)(4,0)(5,0)(6,0)(7,0)(0,1)(1,1)(2,1)(3,1)(4,1)(5,1)(6,1)(7,1)

  (0,2)(1,2)(2,2)(3,2)(4,2)(5,2)(6,2)(7,2)(0,3)(1,3)(2,3)(3,3)(4,3)(5,3)(6,3)(7,3)

  (0,4)(1,4)(2,4)(3,4)(4,4)(5,4)(6,4)(7,4)(0,5)(1,5)(2,5)(3,5)(4,5)(5,5)(6,5)(7,5)

  (0,6)(1,6)(2,6)(3,6)(4,6)(5,6)(6,6)(7,6)(0,7)(1,7)(2,7)(3,7)(4,7)(5,7)(6,7)(7,7)

  8x8:

  (0,0)(1,0)(2,0)(3,0)(4,0)(5,0)(6,0)(7,0)

  (0,2)(1,2)(2,2)(3,2)(4,2)(5,2)(6,2)(7,2)

  (0,4)(1,4)(2,4)(3,4)(4,4)(5,4)(6,4)(7,4)

  (0,6)(1,6)(2,6)(3,6)(4,6)(5,6)(6,6)(7,6)

  (0,1)(1,1)(2,1)(3,1)(4,1)(5,1)(6,1)(7,1)

  (0,3)(1,3)(2,3)(3,3)(4,3)(5,3)(6,3)(7,3)

  (0,5)(1,5)(2,5)(3,5)(4,5)(5,5)(6,5)(7,5)

  (0,7)(1,7)(2,7)(3,7)(4,7)(5,7)(6,7)(7,7)

Link to comment
Share on other sites

here's a quick way to move the midi note range up, which helps

when testing with mios studio, and may be useful for others...

add to main.h:

/////////////////////////////////////////////////////////////////////////////
// Global definitions
/////////////////////////////////////////////////////////////////////////////

#define BLM_MIDI_STARTNOTE 24 ;; NOTE: this should be kept under 64 or the notes will wrap back down to 0
             
change in main.c:
void MPROC_NotifyReceivedEvnt(unsigned char evnt0, unsigned char evnt1, unsigned char evnt2) __wparam
{
  unsigned char led_column;
  unsigned char led_row;
  unsigned char evnt1Adj;

 ...

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

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

...
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 + BLM_MIDI_STARTNOTE) & 0x7f);
  MIOS_MIDI_TxBufferPut(value ? 0x00 : 0x7f);
...

edit* changed as tk suggested...

Link to comment
Share on other sites

Note, that this code will send invalid MIDI events when BLM_MIDI_STARTNOTE >= 65

It's better to write:


  MIOS_MIDI_TxBufferPut((pin + BLM_MIDI_STARTNOTE) & 0x7f);
[/code]

and something similar in MPROC_NotifyReceivedEvnt(); so that the "wrapped" note number is still maching between LEDs and Buttons

Best Regards, Thorsten.

Link to comment
Share on other sites

  • 8 months later...
  • 4 weeks later...

The processing routines in main.c (or in the host software) can easily map the column/row numbers to the "physical layout" if desired.

Best Regards, Thorsten.

Got the hardware working.

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?

Thanks,

Luke

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