there has got to be a better way...
hey all, i have some code here that polls six buttons, then spits out a midi code that corresponds with the button pressed. After the serial string is sent, it lights up one of 6 led's also corresponding to the last button pressed.
the code works great, but it's rather unevolved and longwinded. is there a better way to do this perhaps with a for next loop?
thanks in advance!
Post Edited (skynugget) : 10/20/2009 12:26:23 PM GMT
the code works great, but it's rather unevolved and longwinded. is there a better way to do this perhaps with a for next loop?
thanks in advance!
Btn1 PIN RB.0 input PULLUP SCHMITT Btn2 PIN RB.1 input PULLUP SCHMITT Btn3 PIN RB.2 input PULLUP SCHMITT Btn4 PIN RB.3 input PULLUP SCHMITT Btn5 PIN RB.4 input PULLUP SCHMITT Btn6 PIN RB.5 input PULLUP SCHMITT SW1 PIN RB.6 input PULLUP SCHMITT LEDS PIN RC LED1 PIN RC.0 LED2 PIN RC.1 LED3 PIN RC.2 LED4 PIN RC.3 LED5 PIN RC.4 LED6 PIN RC.5 ' ------------------------------------------------------------------------- ' Constants ' ------------------------------------------------------------------------- open con 1 closed con 0 Baud CON "OT31250" ' for MIDI Channel CON 0 CtrChange CON $C0 | Channel ' ------------------------------------------------------------------------- ' Variables ' ------------------------------------------------------------------------- idx var byte tmpB1 VAR Byte ' for subs/funcs tmpB2 VAR Byte tmpW1 VAR Word ' ========================================================================= PROGRAM Start ' ========================================================================= ' ------------------------------------------------------------------------- ' Subroutine / Function Declarations ' ------------------------------------------------------------------------- WAIT_MS SUB 1, 2 ' replaces PAUSE TX_BYTE SUB 1 ' transmit a byte TX_STR SUB 2 ' transmit a string CNG_PGM SUB 1 ' Change MIDI program ' ------------------------------------------------------------------------- ' Program Code ' ------------------------------------------------------------------------- Start: Main: IF btn1 = closed THEN WAIT_MS 20 'debounce IF btn1 = closed THEN LOW LEDS CNG_PGM 0 WAIT_MS 1000 'allow for program load time HIGH LED1 DO WHILE btn1 = closed 'wait for button release WAIT_MS 20 LOOP ENDIF ENDIF IF btn2 = closed THEN WAIT_MS 20 'debounce IF btn2 = closed THEN LOW LEDS CNG_PGM 1 WAIT_MS 1000 'allow for program load time HIGH LED2 DO WHILE btn2 = closed 'wait for button release WAIT_MS 20 LOOP ENDIF ENDIF IF btn3 = closed THEN WAIT_MS 20 'debounce IF btn3 = closed THEN LOW LEDS CNG_PGM 2 WAIT_MS 1000 'allow for program load time HIGH LED3 DO WHILE btn3 = closed 'wait for button release WAIT_MS 20 LOOP ENDIF ENDIF IF btn4 = closed THEN WAIT_MS 20 'debounce IF btn4 = closed THEN LOW LEDS CNG_PGM 3 WAIT_MS 1000 'allow for program load time HIGH LED4 DO WHILE btn4 = closed 'wait for button release WAIT_MS 20 LOOP ENDIF ENDIF IF btn5 = closed THEN WAIT_MS 20 'debounce IF btn5 = closed THEN LOW LEDS CNG_PGM 4 WAIT_MS 1000 'allow for program load time HIGH LED5 DO WHILE btn5 = closed 'wait for button release WAIT_MS 20 LOOP ENDIF ENDIF IF btn6 = closed THEN WAIT_MS 20 'debounce IF btn6 = closed THEN LOW LEDS CNG_PGM 5 WAIT_MS 1000 'allow for program load time HIGH LED6 DO WHILE btn6 = closed 'wait for button release WAIT_MS 20 LOOP ENDIF ENDIF GOTO Main ' loop
Post Edited (skynugget) : 10/20/2009 12:26:23 PM GMT
Comments
You COULD do some fancy stuff with bit masks and such, but it would make it alot less readable.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Does that byte of memory hold "A", 65, $41 or %01000001 ?
Yes it does...
·
Here's the Main section:
As you can see, this calls a function called GET_BTNS which handles the input debouncing:
Just a note here: You're using active-low inputs. The GET_BTNS routine deals with that and then returns a value with "1" indicating a button press -- it's a little easier to work with in the main code. What I'm saying is that you don't have to change your hardware; this routine will work fine. Just remember that if button 1 is pressed the fuctnion will return %00000001.
Once you get your project working save a new version and try this to see how you like it. Even if you don't use it here, masking tricks are handy to have up one's sleeve.
Post Edited (JonnyMac) : 10/21/2009 7:48:07 PM GMT
I have always had problems with bit masks till now. I really wasn't concerned about space for this stage of the project, i just need to get it built and working. As I have time I would like to incorporate the ISR code from the Mo MIDI project to get status from the device, so it puts me a leg up. (If i can ever get the manual)
Here's the updated code that does the exact same thing above. Hope someone learns something about those fancy bitmasks!
Post Edited (skynugget) : 10/21/2009 9:19:58 PM GMT
Hint: If one SUB/FUNC A is called by SUB/FUNC B then A should appear further down the listing -- this lets you use conditional compilation of routines to preserve space as your projects get bigger. Note, too, how with SX/B 2.0 the WAIT_MS subroutine is simplified to one [noparse][[/noparse]working] line. You'll also note that I replaced the FOR-NEXT loop with manual code; this is a personal style thing as I think one should limit the amount of code enclosed in any loop structure.
Post Edited (JonnyMac) : 10/23/2009 7:41:52 AM GMT
i don't quite understand how the compile time directive saves space? the way i understand it $ifused will not compile the code enclosed if its not called? which has seemed a little odd to me. why write code you're not going to use? got time to set me straight?