'**************************************************************** '* Name : Rodo_Dampers1.BAS * '* Author : Godfried-Willem RAES * '* Notice : Copyleft (c) 2014 Logosoft Public Domain * '* Date : 16-03-2014 * '* Version : 1.2 * '* Notes : code for the 18F4620 * '**************************************************************** ' 11.01.2014: Start coding, in the model used for the beaters. ' Here we use the release byte to set the damping force/time ' When note-on with velo=0 is used, release can be controlled with CC12 ' We have to carefully check the implementation with the e-drive as well ' This version compiles o.k. ' Controls the dampers 48-63 ' Dampers 64-78 are controlled by the second board and the firmware Rodo_Dampers2.bas ' Midi controllers #14,15,64,66,123 implemented. ' 13.01.2014: First version programmed in chip and tested on test-board. ' 01.03.2014: LED spotlites added on notes 114,115 ' 12.03.2014: Blue LED spotlites added on notes 112, 113 ' 15.03.2014: Wiring ready for tests ' This version 1.1 uploaded into PIC ' damping time was still way too short. ' sustain on/off does not seem to work ' 16.03.2014: Version 1.2 : damping time now 6ms to 747ms, by default 240ms. Include "18F4620.inc" ' for the damper processor (40MHz) ' Mapping defines for midi-events on pin outputs and inputs: ' dampers - in order of output on the PC board $define Demp48 PORTA.2 ' #1 $define Demp49 PORTA.1 ' #2 $define Demp50 PORTA.0 ' #3 $define Demp51 PORTA.3 ' #4 $define Demp52 PORTA.4 ' #5 $define Demp53 PORTA.5 ' #6 $define Demp54 PORTE.0 ' #7 $define Demp55 PORTE.1 ' #8 $define Demp56 PORTE.2 ' #9 $define Demp57 PORTB.4 ' #10 $define Demp58 PORTB.3 ' #11 $define Demp59 PORTB.2 ' #12 $define Demp60 PORTB.1 ' #13 $define Demp61 PORTB.0 ' #14 $define Demp62 PORTD.7 ' #15 $define Demp63 PORTD.6 ' #16 '$define spare1 PORTD.5 ' #17 '$define spare2 PORTD.4 ' #18 '$define Valve19 PORTC.5 ' #19 '$define Valve20 PORTC.4 ' #20 pin 23 '$define Valve21 PORTD.3 ' #21 pin 22 ' $define Valve22 PORTD.2 ' #22 pin 21 ' alias defines for lites: ' $define Lite124 PORTC.0 ' #23 steered by Lites.0 ' $define Lite125 PORTC.1 ' #24 Lites.1 $define Lite112 PORTC.2 ' #25 blue frontal spot $define Lite113 PORTC.3 ' #26 blue frontal spot $define Lite114 PORTD.0 ' #27 yellow spot underside $define Lite115 PORTD.1 ' #28 yellow spot underside 'red LED for debug: $define Debug_Led PORTB.5 ' for testing - red led - watchdog Declare All_Digital = True ' makes all analog pins, digital for I/O Clear SSPCON1.5 ' make sure RC3 is free for use. ' configure the input and output pins: TRISA = %11000000 'bits set to 0 are output, 1 = input - bits 6 and 7 are the clock! TRISB = %11100000 'bits 6 and 7 are for the ICP, bit 5 is the red LED TRISC = %11000000 'RC6 en RC7 zijn USART I/O and must be set to input TRISD = %00000000 'all bits can be used TRISE = %11101000 'low nibble only, bit3 (RE3) is MCLR ' bit 4 must be cleared for port D to work normally!!! 'constant definitions: 'initialisations for the midi input parser: Symbol Midichannel = 7 ' Rodo_Channel Symbol NoteOff_Status = 128 + Midichannel ' 2 bytes follow Symbol NoteOn_Status = 144 + Midichannel Symbol Keypres_Status = 160 + Midichannel Symbol Control_Status = 176 + Midichannel 'Symbol ProgChange_Status = 192 + Midichannel ' 1 byte message Symbol Aftertouch_Status = 208 + Midichannel ' 1 byte follows 'Symbol Pitchbend_Status = 224 + Midichannel ' lsb msb follow 'Symbol Minvel = 180 '40 ' 40 was too low, changed to 180 15.03.2014 ' Setup the USART Declare Hserial_Baud = 31250 ' Set baud rate for the USART to MIDI specs. Declare Hserial_TXSTA = 0x24 ' instead of the normal 0x20 - ?? 0x24 ' Declare Hserial_Clear = On ' should clear on errors. Bytes get lost of course... This must be 31250 for MIDI ' Create variables: Dim Cnt As Dword System '32 bit counter Dim CntHw As Cnt.Word1 'used in the timer0 interrupt, where it is incremented Dim CntLw As TMR0L.Word 'this is the trick to read both TMR0L and TMR0H 'it makes Cntlw the low word of cnt, when we use cnt.word0=CntLw Dim Tim1 As TMR1L.Word ' Dim Tim2 As TMR2 ' not used here Dim Cnt3 As Dword System Dim Cnt3Hw As Cnt3.Word1 Dim Tim3 As TMR3L.Word ' same trick for timer3 ' Dim Sr as TMR0L.7 '512 S/s ' As TMR0H.1 would be 128 S/s ' As TMR0H.2 would be 64 S/s ' As TMR0H.3 would be 32 S/s ' As TMR0H.4 would be 16 S/s Dim Bytein As Byte System ' midi byte read from buffer Dim StBit As Bytein.7 ' highest bit of ByteIn Dim i As Byte System ' general purpose counter ' midi variables Dim statusbyte As Byte System Dim noteUit As Byte System ' note off + release value 'Dim release As Word System ' used for damper pressure/time - changed to word 15.03.2014 ' new implementation: Dim demptime As Word System Dim release As demptime.Byte1 ' this multiplies by 256 ' the range should now be 6ms to 747ms. Dim noteAan As Byte System ' note on + release value Dim velo As Byte System ' Dim notePres As Byte System ' note pressure + pressure value ' Dim pres As Byte System Dim Ctrl As Byte System ' continuous controller + value Dim value As Byte System ' Dim prog As Byte System ' program change + program-byte ' Dim aft As Byte System ' channel aftertouch ' Dim pblsb As Byte System ' pitch bend lsb ' Dim pbmsb As Byte System ' pitch bend msb ' Dim veltim As Dword System ' 32 bit velo Dim veltim0 As Dword System ' faster, replaces the arrays Dim veltim1 As Dword System Dim veltim2 As Dword System Dim veltim3 As Dword System Dim veltim4 As Dword System Dim veltim5 As Dword System Dim veltim6 As Dword System Dim veltim7 As Dword System Dim veltim8 As Dword System Dim veltim9 As Dword System Dim veltim10 As Dword System Dim veltim11 As Dword System Dim veltim12 As Dword System Dim veltim13 As Dword System Dim veltim14 As Dword System Dim veltim15 As Dword System Dim VelFlags0 As Byte System ' so we can have only 8 tasks Dim Velflags1 As Byte System ' another 8 tasks Dim CC14 As Byte System ' damping controller, default value 40 Dim CC15 As Byte System ' all-dampers together controller Dim CC16 As Byte System Dim CC64 As Byte System ' sustain controller. If >0 dampers will be disabled and released. Dim CC66 As Byte System ' global on/off switch Dim PowerOn As CC66.0 Dim st As Byte 'System Dim b1 As Byte 'System Dim b2 As Byte 'System ' Dim Lites As Byte ' reflecting the state of the lights in the 4 lowest bits of PortC '----------------------------------------------------------------------------------------- ' Load the USART Interrupt handler and buffer read subroutines into memory Include "Rodo_Beaters_Midi_Irq.inc" ' our own version for UART,Timer0, Timer3 Interrupt '----------------------------------------------------------------------------------------- ' Main program starts here MAIN: High Debug_Led DelayMS 20 ' wait for stability Low Debug_Led GoSub PowerDown CC14 = 40 ' default damping force value : to be checked. (this would be 240ms) Clear CC15 Clear CC16 Clear CC64 ' start up with sustain off, so with dampers active. Clear CC66 Init_Usart_Interrupt ' Initiate the USART serial buffer interrupt ' this procedure is in the include file Clear_Serial_Buffer ' Clear the serial buffer and reset its pointers ' in the include as well ' following only required for pulse outputs: ' Note that we can only use timer0 since the other timers ' are used by the PWM subsystem ' Configure Timer0 for: ' Clear TMR0L and TMR0H registers ' Interrupt on Timer0 overflow ' 16-bit operation ' Internal clock source 40MHz ' 1:256 Prescaler : thus 40MHz / 256 = 156.250kHz ' 6.4 us per clock-tick ' Opentimer0 (Timer_INT_On & T0_16BIT & T0_SOURCE_INT & T0_PS_1_256) ' replacing above macro with in-line coding: Clear T1CON Clear IntConBits_T0IF ' clear interrupt flag Set INTCONBITS_T0IE ' enable interrupt on overflow T0CON = %10000111 ' bit 7 = enable/disable ' bit 6 = 1=8 bot, 0=16 bit ' bit 5 = 1 pin input, 0= Internal Clk0 ' bit 4 = HL or LH transition when bit5 =1 ' bit 3 = 1= bypass prescaler, 0= input from prescaler ' bit 2-0 = prescaler select: 111= 1:256 ' Setup the High priorities for the interrupts ' TIMER1: if enabled, all midi-in is blocked, so it must interfere with the UART ' Configure Timer1 for: ' Clear TMR1L and TMR1H registers ' Interrupt on Timer1 overflow ' 16-bit read/write mode ' Internal clock source ' 1:8 Prescaler ' ' OpenTimer1(TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_8) ' dit kompileert o.k. ' TIMER2: if enabled, the UART stops working... ' Opentimer2 (Timer_Int_On & T2_POST_1_16 & T2_PS_1_16) ' dit lukt... maar de timer is nodig voor de UART... ' TIMER3: ' Configure Timer3 for: ' ' Interrupt on Timer3 overflow ' 16-bit read/write mode ' Internal clock source ' 1:8 Prescaler ' Don’t sync external clock input ' T3_OSC1En_On () ' macro ' OpenTimer3(TIMER_INT_ON & T3_16BIT_RW & T3_SOURCE_INT & T3_PS_1_8 & T3_SYNC_EXT_OFF) ' fout, but == voorbeeld??? ' Opentimer3 (Timer_Int_On & T3_16BIT_RW & T3_SOURCE_INT & T3_PS_1_8 & T3_SYNC_EXT_OFF & T3_SOURCE_CCP) ' fout ' OpenTimer3 (Timer_INT_ON & T3_16BIT_RW & T3_PS_1_8 & T3_SYNC_EXT_OFF) ' fout ' OpenTimer3 (0xFFFF & Timer_INT_On & T3_16BIT_RW) ' OpenTimer3(T3_8BIT_RW & T3_SOURCE_EXT & T3_PS_1_1 & T3_SYNC_EXT_OFF) ' copied from manual, fout!!! ' OpenTimer3(TIMER_INT_OFF & T3_16BIT_RW & T3_SOURCE_INT & T3_PS_1_8) ' doing it this way seems to work: Clear T3CON Clear PIR2BITS_TMR3IF ' clear IRQ flag Set PIE2BITS_TMR3IE ' irq on 'T3_OSC1En_On () ' macro - sets T3CON Clear Tim3 ' Clear TMR3L And TMR3H registers Set RCONbits_IPEN ' Enable priority interrupts Clear IPR2bits_TMR3IP ' Set Timer3 as a low priority interrupt source ' we can also set T3Con in one instruction as: T3CON = %10110001 ' oef, now it works... ' bit 7 = 16 bit mode ' bit 6,3 = 0, 0 ' bit 5,4 = 1:8 prescale ' bit 2 = 0 ' bit 1 = 0 Internal clock = Fosc/4 ' bit 0 : 1= enable timer 3, 0= disable ' maximum count = 52.42ms, 1 tick =0.8uS, freq.=19Hz ' Set up priority interrupts. ' IPR1bits_TMR1IP = 0 ' Set Timer1 as a low priority interrupt source ' INTCONbits_PEIE = 1 ' Enable peripheral interrupts ' INTCONbits_GIE = 1 ' Enable global interrupts ' Open the ADC: ' not used on this board. ' Fosc/32 ' Right justified for 10-bit operation ' Tad value of 0 ' Vref+ at Vcc : Vref- at Gnd ' Make AN0 an analogue input ' ' OpenADC(ADC_FOSC_32 & ADC_RIGHT_JUST & ADC_0_TAD, ADC_REF_VDD_VSS, ADC_1ANA) ' start the main program loop: LOOP: ' Create an infinite loop Bytein = HRSIn ' Read data from the serial buffer, with no timeout ' Start the midi parser. Midi_Parse: If Bytein > Control_Status Then ' here higher statusses are not implemented. If Bytein > 253 Then '254 = midiclock, 255= reset 'midiclock can interrupt all other msg's... '255 had to be intercepted since thats what we 'get when no new byte flows in (?) GoTo Check_Timers 'throw away... Else Clear statusbyte 'reset the status byte GoTo Check_Timers 'throw away End If EndIf If StBit =1 Then 'should be faster than If Bytein > 127 Then 'status byte received, bit 7 is set Clear statusbyte 'if on another channel, the statusbyte needs a reset Select Bytein 'eqv to Select case ByteIn Case NoteOff_Status statusbyte = Bytein Set noteUit 'reset value. Cannot be 0 !!! Set release '0 is a valid midi note! Case NoteOn_Status statusbyte = Bytein Set noteAan '= 255 Set velo '= 255 ' Case Keypres_Status 'could be used for note repetitions ' statusbyte = Bytein ' notePres = 255 ' pres = 255 Case Control_Status ' used statusbyte = Bytein Set Ctrl Set value ' Case ProgChange_Status ' could be used ' statusbyte = Bytein ' prog = 255 ' Case Aftertouch_Status ' not used here ' statusbyte = Bytein ' Set aft ' Case Pitchbend_Status ' statusbyte = Bytein ' pblsb = 255 ' pbmsb = 255 End Select Else 'midi byte is 7 bits Select statusbyte Case 0 'not a message for this channel GoTo Check_Timers 'disregard Case NoteOff_Status If noteUit = 255 Then noteUit = Bytein Else If Bytein > 0 Then release = Bytein 'message complete, so we can do the action... Else release = CC14 EndIf 'release = release << 2 ' 15.03.2014 , shift left 2 = x 4 'now release is byte1 of demptime ' we could implement release value=1 as no damping for that note. If CC64 = 0 Then ' we only use the dampers if sustain is OFF Select noteUit ' wellicht moeten we hier de release waarden vervierdubbelen of meer nog... ' done now by shifting 8 bits. (V1.2) Case 48 Set VelFlags0.0 ' start velo-timer: Cnt.Word0 = CntLw veltim0 = Cnt + demptime 'Minvel + release Set Demp48 Case 49 Set VelFlags0.1 Cnt.Word0 = CntLw veltim1 = Cnt + demptime ' Minvel + release Set Demp49 Case 50 Set VelFlags0.2 Cnt.Word0 = CntLw veltim2 = Cnt + demptime 'Minvel + release Set Demp50 Case 51 Set VelFlags0.3 Cnt.Word0 = CntLw veltim3 = Cnt + demptime 'Minvel + release Set Demp51 Case 52 Set VelFlags0.4 Cnt.Word0 = CntLw veltim4 = Cnt + demptime 'Minvel + release Set Demp52 Case 53 Set VelFlags0.5 Cnt.Word0 = CntLw veltim5 = Cnt + demptime 'Minvel + release Set Demp53 Case 54 Set VelFlags0.6 Cnt.Word0 = CntLw veltim6 = Cnt + demptime ' Minvel + release Set Demp54 Case 55 Set VelFlags0.7 Cnt.Word0 = CntLw veltim7 = Cnt + demptime 'Minvel + release Set Demp55 Case 56 Set Velflags1.0 Cnt.Word0 = CntLw veltim8 = Cnt + demptime 'Minvel + release Set Demp56 Case 57 Set Velflags1.1 Cnt.Word0 = CntLw veltim9 = Cnt + demptime 'Minvel + release Set Demp57 Case 58 Set Velflags1.2 Cnt.Word0 = CntLw veltim10 = Cnt + demptime 'Minvel + release Set Demp58 Case 59 Set Velflags1.3 Cnt.Word0 = CntLw veltim11 = Cnt + demptime 'Minvel + release Set Demp59 Case 60 Set Velflags1.4 Cnt.Word0 = CntLw veltim12 = Cnt + demptime 'Minvel + release Set Demp60 Case 61 Set Velflags1.5 Cnt.Word0 = CntLw veltim13 = Cnt + demptime 'Minvel + release Set Demp61 Case 62 Set Velflags1.6 Cnt.Word0 = CntLw veltim14 = Cnt + demptime 'Minvel + release Set Demp62 Case 63 Set Velflags1.7 Cnt.Word0 = CntLw veltim15 = Cnt + demptime 'Minvel + release Set Demp63 ' further notes (64-78) are for the next board. Case 112 Clear Lite112 Case 113 Clear Lite113 Case 114 Clear Lite114 Case 115 Clear Lite115 End Select Else 'if sustain is ON we still have to switch off lights... Select noteUit Case 112 Clear Lite112 Case 113 Clear Lite113 Case 114 Clear Lite114 Case 115 Clear Lite115 End Select EndIf Set noteUit '= 255 'reset EndIf 'GoTo Check_Timers Case NoteOn_Status If noteAan = 255 Then noteAan = Bytein Else velo = Bytein If velo = 0 Then If CC64 = 0 Then 'release = CC14 << 2 ' x 4 release = CC14 ' release = demptime.byte1 Select noteAan Case 48 Set VelFlags0.0 ' start velo-timer: Cnt.Word0 = CntLw veltim0 = Cnt + demptime 'Minvel + release Set Demp48 Case 49 Set VelFlags0.1 Cnt.Word0 = CntLw veltim1 = Cnt + demptime 'Minvel + release Set Demp49 Case 50 Set VelFlags0.2 Cnt.Word0 = CntLw veltim2 = Cnt + demptime 'Minvel + release Set Demp50 Case 51 Set VelFlags0.3 Cnt.Word0 = CntLw veltim3 = Cnt + demptime 'Minvel + release Set Demp51 Case 52 Set VelFlags0.4 Cnt.Word0 = CntLw veltim4 = Cnt + demptime 'Minvel + release Set Demp52 Case 53 Set VelFlags0.5 Cnt.Word0 = CntLw veltim5 = Cnt + demptime 'Minvel + release Set Demp53 Case 54 Set VelFlags0.6 Cnt.Word0 = CntLw veltim6 = Cnt + demptime' Minvel + release Set Demp54 Case 55 Set VelFlags0.7 Cnt.Word0 = CntLw veltim7 = Cnt + demptime 'Minvel + release Set Demp55 Case 56 Set Velflags1.0 Cnt.Word0 = CntLw veltim8 = Cnt + demptime 'Minvel + release Set Demp56 Case 57 Set Velflags1.1 Cnt.Word0 = CntLw veltim9 = Cnt + demptime 'Minvel + release Set Demp57 Case 58 Set Velflags1.2 Cnt.Word0 = CntLw veltim10 = Cnt + demptime 'Minvel + release Set Demp58 Case 59 Set Velflags1.3 Cnt.Word0 = CntLw veltim11 = Cnt + demptime 'Minvel + release Set Demp59 Case 60 Set Velflags1.4 Cnt.Word0 = CntLw veltim12 = Cnt + demptime 'Minvel + release Set Demp60 Case 61 Set Velflags1.5 Cnt.Word0 = CntLw veltim13 = Cnt + demptime 'Minvel + release Set Demp61 Case 62 Set Velflags1.6 Cnt.Word0 = CntLw veltim14 = Cnt + demptime 'Minvel + release Set Demp62 Case 63 Set Velflags1.7 Cnt.Word0 = CntLw veltim15 = Cnt + demptime 'Minvel + release Set Demp63 ' further notes (64-78) are for the next board. Case 112 Clear Lite112 Case 113 Clear Lite113 Case 114 Clear Lite114 Case 115 Clear Lite115 End Select Else Select Case noteAan Case 112 Clear Lite112 Case 113 Clear Lite113 Case 114 Clear Lite114 Case 115 Clear Lite115 End Select End If Else ' should we clear the dampers in fact? ' if we do not do it, we can play with the dampers on if we set the release value high enough. ' we use CC16 to leave both things possible. If CC16 = 0 Then ' this is the default behaviour Select noteAan Case 48 Clear VelFlags0.0 Clear Demp48 Case 49 Clear VelFlags0.1 Clear Demp49 Case 50 Clear VelFlags0.2 Clear demp50 Case 51 Clear VelFlags0.3 Clear demp51 Case 52 Clear VelFlags0.4 Clear Demp52 Case 53 Clear VelFlags0.5 Clear Demp53 Case 54 Clear VelFlags0.6 Clear Demp54 Case 55 Clear VelFlags0.7 Clear Demp55 Case 56 Clear Velflags1.0 Clear Demp56 Case 57 Clear Velflags1.1 Clear Demp57 Case 58 Clear Velflags1.2 Clear Demp58 Case 59 Clear Velflags1.3 Clear Demp59 Case 60 Clear Velflags1.4 Clear Demp60 Case 61 Clear Velflags1.5 Clear Demp61 Case 62 Clear Velflags1.6 Clear Demp62 Case 63 Clear Velflags1.7 Clear Demp63 Case 112 Set Lite112 Case 113 Set Lite113 Case 114 Set Lite114 Case 115 Set Lite115 End Select Else ' if CC16 is non-zero... ' we let the damper timers run out. ' here we just just do the lights Select noteAan Case 112 Set Lite112 Case 113 Set Lite113 Case 114 Set Lite114 Case 115 Set Lite115 End Select EndIf EndIf Set noteAan EndIf 'GoTo Check_Timers ' Case Keypres_Status 'used for lite flashing on Fa-Hub ' 'in used by PIC2 for fingerings !!! ' If notePres = 255 Then ' notePres = Bytein ' Else ' pres = Bytein ' 'GoSub KeyPres ' EndIf ' GoTo Check_Timers Case Control_Status 'this is where the action takes place for controllers If Ctrl = 255 Then Ctrl = Bytein Else value = Bytein GoSub Controller EndIf 'GoTo Check_Timers ' Case ProgChange_Status ' could be used to select alternative fingering lookups ' If prog = 255 Then 'single byte message ' prog = Bytein 'weak coding... ' GoSub ProgChange ' EndIf ' Case Aftertouch_Status ' If aft = 255 Then ' aft = Bytein ' GoSub Aftertouch ' EndIf ' GoTo Check_Timers End Select EndIf Check_Timers: ' here we check the Task counters and compare them with the 32 bit cnt value ' using the Velflags dword variable: If VelFlags0 > 0 Then 'if any bit is set here, there is a timer running ' with the while-wend construction we have a guarantee that we will ' never miss any output .. bug: would wait until all timers time-out... ' to speed up things, we could first check for the smallest of the veltim's ' and only compare that one with the counter. If VelFlags0.0 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim0 Then Clear Demp48 Clear VelFlags0.0 ' one shot EndIf EndIf If VelFlags0.1 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim1 Then Clear Demp49 Clear VelFlags0.1 ' one shot EndIf EndIf If VelFlags0.2 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim2 Then Clear Demp50 Clear VelFlags0.2 ' one shot EndIf EndIf If VelFlags0.3 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim3 Then Clear Demp51 Clear VelFlags0.3 ' one shot EndIf EndIf If VelFlags0.4 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim4 Then Clear Demp52 Clear VelFlags0.4 ' one shot EndIf EndIf If VelFlags0.5 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim5 Then Clear Demp53 Clear VelFlags0.5 ' one shot EndIf EndIf If VelFlags0.6 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim6 Then Clear Demp54 Clear VelFlags0.6 ' one shot EndIf EndIf If VelFlags0.7 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim7 Then Clear Demp55 Clear VelFlags0.7 ' one shot EndIf EndIf EndIf ' tweede groep van 8 beaters/timers: If Velflags1 > 0 Then If Velflags1.0 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim8 Then Clear Demp56 Clear Velflags1.0 EndIf EndIf If Velflags1.1 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim9 Then Clear Demp57 Clear Velflags1.1 EndIf EndIf If Velflags1.2 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim10 Then Clear Demp58 Clear Velflags1.2 EndIf EndIf If Velflags1.3 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim11 Then Clear Demp59 Clear Velflags1.3 EndIf EndIf If Velflags1.4 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim12 Then Clear Demp60 Clear Velflags1.4 EndIf EndIf If Velflags1.5 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim13 Then Clear Demp61 Clear Velflags1.5 EndIf EndIf If Velflags1.6 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim14 Then Clear Demp62 Clear Velflags1.6 EndIf EndIf If Velflags1.7 = 1 Then Cnt.Word0 = CntLw If Cnt >= veltim15 Then Clear Demp63 Clear Velflags1.7 EndIf EndIf EndIf GoTo LOOP ' end of the main loop 'KeyPres: ' ' not implemented on this board ' notePres = 255 'Return 'ProgChange: ' prog = 255 'this is not realy required 'Return 'Pitchbend: ' 'only implemented on dsPIC based robots, irrelevant here ' set pblsb '= 255 'Return 'Aftertouch: '' 'this is the channel aftertouch, affecting any playing note '' 'used for fingered vibrato '' 'the value of aft is used to set the vibrato speed. Minimum freq=19Hz/2 = 9.54Hz ' ' coding using timer3: ' If aft > 0 Then ' Clear T3CONBITS_TMR3ON ' stop timer ' CC31 = aft ' VibratoPeriod = CC31 << 9 '* CC31 ' Tim3 = VibratoPeriod ' Set T3CONBITS_TMR3ON ' restart timer ' Else ' Clear CC31 ' Clear VibratoPeriod ' Clear T3CONBITS_TMR3ON ' stop timer ' EndIf ' Set aft ' reset 'Return Controller: Select Ctrl Case 14 ' damping force controller (damping time in fact) CC14 = value Case 15 CC15 = value If CC15 = 0 Then GoSub DampersUp EndIf If CC15 = 127 Then GoSub DampersDown EndIf Case 16 CC16 = value ' when 0, note on's will always release the damper. ' when not zero, it becomes possible to strike the notes with the dampers on Case 64 ' sustain controller If value < 64 Then Clear CC64 Else Set CC64 ' sustain on= dampers disabled. GoSub DampersUp EndIf Case 66 'on/off for the robot If value = 0 Then Clear PowerOn 'CC66.0 =0 GoSub PowerDown Else Set PowerOn ' CC66.0 =1 CC14 = 40 ' reset to default Clear CC64 ' reset to sustain off Clear CC15 Clear CC16 ' here we reset all controllers to their cold boot value EndIf Case 123 GoSub PowerDown End Select Set Ctrl 'mandatory reset Return DampersUp: Clear VelFlags0 'stop all running timers Clear Velflags1 Clear Demp48 Clear Demp49 ' = 0 Clear Demp50 ' = 0 Clear Demp51 ' = 0 Clear Demp52 ' = 0 Clear Demp53 ' = 0 Clear Demp54 ' = 0 Clear Demp55 ' = 0 Clear Demp56 ' = 0 Clear Demp57 ' = 0 Clear Demp58 ' = 0 Clear Demp59 ' = 0 Clear Demp60 ' = 0 Clear Demp61 ' = 0 Clear Demp62 ' = 0 Clear Demp63 ' = 0 Return DampersDown: Clear VelFlags0 'stop all running timers Clear Velflags1 Set Demp48 Set Demp49 ' = 1 Set Demp50 ' = 1 Set Demp51 ' = 1 Set Demp52 ' = 1 Set Demp53 ' = 1 Set Demp54 ' = 1 Set Demp55 ' = 1 Set Demp56 ' = 1 Set Demp57 ' = 1 Set Demp58 ' = 1 Set Demp59 ' = 1 Set Demp60 ' = 1 Set Demp61 ' = 1 Set Demp62 ' = 1 Set Demp63 ' = 1 Return PowerDown: 'should switch off all solenoids and devices activated Clear VelFlags0 'stop all running timers Clear Velflags1 Clear CntHw ' reset timer ' Low Dempx is no good, as it affects the TRIS settings Clear Demp48 Clear Demp49 ' = 0 Clear Demp50 ' = 0 Clear Demp51 ' = 0 Clear Demp52 ' = 0 Clear Demp53 ' = 0 Clear Demp54 ' = 0 Clear Demp55 ' = 0 Clear Demp56 ' = 0 Clear Demp57 ' = 0 Clear Demp58 ' = 0 Clear Demp59 ' = 0 Clear Demp60 ' = 0 Clear Demp61 ' = 0 Clear Demp62 ' = 0 Clear Demp63 ' = 0 Clear Lite112 Clear Lite113 Clear Lite114 Clear Lite115 Return '[EOF]