News:

SMF for DIYStompboxes.com!

Main Menu

Whammy MIDI Controller

Started by LiquidMetal, November 18, 2010, 11:14:10 PM

Previous topic - Next topic

LiquidMetal

Hello!

I was not happy with the inability of my Whammy 4 to switch back and fourth trough the programs and got some inspiration from the original MIDI controller from Molten Voltage. I had an old 8051 kit collecting dust and decided to put a small prototype together. The basic function is implemented by three momentary switches - Up, Down and Active/Bypass mode. My biggest problem as usual was the de-bouncing code which can still be improved. The next step will be to move it from a breadboard to something more permanent. The source code file is available upon request. 



Uploaded with ImageShack.us


Uploaded with ImageShack.us


Uploaded with ImageShack.us

;***************************************************************************
;*                                                                         *
;*                                                                         *
;*                  Digitech Whammy MIDI Control Program                   *
;*                           Version 0.7                                   *
;*                            11/18/2010                                   *
;*                                                                         *
;*                                                                         *
;***************************************************************************
;
#INCLUDE "8051EQU.INC"          ;include predefined constants
;
;
;                          VARIABLES AND CONSTANTS
;
;   R5,R6,R7 - used in delay routines
;   R4 - program value
;   R1 - used for Program Change commands
;   R0 - used for Program Change commands
;   
;   Ports
;      P3
;         P3.0 - Serial Receive
;         P3.1 - Serial Transmit
;      P1
;   P1.0 - LED
;   P1.1 - UP   momentary switch (NC)
;   P1.2 - DOWN momentary switch (NC)
;         P1.3 - Active/Bypass momentary switch (NC)
;
;   User Bits
;         bit 20h - Active/Bypass Value
;**************************************************************************
;
; RESET                         ;reset routine

   .ORG   0H                    ;locate routine at 00H
    AJMP   START                ;jump to START
;
;**************************************************************************
;
; INTERRUPTS                    ;place interrupt routines at appropriate
;                                ;memory locations
   .ORG   03H                   ;external interrupt 0
    RETI
;
   .ORG   0BH                   ;timer 0 interrupt
    RETI
;
   .ORG   13H                   ;external interrupt 1
    RETI
;
   .ORG   1BH                   ;timer 1 interrupt
    RETI
;
   .ORG   23H                   ;serial port interrupt
    RETI
;
;*************************************************************************
;
   .ORG   030H                  ;locate beginning of rest of program
;
;**************************************************************************
;
INITIALIZE:                     ;set up control registers
;
    MOV   PCON,#00H
    MOV   TMOD,#020H            ;Set Timer 1 for Mode 2, Auto Reload
    MOV   TCON,#040H            ;Turn timer 1 on
    MOV   PSW,#00H
    MOV   SCON,#050H            ;set serial port to 8 bit UART
    MOV   TH1,#0FEH             ;Reload value for timer 1 for 31.25k baud (24MHz xtal)
    MOV   P3,#003H              ;Enable TxD and RxD         
;    MOV   IE, #090H             ;Enable Serial Interrupt
    RET
;
;**************************************************************************
;
;      Real code starts below.
;
;**************************************************************************
;**************************************************************************
;
DELAYMS:                        ;millisecond delay routine
;                               ;
   MOV   R7,#00H                ;put value of 0 in register R7
LOOPA:                         
   INC   R7                     ;increase R7 by one (R7 = R7 +1)
   MOV   A,R7                   ;move value in R7 to Accumlator (also known as A)
   CJNE   A,#0FFH,LOOPA         ;compare A to FF hex (256). If not equal go to LOOPA
   RET                          ;return to the point that this routine was called from
;
;**************************************************************************
;
DELAYHS:                        ;half second delay above millisecond delay
;                               ;
   MOV   R6,#00H                ;put 0 in register R6 (R6 = 0)
   MOV   R5,#002H               ;put 2 in register R5 (R5 = 2)
LOOPB:
   INC   R6                     ;increase R6 by one (R6 = R6 +1)
   ACALL   DELAYMS              ;call the routine above. It will run and return to here.
   MOV   A,R6                   ;move value in R6 to A                   
   JNZ   LOOPB                  ;if A is not 0, go to LOOPB
   DEC   R5                     ;decrease R5 by one. (R5 = R5 -1)
   MOV   A,R5                   ;move value in R5 to A
   JNZ   LOOPB                  ;if A is not 0 then go to LOOPB.
   RET
;
;**************************************************************************
; Transmits the value in A through the serial (MIDI) port
SEND:
   CLR TI
   MOV SBUF,A             
WAIT1:
   JNB TI, WAIT1                ;Wait till done transmitting
   RET
   
;**************************************************************************
;
;      MIDI Functions
;
;**************************************************************************
;**************************************************************************
; Play Note Command
NOTE_ON:
   MOV A,#090H                  ;NOTE ON Command
   ACALL SEND
   MOV A, R0                    ;Play note specified by R0
   ACALL SEND
   MOV A, #40H                  ;Use attack velocity of 40H
   ACALL SEND
   RET
;**************************************************************************
; Note Off Command
NOTE_OFF:
   MOV A,#080H                  ;NOTE OFF Command
   ACALL SEND
   MOV A, R1                    ;Turn off note specified by R1
   ACALL SEND
   MOV A, #40H                  ;Use release velocity of 40H
   ACALL SEND
   RET
;**************************************************************************
; Program Change Command
PGM_CHG:
   MOV A,#0C0H                  ;PROGRAM CHANGE Command
   ACALL SEND
   MOV A, R0                    ;Program Change value specified by R0
   ACALL SEND
   RET
   
;**************************************************************************
; Blink the LED 3 times on boot
HELLO:
    MOV R1,#0   
HelloLoop:
    CLR P1.0 ; turn LED on
    ACALL DELAYHS
    SETB P1.0 ; turn LED off
    ACALL DELAYHS
    INC R1
    CJNE R1,#3,HelloLoop

RET

;**************************************************************************
;
; P1.0 - LED
; P1.1 - UP   momentary switch (NC)
; P1.2 - DOWN momentary switch (NC)
; P1.3 - Active/Bypass momentary switch (NC)
; R4   - program value
; bit 20h - Active/Bypass Value
START:                           ;main program (on power up, program starts at this point)
MOV   SP,#02FH               ;Set Stack Pointer = 2FH
ACALL INITIALIZE             ;set up control registers
ACALL HELLO ; Blink the LED 3 times on boot

CLR   20h ; set the default Active/Bypass mode to Active
MOV   R4,#3 ; set the default program to 'Whammy Octave Up'
    MOV   A, R4
    MOV   R0, A
    ACALL PGM_CHG ; set the initial program

SETB  P1.1
SETB  P1.2
SETB  P1.3
SETB  P1.0 ; Turn LED off

wait_for_pressed:
MOV C,P1.1
ORL C,P1.2
ORL C,P1.3
JNC wait_for_pressed

    MOV R7,#255
deb_loop1:
MOV C,P1.1
ORL C,P1.2
ORL C,P1.3
JNC wait_for_pressed

DJNZ R7,deb_loop1

JB   P1.1, inc_pgm
JB   P1.2, dec_pgm
JB   P1.3, act_bypass
SJMP pgm_change

act_bypass:
CPL  20h
SJMP pgm_change

inc_pgm:
INC  R4
SJMP pgm_change

dec_pgm:
DEC  R4
SJMP pgm_change

pgm_change:
    MOV A, R4 ; Take care of values greater than 0-16
MOV B, #17
DIV AB
MOV A,B

JNB 20h,no_bypass ; Skip the next line for Active mode
ADD A, #17 ; Add 17 to the program number for Bypass mode
no_bypass:
    MOV R0, A
    ACALL PGM_CHG ; Set the program

CLR P1.0 ; Turn LED on

wait_for_release:
MOV C,P1.1
ORL C,P1.2
ORL C,P1.3
JC wait_for_release

    MOV R7,#255
deb_loop2:
MOV C,P1.1
ORL C,P1.2
ORL C,P1.3
JC wait_for_release

DJNZ R7,deb_loop2

SETB P1.0 ; Turn LED off

AJMP wait_for_pressed
.END                            ;end of program

LiquidMetal

I managed to finish it this weekend. I decided to change the function of the middle button from on/off to max/min. This controls the virtual treadle position from 127 (when pressed) to 0 (on release). The next steps will be to implement a tap tempo button, step sequencer and probably to port to AVR ATTiny13.




Bunyaman

LiquidMetal, did you finish this priject?  I want to make controller for WHAMY 4: up and down bank, that`s all i need:)

LiquidMetal

Yes, I finished it and it works very well. You will need to do a slight change to the program for just ups/downs. Let me know if you need further info.

Bunyaman

Have anyone a contact information with topicstarter?