' ******************************************************************** ' * PIC firmware for the robot * ' * pulse and hold coding * ' * coded by dr.Godfried-Willem Raes * ' * http://www.logosfoundation.org/instrum_gwr/flut/picworks * ' * source code development directory: * ' * Flut_PH.bas * ' * Version 1.1 - 29.01.2020 * ' * Version 1.2 - 08.03.2020 * ' * Version 1.3 - 01.04.2020 * ' * Version 1.4 - 27.05.2020 * ' ******************************************************************** ' ------------------------------------------------------------------- ' 26.04.2018: Starting from the player piano code with note repeats, ' coding for , using the 18F4620 processor ' These boards serve up to 14 notes each. ' 5 boards programmed Version 1.0 ' 09.12.2019: Upgrade start to better timer0 implementation. ' Tested o.k. now ' Velo1 = 660us ' Velo64 = 26.5ms ' velo127 = 52.2ms glitchfree now! ' This be Pos code version 1.1 '---------------------------------------------------------------------- '21.01.2020: adapted to requirements for ' here we use a timer for holding the finger down after note-off ' and another timer for the velo-pulse. Same timer for all keys. ' We could also use timer3 with its interrupt for the velo-times. ' Maybe, we could implement fingered vibrato here, using timer3 as on ' For measurement of the loop-frequency, we can use port RD1 or RC3, as for these pins ' we have (sofar) no mosfet connected. '22.01.2020: considering to add fingered vibrato using aftertouch and timer3 ' lights implemented now. '25.01.2020: Start coding for automatic lights. '29.01.2020: Note range extended to 105 '08.03.2020: Changing automatic lights to use the eyes instead of the center light. ' CC69 still used to switch this on or off. '01.04.2020: note-off coding changed to solve the overlapping note problem. '09.04.2020: Firmware upload done. '27.05.2020: declare nn nnn System removed, as system is no longer documented in the manual. ' eye lites are not doing what they should do. ' BUG: we are using the velo byte for the force of the solenoids!!! This is very wrong. ' should be CC25 or CC26 - to be changed. ' Valve release on note-off does not look like working now. This is since we ' tried to implement disregard note-off if not for the playing note. ' CC25 added. ' Bug solved: we forgot to set playing_note = NoteAan in the note-on procedure. ' Velo-bug solved: CC25 introduced. Include "18F4620.inc" ' Mapping defines for midi-events on pin outputs and inputs: ' to be checked!!! $define Hol0 PORTA.2 ' C# klep ok pin4 $define Vel0 PORTA.1 ' ok pin3 $define Hol1 PORTA.0 ' D klep ok pin2 $define Vel1 PORTA.3 ' ok pin5 $define Hol2 PORTA.4 ' E-klep pin6 $define Vel2 PORTA.5 ' pin 7 $define Hol3 PORTE.0 ' F-klep $define Vel3 PORTE.1 ' pin 9 $define Hol4 PORTE.2 ' G-klep pin 10 $define Vel4 PORTB.4 $define Hol5 PORTB.3 ' A-klep $define Vel5 PORTB.2 $define Hol6 PORTB.1 ' c'-klep $define Vel6 PORTB.0 $define Hol7 PORTD.7 ' d-trilklep $define Vel7 PORTD.6 $define Hol8 PORTD.5 'd# trilklep $define Vel8 PORTD.4 ' free for lights: $define Hol9 PORTC.5 ' free $define Vel9 PORTC.4 $define Hol10 PORTD.3 ' free $define Vel10 PORTD.2 $define Hol11 PORTC.0 ' center light - note 122 $define Vel11 PORTC.1 ' can pwm $define Hol12 PORTC.2 ' eye light - can pwm note 123 $define Vel12 PORTC.3 ' not used $define Hol13 PORTD.0 ' eye light note 124 $define Vel13 PORTD.1 ' not used 'red LED for debug: $define Debug_Led PORTB.5 ' for testing - red led - watchdog - pin 38 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 most be zero to disable PSP mode on port D - gwr 20.01.2012 'this was the bug we had! 'constant definitions: Symbol Flut_low_note = 48 Symbol Flut_high_note = 105 '96 Symbol lite120 = 120 Symbol lite121 = 121 Symbol lite122 = 122 ' center Symbol lite123 = 123 ' eye Symbol lite124 = 124 ' eye Symbol Hold_Time = 65535 ' houdtijd voor de kleppen - this is 1.5 seconds ' timeunits are 22.8us here Symbol Eye_Time = 8192 ' should be 187 ms, time the eyes stay on after a note-off Symbol NrTasks = 8 Symbol LastTask = NrTasks - 1 'initialisations for the midi input parser: Symbol Midichannel = 13 ' Flut_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 CC25_default = 40 ' 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... ' Create variables: Dim Cnt As Dword '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 time As Cnt 'alias = 09.12.2019 ' Dim Tim1 As TMR1L.Word 'not used here ' Dim Tim2 As TMR2 'not used here Dim Cnt3 As Dword Dim Cnt3Hw As Cnt3.Word1 Dim Tim3 As TMR3L.Word ' same trick for timer3 ' Dim Sr as TMR0L.7 '512 S/s - this works but these DO NOT WORK!!!: ' Dim Sr as CntLw.Byte1 does not ' Dim Sr As TMR0H.0 'sampling rate bit, 256 S/s ' DIM Sr as CntLw.8 ' 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 ' midi byte read from buffer Dim StBit As Bytein.7 ' highest bit of ByteIn Dim i As Byte ' general purpose counter ' midi variables Dim statusbyte As Byte Dim noteUit As Byte ' note off + release value Dim release As Byte Dim noteAan As Byte ' note on + release value Dim velo As Byte Dim notePres As Byte ' note pressure + pressure value Dim pres As Byte Dim Ctrl As Byte ' continuous controller + value Dim value As Byte Dim prog As Byte ' program change + program-byte ' Dim aft As Byte ' channel aftertouch ' Dim pblsb As Byte ' pitch bend lsb ' Dim pbmsb As Byte ' pitch bend msb ' Dim Velflags As Word ' so we can have only 16 tasks ' Dim Holdflags As Word ' added 24.01.2016 ' Dim Waitflags As Word Dim CC25 As Byte ' attack speed for the valves Dim CC66 As Byte ' global on/off switch Dim PowerOn As CC66.0 ' handled on the hub board. Dim lites As Byte ' for lights repetition mechanism Dim cc69 As Byte ' enable/disable automatic lights Dim Rate0 As Word ' used for flashing speed Dim Rate1 As Word Dim Rate2 As Word Dim Rate3 As Word Dim Rate4 As Word Dim velo0 As Word ' Dim velo13 As Word Dim klep As Byte ' 9 bits used, so it would require a word... ' if we implement the d-tril and d#tril separate, we can make it a byte Dim playing_note As Byte Dim old_note As Byte ' previous note Dim maxtim As Cnt.31 ' overflow bit, will cause timer reset after 1h45 ' Dim t As Byte ' loopcounter, running at 4 times time-clock ' Dim tog As Byte ' Dim tg As tog.0 ' divide by 4 bit Dim TimVals[NrTasks] As Dword ' lijst met timer waarden - de kleinste is eerst aan de beurt Dim Nxt As Dword ' waarde voor de eerstvolgende timer Dim idx As Byte ' index voor de eerstvolgende timer Dim Ringbuffer[256] As Byte '----------------------------------------------------------------------------------------- ' Load the USART Interrupt handler and buffer read subroutines into memory Include "flut_hub_Irq.inc" ' for UART,Timer0, Timer3 Interrupt 'Clear ' clear all RAM '----------------------------------------------------------------------------------------- Dim vels[128] As Word ' velocity lookup table in use Dim Dur[128] As Word ' duration lookup for repetitions Dim Kleppen[128] As Byte ' Main program starts here MAIN: Low Debug_Led DelayMS 10 ' wait for stability Low Vel0 Low Vel1 Low Vel2 Low Vel3 Low Vel4 Low Vel5 Low Vel6 Low Vel7 Low Vel8 Low Vel9 Low Vel10 Low Vel11 Low Vel12 Low Vel13 Low Hol0 Low Hol1 Low Hol2 Low Hol3 Low Hol4 Low Hol5 Low Hol6 Low Hol7 Low Hol8 Low Hol9 Low Hol10 Low Hol11 Low Hol12 ' eyes Low Hol13 ' eyes ' Clear lites ' Clear Velflags ' Clear Holdflags ' Clear Waitflags Set TimVals Set cc69 ' on by default CC25 = CC25_default Clear velo0 ' Clear velo13 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 ' 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 GoSub Dur_Lookup GoSub Vels_Lookup_0 ' read the default lookup table GoSub Kleppen_lookup HRSOut Ctrl, 66, 64 ' adding this dummy made the whole program work... ' we have no explanation for this behavior. ' start the main program loop: Do ' Create an infinite loop ' for loopcounter version: ' Inc t ' byte ' If t.1 = tg Then ' Btg tg ' Inc time ' dword ' EndIf ' for Timer0 version Cnt.Word0 = CntLw ' read timer 0 GetMidiIn Bytein = MidiIn ' 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. Else Clear statusbyte 'reset the status byte EndIf GoTo Check_Timers 'throw away... 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 Set velo Case Keypres_Status 'not used here statusbyte = Bytein Set notePres Set pres Case Control_Status ' controllers and switches statusbyte = Bytein Set Ctrl Set value ' Case ProgChange_Status ' used for different lookup tables ' statusbyte = Bytein ' prog = 255 ' Case Aftertouch_Status ' statusbyte = Bytein ' Set aft ' Case Pitchbend_Status ' not on this board. ' statusbyte = Bytein ' pblsb = 255 ' pbmsb = 255 EndSelect 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 release = Bytein 'message complete, so we can do the action... Select noteUit Case 48 To 93 If noteUit = playing_note Then Clear playing_note ' start note-off timer such that we hold valves unless ' a new notes comes in TimVals[0] = Cnt + Hold_Time old_note = noteUit ' so the fingering now is that for old_note Clear Vel0 Clear Vel1 Clear Vel2 Clear Vel3 Clear Vel4 Clear Vel5 Clear Vel6 Clear Vel7 Set TimVals[1] If cc69 = 255 Then TimVals[7] = Cnt + Eye_Time EndIf EndIf Case 94 If noteUit = playing_note Then Clear playing_note ' start note-off timer such that we hold valves unless ' a new notes comes in TimVals[0] = Cnt + Hold_Time old_note = noteUit ' so the fingering now is that for old_note Clear Vel0 Clear Vel1 Clear Vel2 Clear Vel3 Clear Vel4 Clear Vel5 Clear Vel6 Clear Vel7 Clear Vel8 Set TimVals[1] If cc69 = 255 Then TimVals[7] = Cnt + Eye_Time EndIf EndIf Case 95 To 105 '96 If noteUit = playing_note Then Clear playing_note ' start note-off timer such that we hold valves unless ' a new notes comes in TimVals[0] = Cnt + Hold_Time old_note = noteUit ' so the fingering now is that for old_note Clear Vel0 Clear Vel1 Clear Vel2 Clear Vel3 Clear Vel4 Clear Vel5 Clear Vel6 Clear Vel7 Set TimVals[1] If cc69 = 255 Then TimVals[7] = Cnt + Eye_Time EndIf EndIf Case lite120 ' Clear Holdflags.9 ' Clear Waitflags.9 ' Clear lites.0 Set TimVals[2] ' Clear Vel9 Clear Hol9 Case lite121 Clear Hol10 Set TimVals[3] Case lite122 'If cc69 = 0 Then Clear Hol11 Set TimVals[4] 'EndIf Case lite123 If cc69 = 0 Then Clear Hol12 Set TimVals[5] EndIf Case lite124 If cc69 = 0 Then Clear Hol13 Set TimVals[6] EndIf EndSelect Set noteUit ' reset GoTo resort ' mandatory, as we changed timers! EndIf GoTo Check_Timers Case NoteOn_Status If noteAan = 255 Then noteAan = Bytein Else velo = Bytein If velo = 0 Then Select noteAan Case 48 To 93 If noteAan = playing_note Then Clear playing_note ' start note-off timer such that we hold valves unless ' a new notes comes in TimVals[0] = Cnt + Hold_Time old_note = noteAan ' so the fingering now is that for old_note Clear Vel0 Clear Vel1 Clear Vel2 Clear Vel3 Clear Vel4 Clear Vel5 Clear Vel6 Clear Vel7 Set TimVals[1] If cc69 = 255 Then TimVals[7] = Cnt + Eye_Time EndIf EndIf Case 94 If noteAan = playing_note Then Clear playing_note ' start note-off timer such that we hold valves unless ' a new notes comes in TimVals[0] = Cnt + Hold_Time old_note = noteAan ' so the fingering now is that for old_note Clear Vel0 Clear Vel1 Clear Vel2 Clear Vel3 Clear Vel4 Clear Vel5 Clear Vel6 Clear Vel7 Clear Vel8 Set TimVals[1] If cc69 = 255 Then TimVals[7] = Cnt + Eye_Time EndIf EndIf Case 95 To 105 '96 If noteAan = playing_note Then Clear playing_note ' start note-off timer such that we hold valves unless ' a new notes comes in TimVals[0] = Cnt + Hold_Time old_note = noteAan ' so the fingering now is that for old_note Clear Vel0 Clear Vel1 Clear Vel2 Clear Vel3 Clear Vel4 Clear Vel5 Clear Vel6 Clear Vel7 Set TimVals[1] If cc69 = 255 Then TimVals[7] = Cnt + Eye_Time EndIf EndIf Case lite120 Set TimVals[2] Clear Hol9 Case lite121 Set TimVals[3] Clear Hol10 Case lite122 'If cc69 = 0 Then Set TimVals[4] Clear Hol11 'EndIf Case lite123 If cc69 = 0 Then Set TimVals[5] Clear Hol12 EndIf Case lite124 If cc69 = 0 Then Set TimVals[6] Clear Hol13 EndIf Case Else Set noteAan GoTo Check_Timers EndSelect Set noteAan GoTo resort ' mandatory as we changed timers Else Select noteAan Case 48 To 105 '96 ' cancel hold timer Set TimVals[0] klep = Kleppen[noteAan] i = Kleppen[old_note] ' here we should only apply the velo pulse to valves that ' are in the 0 state - we use CC25 here instead of velo!!! If klep.0 = 0 Then Clear Hol0 Else Set Hol0 If i.0 = 0 Then Set Vel0 EndIf If klep.1 = 0 Then Clear Hol1 Else Set Hol1 If i.1 = 0 Then Set Vel1 EndIf If klep.2 = 0 Then Clear Hol2 Else Set Hol2 If i.2 = 0 Then Set Vel2 EndIf If klep.3 = 0 Then Clear Hol3 Else Set Hol3 If i.3 = 0 Then Set Vel3 EndIf If klep.4 = 0 Then Clear Hol4 Else Set Hol4 If i.4 = 0 Then Set Vel4 EndIf If klep.5 = 0 Then Clear Hol5 Else Set Hol5 If i.5 = 0 Then Set Vel5 EndIf If klep.6 = 0 Then Clear Hol6 Else Set Hol6 If i.6 = 0 Then Set Vel6 EndIf If klep.7 = 0 Then Clear Hol7 Else Set Hol7 If i.7 = 0 Then Set Vel7 EndIf If noteAan = 94 Then Set Hol8 If old_note <> 94 Then Set Vel8 Else Clear Hol8 EndIf If cc69 = 255 Then Set TimVals[7] ' clear timer! Set Hol12 ' eyes on Set Hol13 ' eyes on EndIf playing_note = noteAan ' we forgot this! added 27.05.2020... ' now we set the velo-pulse timer with the value of CC25: velo0 = vels[CC25] TimVals[1] = Cnt + velo0 Case lite120 If velo < 127 Then Set Hol9 TimVals[2] = Cnt + Dur[velo] ' here we can use velo! Rate0 = Dur[velo] Else Set Hol9 Set TimVals[2] EndIf Case lite121 If velo < 127 Then Set Hol10 TimVals[3] = Cnt + Dur[velo] Rate1 = Dur[velo] Else Set Hol10 Set TimVals[3] EndIf Case lite122 ' If cc69 = 0 Then If velo < 127 Then Set Hol11 TimVals[4] = Cnt + Dur[velo] Rate2 = Dur[velo] Else Set Hol11 Set TimVals[4] EndIf ' EndIf Case lite123 If cc69 = 0 Then If velo < 127 Then Set Hol12 TimVals[5] = Cnt + Dur[velo] Rate3 = Dur[velo] Else Set Hol12 Set TimVals[5] EndIf EndIf Case lite124 If cc69 = 0 Then If velo < 127 Then Set Hol13 TimVals[6] = Cnt + Dur[velo] Rate4 = Dur[velo] Else Set Hol13 Set TimVals[6] EndIf EndIf Case Else Set noteAan GoTo Check_Timers EndSelect Set noteAan 'reset !!! GoTo resort EndIf EndIf GoTo Check_Timers Case Keypres_Status 'used for note repetitions 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 ' not implemented on this board. ' Case ProgChange_Status ' could be used to select alternative lookups ' If prog = 255 Then 'single byte message ' prog = Bytein 'weak coding... ' GoSub ProgChange ' EndIf ' GoTo Check_Timers Case Else GoTo Check_Timers ' no sorting EndSelect EndIf resort: GoSub SortTimers ' so we resort only if an incoming midi command changed something Check_Timers: If idx < NrTasks Then ' we moeten alleen checken wanneer er een timer loopt If Cnt >= Nxt Then ' nagaan of de eerstvolgende timer afgelopen is... ' in dit geval is de eerste timer afgelopen en moeten we de juiste aktie ondernemen: Set Nxt.31 ' timer reset, is immers afgelopen ' aan de hand van idx weten we welke timer dit is Select idx Case 0 ' dit is de hold-tijd timer voor de kleppen Clear Hol0 'C#_valve Clear Hol1 'D_valve Clear Hol2 'E_valve Clear Hol3 'F_valve Clear Hol4 ' G-valve Clear Hol5 'A_valve Clear Hol6 ' c-valve Clear Hol7 ' d-tril valve Clear Hol8 ' d#-tril valve Clear klep Set TimVals[0] Clear old_note ' following done only for debug.... ' If cc69 = 255 Then ' - now done with Timvals[7] ' Clear Hol12 ' Clear Hol13 ' Set TimVals[7] ' EndIf Case 1 ' dit moet de velo-pulse timer zijn ' 1 timer volstaat hier Clear Vel0 Clear Vel1 ' cut velo-voltages Clear Vel2 Clear Vel3 Clear Vel4 Clear Vel5 Clear Vel6 Clear Vel7 Clear Vel8 ' Set Hol1 ' switch hold voltage on - we can do this in the note-on Set TimVals[1] ' set to infinite= disable Case 2 ' lite120 Btg Hol9 TimVals[2] = Cnt + Rate0 Case 3 Btg Hol10 TimVals[3] = Cnt + Rate1 Case 4 Btg Hol11 TimVals[4] = Cnt + Rate2 Case 5 Btg Hol12 TimVals[5] = Cnt + Rate3 Case 6 Btg Hol13 TimVals[6] = Cnt + Rate4 Case 7 ' used for switching off the eyes after a note-off ' should only happen when CC69 = 255 Set TimVals[7] ' clear timer Clear Hol12 Clear Hol13 'Case Else ' ' in dit geval is idx geset ' GoTo jumpout EndSelect GoSub SortTimers ' find a new nxt and idx EndIf ' beveiliging tegen overflow crashes... ' If maxtim = 1 Then ' Clear time.word1 ' ' Clear lites ' Set TimVals ' EndIf Else ' idx > 7, no timers running, so to avoid overflows, we can reset the loop timer If maxtim = 1 Then Clear Cnt.Word1 ' 16.06.2015 EndIf ' average loop-speed: (Tektronix measurement) ' 5.5 us under no load up to 10us jittering under full load ' Btg Vel12 Loop SortTimers: 'look up the next smallest timer value in the Timvals array ' zoek de de volgende kleinste timer waarde: Set idx ' makes it 255 Set Nxt.31 ' nxt is set on entry. - for speed, we just set the highest bit For i = 0 To LastTask ' 7 = NrTasks - 1 If TimVals[i] < Nxt Then Nxt = TimVals[i] ' 8 dword comparisons idx = i EndIf Next i Return KeyPres: ' used for auto-repeat in ' adapted to 14 notes 26.04.2018 ' not implemented here Set notePres Return 'ProgChange: ' ' here we have to change the velo lookup ' ' implemented prog. changes: 0 to 7 ' ' not implemented on for the valves ' Set prog '= 255 'Return 'Pitchbend: ' Set pblsb 'Return 'Aftertouch: ' not implemented ' 'this is the channel aftertouch, affecting any playing note ' 'used for fingered vibrato in instruments such as ' 'the value of aft is used to set or modify 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 25 ' valve velocity controller CC25 = value Case 66 'on/off for the robot If value = 0 Then GoSub PowerDown Else Set cc69 Set CC66 CC25 = CC25_default EndIf Case 69 ' used to enable/disable automatic light for the eyes If value < 64 Then Clear Hol12 Clear Hol13 Set TimVals[7] Clear cc69 Else Set cc69 EndIf Case 123 'Clear Velflags 'Clear Holdflags 'Clear Waitflags 'Clear lites Set TimVals Clear Vel0 Clear Vel1 Clear Vel2 Clear Vel3 Clear Vel4 Clear Vel5 Clear Vel6 Clear Vel7 Clear Vel8 Clear Vel9 Clear Vel10 Clear Vel11 Clear Vel12 Clear Vel13 Clear Hol0 Clear Hol1 Clear Hol2 Clear Hol3 Clear Hol4 Clear Hol5 Clear Hol6 Clear Hol7 Clear Hol8 Clear Hol9 Clear Hol10 Clear Hol11 Clear Hol12 Clear Hol13 GoSub SortTimers EndSelect Set Ctrl 'mandatory reset Return PowerDown: ' must perform a controller reset!!! 'Clear Velflags 'stop all running timers 'Clear Holdflags 'Clear Waitflags Clear lites Set TimVals Set cc69 Clear CC66 CC25 = CC25_default Clear Vel0 Clear Vel1 Clear Vel2 Clear Vel3 Clear Vel4 Clear Vel5 Clear Vel6 Clear Vel7 Clear Vel8 Clear Vel9 Clear Vel10 Clear Vel11 Clear Vel12 Clear Vel13 Clear Hol0 Clear Hol1 Clear Hol2 Clear Hol3 Clear Hol4 Clear Hol5 Clear Hol6 Clear Hol7 Clear Hol8 Clear Hol9 Clear Hol10 Clear Hol11 Clear Hol12 Clear Hol13 GoSub SortTimers Return Dur_Lookup: Set Dur[0] ' durations for note repetition on pos ' the dur values are for a half period ! ' the frequencies are for the full period. Dur[1]= 23674 ' freq= 2.01144916866806 Dur[2]= 22917 ' freq= 2.07789185404056 Dur[3]= 22548 ' freq= 2.11189673669716 Dur[4]= 22185 ' freq= 2.14645245071208 Dur[5]= 21827 ' freq= 2.18165792912666 Dur[6]= 21475 ' freq= 2.21741781695216 Dur[7]= 21129 ' freq= 2.25372935865624 Dur[8]= 20789 ' freq= 2.29058865837932 Dur[9]= 20454 ' freq= 2.32810441082662 Dur[10]= 20124 ' freq= 2.36628143604888 Dur[11]= 19800 ' freq= 2.4050024050024 Dur[12]= 19481 ' freq= 2.44438414963542 Dur[13]= 19167 ' freq= 2.48442884223132 Dur[14]= 18858 ' freq= 2.52513774626406 Dur[15]= 18554 ' freq= 2.56651113609182 Dur[16]= 18255 ' freq= 2.60854821249234 Dur[17]= 17961 ' freq= 2.65124701403305 Dur[18]= 17672 ' freq= 2.69460432430102 Dur[19]= 17387 ' freq= 2.73877308443364 Dur[20]= 17107 ' freq= 2.78360014140689 Dur[21]= 16831 ' freq= 2.82924648678318 Dur[22]= 16560 ' freq= 2.87554635380722 Dur[23]= 16293 ' freq= 2.92266909832736 Dur[24]= 16030 ' freq= 2.97062056263553 Dur[25]= 15772 ' freq= 3.01921427967586 Dur[26]= 15518 ' freq= 3.06863304672301 Dur[27]= 15268 ' freq= 3.11887919957084 Dur[28]= 15022 ' freq= 3.16995390887016 Dur[29]= 14780 ' freq= 3.22185707842 Dur[30]= 14542 ' freq= 3.27458723827862 Dur[31]= 14307 ' freq= 3.32837405598991 Dur[32]= 14077 ' freq= 3.38275538957502 Dur[33]= 13850 ' freq= 3.43819838404676 Dur[34]= 13627 ' freq= 3.49446302333952 Dur[35]= 13407 ' freq= 3.55180484963434 Dur[36]= 13191 ' freq= 3.60996494724036 Dur[37]= 12978 ' freq= 3.66921310055845 Dur[38]= 12769 ' freq= 3.7292699208276 Dur[39]= 12564 ' freq= 3.79011840329892 Dur[40]= 12361 ' freq= 3.85236207580678 Dur[41]= 12162 ' freq= 3.91539612062552 Dur[42]= 11966 ' freq= 3.97952930127424 Dur[43]= 11773 ' freq= 4.04476748654104 Dur[44]= 11583 ' freq= 4.11111522222633 Dur[45]= 11397 ' freq= 4.17820896894337 Dur[46]= 11213 ' freq= 4.24677139204919 Dur[47]= 11032 ' freq= 4.3164473911392 Dur[48]= 10855 ' freq= 4.38683073413612 Dur[49]= 10680 ' freq= 4.45871232388086 Dur[50]= 10508 ' freq= 4.53169467253974 Dur[51]= 10338 ' freq= 4.60621470487982 Dur[52]= 10172 ' freq= 4.68138494092092 Dur[53]= 10008 ' freq= 4.75809828327814 Dur[54]= 9846 ' freq= 4.83638509232659 Dur[55]= 9688 ' freq= 4.91526090204868 Dur[56]= 9532 ' freq= 4.99570369482245 Dur[57]= 9378 ' freq= 5.07774020250028 Dur[58]= 9227 ' freq= 5.16083750070962 Dur[59]= 9078 ' freq= 5.24554391044807 Dur[60]= 8932 ' freq= 5.33128611946346 Dur[61]= 8788 ' freq= 5.41864447189891 Dur[62]= 8646 ' freq= 5.50763909542536 Dur[63]= 8507 ' freq= 5.59763108252588 Dur[64]= 8370 ' freq= 5.68925300108096 Dur[65]= 8235 ' freq= 5.78251944372163 Dur[66]= 8102 ' freq= 5.87744354715473 Dur[67]= 7972 ' freq= 5.97328745848565 Dur[68]= 7843 ' freq= 6.07153482328798 Dur[69]= 7717 ' freq= 6.17066834508846 Dur[70]= 7593 ' freq= 6.2714404871655 Dur[71]= 7470 ' freq= 6.37470516988589 Dur[72]= 7350 ' freq= 6.47878198898607 Dur[73]= 7231 ' freq= 6.58540279616203 Dur[74]= 7115 ' freq= 6.692768463675 Dur[75]= 7000 ' freq= 6.80272108843537 Dur[76]= 6888 ' freq= 6.91333443946684 Dur[77]= 6777 ' freq= 7.02656745153425 Dur[78]= 6667 ' freq= 7.14250001785625 Dur[79]= 6560 ' freq= 7.25900116144019 Dur[80]= 6454 ' freq= 7.37822243865008 Dur[81]= 6350 ' freq= 7.49906261717285 Dur[82]= 6248 ' freq= 7.62148649472593 Dur[83]= 6147 ' freq= 7.74671345681595 Dur[84]= 6048 ' freq= 7.87351977828168 Dur[85]= 5951 ' freq= 8.00185643069192 Dur[86]= 5855 ' freq= 8.13305680940181 Dur[87]= 5760 ' freq= 8.26719576719577 Dur[88]= 5668 ' freq= 8.40138454817354 Dur[89]= 5576 ' freq= 8.54000136640022 Dur[90]= 5486 ' freq= 8.68010346683332 Dur[91]= 5398 ' freq= 8.82160941442157 Dur[92]= 5311 ' freq= 8.96611704369189 Dur[93]= 5225 ' freq= 9.11369332421964 Dur[94]= 5141 ' freq= 9.26260408851344 Dur[95]= 5058 ' freq= 9.41460016193112 Dur[96]= 4977 ' freq= 9.56782150272204 Dur[97]= 4897 ' freq= 9.72412653033441 Dur[98]= 4818 ' freq= 9.88357152740714 Dur[99]= 4740 ' freq= 10.0462125778581 Dur[100]= 4664 ' freq= 10.2099158702932 Dur[101]= 4589 ' freq= 10.3767809150245 Dur[102]= 4515 ' freq= 10.546854400675 Dur[103]= 4442 ' freq= 10.7201818142836 Dur[104]= 4370 ' freq= 10.89680723548 Dur[105]= 4300 ' freq= 11.0741971207087 Dur[106]= 4231 ' freq= 11.2547973573736 Dur[107]= 4162 ' freq= 11.4413857806458 Dur[108]= 4095 ' freq= 11.6285830571545 Dur[109]= 4029 ' freq= 11.8190736210096 Dur[110]= 3964 ' freq= 12.012877805007 Dur[111]= 3901 ' freq= 12.206882240207 Dur[112]= 3838 ' freq= 12.4072557631703 Dur[113]= 3776 ' freq= 12.6109765940274 Dur[114]= 3715 ' freq= 12.8180478113183 Dur[115]= 3655 ' freq= 13.0284672008338 Dur[116]= 3596 ' freq= 13.2422268128608 Dur[117]= 3538 ' freq= 13.4593124983176 Dur[118]= 3481 ' freq= 13.6797034240298 Dur[119]= 3425 ' freq= 13.9033715676051 Dur[120]= 3370 ' freq= 14.1302811925957 Dur[121]= 3316 ' freq= 14.3603883048998 Dur[122]= 3262 ' freq= 14.5981139236811 Dur[123]= 3210 ' freq= 14.8345942738466 Dur[124]= 3158 ' freq= 15.0788624506167 Dur[125]= 3107 ' freq= 15.3263751590111 Dur[126]= 3057 ' freq= 15.5770518871598 Dur[127]= 3008 ' freq= 15.8308004052685 ' rescaling for the new timer0 version: [09.12.2019] For i = 1 To 127 Dur[i] = Dur[i] >> 1 ' divide by 2 Next i Return Vels_Lookup_0: ' lookup table for the velocity controlled pulse durations ' first test: ' resolution is 6.2 us. ' 21 = 130 us (meting 21.01.2016) ' vels[1] = 88 ' should be 550 microseconds ' maxvel = 44ms, or 44ms / 6.2us = 7096 units ' stepsize = (7096 - 88) / 126 = 55.6 ' For i = 2 To 127 ' vels[i] = vels[i-1] + 55 ' Next i ' resultaat: ' 1 = 88 units = 1ms ' 127 = 7096 units = 70ms ' benadering 2: resolution = 10.5 us (op grond van vorige meting) vels[1] = 52 ' maxvel = 44ms or 44000/10.5 = 4190 units ' stepsize = (4190 - 52) / 126 = 32.8 For i = 2 To 127 vels[i] = vels[i-1] + 32.8 Next i ' resultaat: [23.01.2016, 18u10] ' 1 = 52 => 550 us ' 127 = 4190 => 44ms ' dit komt overeen met prog change 0 to boards 1 tot 9 in pp2-firmware versie 2005. ' rescaling 09.12.2019: For i = 1 To 127 vels[i] = vels[i] >> 1 ' divide by 2 Next i ' meting 09.12.2019: ' velo = 1 => 660us ' velo = 64 => 26.5ms ' velo = 127 => 52.2 ms Return Vels_Lookup_1: ' velo lookup scale prog.change 1 Same range as 0 but logarithmic vels[1]= 52 ' duur= .000546 vels[2]= 56 ' duur= .000588 vels[3]= 58 ' duur= .000609 vels[4]= 60 ' duur= .00063 vels[5]= 62 ' duur= .000651 vels[6]= 64 ' duur= .000672 vels[7]= 66 ' duur= .000693 vels[8]= 69 ' duur= .0007245 vels[9]= 71 ' duur= .0007455 vels[10]= 73 ' duur= .0007665 vels[11]= 76 ' duur= .000798 vels[12]= 79 ' duur= .0008295 vels[13]= 81 ' duur= .0008505 vels[14]= 84 ' duur= .000882 vels[15]= 87 ' duur= .0009135 vels[16]= 90 ' duur= .000945 vels[17]= 94 ' duur= .000987 vels[18]= 97 ' duur= .0010185 vels[19]= 100 ' duur= .00105 vels[20]= 104 ' duur= .001092 vels[21]= 107 ' duur= .0011235 vels[22]= 111 ' duur= .0011655 vels[23]= 115 ' duur= .0012075 vels[24]= 119 ' duur= .0012495 vels[25]= 123 ' duur= .0012915 vels[26]= 128 ' duur= .001344 vels[27]= 132 ' duur= .001386 vels[28]= 137 ' duur= .0014385 vels[29]= 142 ' duur= .001491 vels[30]= 147 ' duur= .0015435 vels[31]= 152 ' duur= .001596 vels[32]= 157 ' duur= .0016485 vels[33]= 163 ' duur= .0017115 vels[34]= 168 ' duur= .001764 vels[35]= 174 ' duur= .001827 vels[36]= 180 ' duur= .00189 vels[37]= 187 ' duur= .0019635 vels[38]= 193 ' duur= .0020265 vels[39]= 200 ' duur= .0021 vels[40]= 207 ' duur= .0021735 vels[41]= 214 ' duur= .002247 vels[42]= 222 ' duur= .002331 vels[43]= 230 ' duur= .002415 vels[44]= 238 ' duur= .002499 vels[45]= 246 ' duur= .002583 vels[46]= 255 ' duur= .0026775 vels[47]= 264 ' duur= .002772 vels[48]= 273 ' duur= .0028665 vels[49]= 283 ' duur= .0029715 vels[50]= 293 ' duur= .0030765 vels[51]= 303 ' duur= .0031815 vels[52]= 314 ' duur= .003297 vels[53]= 325 ' duur= .0034125 vels[54]= 336 ' duur= .003528 vels[55]= 348 ' duur= .003654 vels[56]= 360 ' duur= .00378 vels[57]= 373 ' duur= .0039165 vels[58]= 386 ' duur= .004053 vels[59]= 400 ' duur= .0042 vels[60]= 414 ' duur= .004347 vels[61]= 428 ' duur= .004494 vels[62]= 443 ' duur= .0046515 vels[63]= 459 ' duur= .0048195 vels[64]= 475 ' duur= .0049875 vels[65]= 492 ' duur= .005166 vels[66]= 509 ' duur= .0053445 vels[67]= 527 ' duur= .0055335 vels[68]= 545 ' duur= .0057225 vels[69]= 564 ' duur= .005922 vels[70]= 584 ' duur= .006132 vels[71]= 605 ' duur= .0063525 vels[72]= 626 ' duur= .006573 vels[73]= 648 ' duur= .006804 vels[74]= 671 ' duur= .0070455 vels[75]= 695 ' duur= .0072975 vels[76]= 719 ' duur= .0075495 vels[77]= 744 ' duur= .007812 vels[78]= 770 ' duur= .008085 vels[79]= 798 ' duur= .008379 vels[80]= 826 ' duur= .008673 vels[81]= 855 ' duur= .0089775 vels[82]= 885 ' duur= .0092925 vels[83]= 916 ' duur= .009618 vels[84]= 948 ' duur= .009954 vels[85]= 981 ' duur= .0103005 vels[86]= 1016 ' duur= .010668 vels[87]= 1052 ' duur= .011046 vels[88]= 1089 ' duur= .0114345 vels[89]= 1127 ' duur= .0118335 vels[90]= 1166 ' duur= .012243 vels[91]= 1207 ' duur= .0126735 vels[92]= 1250 ' duur= .013125 vels[93]= 1294 ' duur= .013587 vels[94]= 1339 ' duur= .0140595 vels[95]= 1386 ' duur= .014553 vels[96]= 1435 ' duur= .0150675 vels[97]= 1486 ' duur= .015603 vels[98]= 1538 ' duur= .016149 vels[99]= 1592 ' duur= .016716 vels[100]= 1648 ' duur= .017304 vels[101]= 1706 ' duur= .017913 vels[102]= 1766 ' duur= .018543 vels[103]= 1828 ' duur= .019194 vels[104]= 1892 ' duur= .019866 vels[105]= 1959 ' duur= .0205695 vels[106]= 2028 ' duur= .021294 vels[107]= 2099 ' duur= .0220395 vels[108]= 2173 ' duur= .0228165 vels[109]= 2249 ' duur= .0236145 vels[110]= 2328 ' duur= .024444 vels[111]= 2410 ' duur= .025305 vels[112]= 2495 ' duur= .0261975 vels[113]= 2583 ' duur= .0271215 vels[114]= 2674 ' duur= .028077 vels[115]= 2768 ' duur= .029064 vels[116]= 2865 ' duur= .0300825 vels[117]= 2966 ' duur= .031143 vels[118]= 3070 ' duur= .032235 vels[119]= 3178 ' duur= .033369 vels[120]= 3290 ' duur= .034545 vels[121]= 3405 ' duur= .0357525 vels[122]= 3525 ' duur= .0370125 vels[123]= 3649 ' duur= .0383145 vels[124]= 3777 ' duur= .0396585 vels[125]= 3910 ' duur= .041055 vels[126]= 4048 ' duur= .042504 vels[127]= 4190 ' duur= .043995 For i = 1 To 127 vels[i] = vels[i] >> 1 Next i Return Vels_Lookup_2: ' lookup table for the velocity controlled pulse durations ' minvel = 500us or, 500us / 10.5us = 47.6 units ' maxvel = 27ms or, 27000us / 10.5us = 2571 units ' stepsize = (2571 - 47.6) / 126 = 20.02 vels[1] = 47 For i = 2 To 127 vels[i] = vels[i-1] + 20 Next i For i = 1 To 127 vels[i] = vels[i] >> 1 Next i Return Vels_Lookup_3: ' lookup table for the velocity controlled pulse durations ' minvel = 480 us or, 45.7 units ' maxvel = 17ms or, 17000us / 10.5us = 1619 units ' stepsize = (1619 - 45) / 126 = 12.49 vels[1] = 46 For i = 2 To 127 vels[i] = vels[i-1] + 12.49 Next i For i = 1 To 127 vels[i] = vels[i] >> 1 Next i Return ' velo lookup scale prog.change 4 Same range as 2 but logarithmic Vels_Lookup_4: vels[1]= 47 ' duur= .0004935 vels[2]= 50 ' duur= .000525 vels[3]= 52 ' duur= .000546 vels[4]= 53 ' duur= .0005565 vels[5]= 55 ' duur= .0005775 vels[6]= 57 ' duur= .0005985 vels[7]= 59 ' duur= .0006195 vels[8]= 60 ' duur= .00063 vels[9]= 62 ' duur= .000651 vels[10]= 64 ' duur= .000672 vels[11]= 66 ' duur= .000693 vels[12]= 69 ' duur= .0007245 vels[13]= 71 ' duur= .0007455 vels[14]= 73 ' duur= .0007665 vels[15]= 75 ' duur= .0007875 vels[16]= 78 ' duur= .000819 vels[17]= 80 ' duur= .00084 vels[18]= 83 ' duur= .0008715 vels[19]= 86 ' duur= .000903 vels[20]= 88 ' duur= .000924 vels[21]= 91 ' duur= .0009555 vels[22]= 94 ' duur= .000987 vels[23]= 97 ' duur= .0010185 vels[24]= 100 ' duur= .00105 vels[25]= 103 ' duur= .0010815 vels[26]= 107 ' duur= .0011235 vels[27]= 110 ' duur= .001155 vels[28]= 114 ' duur= .001197 vels[29]= 117 ' duur= .0012285 vels[30]= 121 ' duur= .0012705 vels[31]= 125 ' duur= .0013125 vels[32]= 129 ' duur= .0013545 vels[33]= 133 ' duur= .0013965 vels[34]= 137 ' duur= .0014385 vels[35]= 142 ' duur= .001491 vels[36]= 146 ' duur= .001533 vels[37]= 151 ' duur= .0015855 vels[38]= 156 ' duur= .001638 vels[39]= 161 ' duur= .0016905 vels[40]= 166 ' duur= .001743 vels[41]= 171 ' duur= .0017955 vels[42]= 177 ' duur= .0018585 vels[43]= 182 ' duur= .001911 vels[44]= 188 ' duur= .001974 vels[45]= 194 ' duur= .002037 vels[46]= 200 ' duur= .0021 vels[47]= 207 ' duur= .0021735 vels[48]= 213 ' duur= .0022365 vels[49]= 220 ' duur= .00231 vels[50]= 227 ' duur= .0023835 vels[51]= 234 ' duur= .002457 vels[52]= 242 ' duur= .002541 vels[53]= 250 ' duur= .002625 vels[54]= 258 ' duur= .002709 vels[55]= 266 ' duur= .002793 vels[56]= 274 ' duur= .002877 vels[57]= 283 ' duur= .0029715 vels[58]= 292 ' duur= .003066 vels[59]= 302 ' duur= .003171 vels[60]= 311 ' duur= .0032655 vels[61]= 321 ' duur= .0033705 vels[62]= 332 ' duur= .003486 vels[63]= 342 ' duur= .003591 vels[64]= 353 ' duur= .0037065 vels[65]= 364 ' duur= .003822 vels[66]= 376 ' duur= .003948 vels[67]= 388 ' duur= .004074 vels[68]= 401 ' duur= .0042105 vels[69]= 413 ' duur= .0043365 vels[70]= 427 ' duur= .0044835 vels[71]= 440 ' duur= .00462 vels[72]= 454 ' duur= .004767 vels[73]= 469 ' duur= .0049245 vels[74]= 484 ' duur= .005082 vels[75]= 499 ' duur= .0052395 vels[76]= 515 ' duur= .0054075 vels[77]= 532 ' duur= .005586 vels[78]= 549 ' duur= .0057645 vels[79]= 567 ' duur= .0059535 vels[80]= 585 ' duur= .0061425 vels[81]= 603 ' duur= .0063315 vels[82]= 623 ' duur= .0065415 vels[83]= 643 ' duur= .0067515 vels[84]= 663 ' duur= .0069615 vels[85]= 684 ' duur= .007182 vels[86]= 706 ' duur= .007413 vels[87]= 729 ' duur= .0076545 vels[88]= 752 ' duur= .007896 vels[89]= 776 ' duur= .008148 vels[90]= 801 ' duur= .0084105 vels[91]= 827 ' duur= .0086835 vels[92]= 853 ' duur= .0089565 vels[93]= 881 ' duur= .0092505 vels[94]= 909 ' duur= .0095445 vels[95]= 938 ' duur= .009849 vels[96]= 968 ' duur= .010164 vels[97]= 999 ' duur= .0104895 vels[98]= 1031 ' duur= .0108255 vels[99]= 1064 ' duur= .011172 vels[100]= 1098 ' duur= .011529 vels[101]= 1133 ' duur= .0118965 vels[102]= 1169 ' duur= .0122745 vels[103]= 1207 ' duur= .0126735 vels[104]= 1246 ' duur= .013083 vels[105]= 1285 ' duur= .0134925 vels[106]= 1327 ' duur= .0139335 vels[107]= 1369 ' duur= .0143745 vels[108]= 1413 ' duur= .0148365 vels[109]= 1458 ' duur= .015309 vels[110]= 1505 ' duur= .0158025 vels[111]= 1553 ' duur= .0163065 vels[112]= 1603 ' duur= .0168315 vels[113]= 1654 ' duur= .017367 vels[114]= 1707 ' duur= .0179235 vels[115]= 1761 ' duur= .0184905 vels[116]= 1818 ' duur= .019089 vels[117]= 1876 ' duur= .019698 vels[118]= 1936 ' duur= .020328 vels[119]= 1998 ' duur= .020979 vels[120]= 2062 ' duur= .021651 vels[121]= 2128 ' duur= .022344 vels[122]= 2196 ' duur= .023058 vels[123]= 2267 ' duur= .0238035 vels[124]= 2339 ' duur= .0245595 vels[125]= 2414 ' duur= .025347 vels[126]= 2491 ' duur= .0261555 vels[127]= 2571 ' duur= .0269955 For i = 1 To 127 vels[i] = vels[i] >> 1 Next i Return ' velo lookup scale prog.change 5 Same range as 3 but logarithmic Vels_Lookup_5: vels[1]= 46 ' duur= .000483 vels[2]= 49 ' duur= .0005145 vels[3]= 50 ' duur= .000525 vels[4]= 51 ' duur= .0005355 vels[5]= 53 ' duur= .0005565 vels[6]= 54 ' duur= .000567 vels[7]= 56 ' duur= .000588 vels[8]= 58 ' duur= .000609 vels[9]= 59 ' duur= .0006195 vels[10]= 61 ' duur= .0006405 vels[11]= 63 ' duur= .0006615 vels[12]= 64 ' duur= .000672 vels[13]= 66 ' duur= .000693 vels[14]= 68 ' duur= .000714 vels[15]= 70 ' duur= .000735 vels[16]= 72 ' duur= .000756 vels[17]= 74 ' duur= .000777 vels[18]= 76 ' duur= .000798 vels[19]= 78 ' duur= .000819 vels[20]= 81 ' duur= .0008505 vels[21]= 83 ' duur= .0008715 vels[22]= 85 ' duur= .0008925 vels[23]= 88 ' duur= .000924 vels[24]= 90 ' duur= .000945 vels[25]= 93 ' duur= .0009765 vels[26]= 95 ' duur= .0009975 vels[27]= 98 ' duur= .001029 vels[28]= 101 ' duur= .0010605 vels[29]= 104 ' duur= .001092 vels[30]= 107 ' duur= .0011235 vels[31]= 110 ' duur= .001155 vels[32]= 113 ' duur= .0011865 vels[33]= 116 ' duur= .001218 vels[34]= 119 ' duur= .0012495 vels[35]= 123 ' duur= .0012915 vels[36]= 126 ' duur= .001323 vels[37]= 130 ' duur= .001365 vels[38]= 134 ' duur= .001407 vels[39]= 137 ' duur= .0014385 vels[40]= 141 ' duur= .0014805 vels[41]= 145 ' duur= .0015225 vels[42]= 149 ' duur= .0015645 vels[43]= 154 ' duur= .001617 vels[44]= 158 ' duur= .001659 vels[45]= 162 ' duur= .001701 vels[46]= 167 ' duur= .0017535 vels[47]= 172 ' duur= .001806 vels[48]= 177 ' duur= .0018585 vels[49]= 182 ' duur= .001911 vels[50]= 187 ' duur= .0019635 vels[51]= 192 ' duur= .002016 vels[52]= 198 ' duur= .002079 vels[53]= 203 ' duur= .0021315 vels[54]= 209 ' duur= .0021945 vels[55]= 215 ' duur= .0022575 vels[56]= 221 ' duur= .0023205 vels[57]= 227 ' duur= .0023835 vels[58]= 234 ' duur= .002457 vels[59]= 241 ' duur= .0025305 vels[60]= 247 ' duur= .0025935 vels[61]= 254 ' duur= .002667 vels[62]= 262 ' duur= .002751 vels[63]= 269 ' duur= .0028245 vels[64]= 277 ' duur= .0029085 vels[65]= 285 ' duur= .0029925 vels[66]= 293 ' duur= .0030765 vels[67]= 301 ' duur= .0031605 vels[68]= 310 ' duur= .003255 vels[69]= 318 ' duur= .003339 vels[70]= 327 ' duur= .0034335 vels[71]= 337 ' duur= .0035385 vels[72]= 346 ' duur= .003633 vels[73]= 356 ' duur= .003738 vels[74]= 366 ' duur= .003843 vels[75]= 377 ' duur= .0039585 vels[76]= 387 ' duur= .0040635 vels[77]= 398 ' duur= .004179 vels[78]= 410 ' duur= .004305 vels[79]= 421 ' duur= .0044205 vels[80]= 433 ' duur= .0045465 vels[81]= 446 ' duur= .004683 vels[82]= 458 ' duur= .004809 vels[83]= 471 ' duur= .0049455 vels[84]= 485 ' duur= .0050925 vels[85]= 499 ' duur= .0052395 vels[86]= 513 ' duur= .0053865 vels[87]= 527 ' duur= .0055335 vels[88]= 542 ' duur= .005691 vels[89]= 558 ' duur= .005859 vels[90]= 574 ' duur= .006027 vels[91]= 590 ' duur= .006195 vels[92]= 607 ' duur= .0063735 vels[93]= 624 ' duur= .006552 vels[94]= 642 ' duur= .006741 vels[95]= 660 ' duur= .00693 vels[96]= 679 ' duur= .0071295 vels[97]= 698 ' duur= .007329 vels[98]= 718 ' duur= .007539 vels[99]= 738 ' duur= .007749 vels[100]= 759 ' duur= .0079695 vels[101]= 781 ' duur= .0082005 vels[102]= 803 ' duur= .0084315 vels[103]= 826 ' duur= .008673 vels[104]= 850 ' duur= .008925 vels[105]= 874 ' duur= .009177 vels[106]= 899 ' duur= .0094395 vels[107]= 924 ' duur= .009702 vels[108]= 950 ' duur= .009975 vels[109]= 977 ' duur= .0102585 vels[110]= 1005 ' duur= .0105525 vels[111]= 1034 ' duur= .010857 vels[112]= 1063 ' duur= .0111615 vels[113]= 1093 ' duur= .0114765 vels[114]= 1124 ' duur= .011802 vels[115]= 1156 ' duur= .012138 vels[116]= 1189 ' duur= .0124845 vels[117]= 1223 ' duur= .0128415 vels[118]= 1258 ' duur= .013209 vels[119]= 1294 ' duur= .013587 vels[120]= 1330 ' duur= .013965 vels[121]= 1368 ' duur= .014364 vels[122]= 1407 ' duur= .0147735 vels[123]= 1447 ' duur= .0151935 vels[124]= 1488 ' duur= .015624 vels[125]= 1531 ' duur= .0160755 vels[126]= 1574 ' duur= .016527 vels[127]= 1619 ' duur= .0169995 For i = 1 To 127 vels[i] = vels[i] >> 1 Next i Return Vels_Lookup_6: ' linear mapping that will work for all repetition frequencies ' lookup table for the velocity controlled pulse durations ' minvel = 480 us or, 45.7 units ' maxvel = 3000 units (=Dur[127] ' stepsize = (3000 - 45) / 126 = 23.45 vels[1] = 45 For i = 2 To 127 vels[i] = vels[i-1] + 23.45 Next i For i = 1 To 127 vels[i] = vels[i] >> 1 Next i Return Vels_Lookup_7: ' velo lookup scale prog.change 7 Same range as 6 but logarithmic ' log mapping that will work for all repetition speeds vels[1]= 44 ' duur= .000462 vels[2]= 47 ' duur= .0004935 vels[3]= 49 ' duur= .0005145 vels[4]= 50 ' duur= .000525 vels[5]= 52 ' duur= .000546 vels[6]= 54 ' duur= .000567 vels[7]= 56 ' duur= .000588 vels[8]= 57 ' duur= .0005985 vels[9]= 59 ' duur= .0006195 vels[10]= 61 ' duur= .0006405 vels[11]= 63 ' duur= .0006615 vels[12]= 66 ' duur= .000693 vels[13]= 68 ' duur= .000714 vels[14]= 70 ' duur= .000735 vels[15]= 72 ' duur= .000756 vels[16]= 75 ' duur= .0007875 vels[17]= 77 ' duur= .0008085 vels[18]= 80 ' duur= .00084 vels[19]= 83 ' duur= .0008715 vels[20]= 86 ' duur= .000903 vels[21]= 88 ' duur= .000924 vels[22]= 91 ' duur= .0009555 vels[23]= 95 ' duur= .0009975 vels[24]= 98 ' duur= .001029 vels[25]= 101 ' duur= .0010605 vels[26]= 104 ' duur= .001092 vels[27]= 108 ' duur= .001134 vels[28]= 112 ' duur= .001176 vels[29]= 115 ' duur= .0012075 vels[30]= 119 ' duur= .0012495 vels[31]= 123 ' duur= .0012915 vels[32]= 127 ' duur= .0013335 vels[33]= 132 ' duur= .001386 vels[34]= 136 ' duur= .001428 vels[35]= 141 ' duur= .0014805 vels[36]= 146 ' duur= .001533 vels[37]= 151 ' duur= .0015855 vels[38]= 156 ' duur= .001638 vels[39]= 161 ' duur= .0016905 vels[40]= 166 ' duur= .001743 vels[41]= 172 ' duur= .001806 vels[42]= 178 ' duur= .001869 vels[43]= 184 ' duur= .001932 vels[44]= 190 ' duur= .001995 vels[45]= 196 ' duur= .002058 vels[46]= 203 ' duur= .0021315 vels[47]= 210 ' duur= .002205 vels[48]= 217 ' duur= .0022785 vels[49]= 224 ' duur= .002352 vels[50]= 232 ' duur= .002436 vels[51]= 240 ' duur= .00252 vels[52]= 248 ' duur= .002604 vels[53]= 256 ' duur= .002688 vels[54]= 265 ' duur= .0027825 vels[55]= 274 ' duur= .002877 vels[56]= 283 ' duur= .0029715 vels[57]= 293 ' duur= .0030765 vels[58]= 303 ' duur= .0031815 vels[59]= 313 ' duur= .0032865 vels[60]= 323 ' duur= .0033915 vels[61]= 334 ' duur= .003507 vels[62]= 346 ' duur= .003633 vels[63]= 357 ' duur= .0037485 vels[64]= 369 ' duur= .0038745 vels[65]= 382 ' duur= .004011 vels[66]= 395 ' duur= .0041475 vels[67]= 408 ' duur= .004284 vels[68]= 422 ' duur= .004431 vels[69]= 436 ' duur= .004578 vels[70]= 451 ' duur= .0047355 vels[71]= 466 ' duur= .004893 vels[72]= 482 ' duur= .005061 vels[73]= 498 ' duur= .005229 vels[74]= 515 ' duur= .0054075 vels[75]= 533 ' duur= .0055965 vels[76]= 551 ' duur= .0057855 vels[77]= 569 ' duur= .0059745 vels[78]= 588 ' duur= .006174 vels[79]= 608 ' duur= .006384 vels[80]= 629 ' duur= .0066045 vels[81]= 650 ' duur= .006825 vels[82]= 672 ' duur= .007056 vels[83]= 695 ' duur= .0072975 vels[84]= 718 ' duur= .007539 vels[85]= 743 ' duur= .0078015 vels[86]= 768 ' duur= .008064 vels[87]= 794 ' duur= .008337 vels[88]= 820 ' duur= .00861 vels[89]= 848 ' duur= .008904 vels[90]= 877 ' duur= .0092085 vels[91]= 906 ' duur= .009513 vels[92]= 937 ' duur= .0098385 vels[93]= 969 ' duur= .0101745 vels[94]= 1002 ' duur= .010521 vels[95]= 1035 ' duur= .0108675 vels[96]= 1070 ' duur= .011235 vels[97]= 1107 ' duur= .0116235 vels[98]= 1144 ' duur= .012012 vels[99]= 1183 ' duur= .0124215 vels[100]= 1223 ' duur= .0128415 vels[101]= 1264 ' duur= .013272 vels[102]= 1307 ' duur= .0137235 vels[103]= 1351 ' duur= .0141855 vels[104]= 1396 ' duur= .014658 vels[105]= 1444 ' duur= .015162 vels[106]= 1493 ' duur= .0156765 vels[107]= 1543 ' duur= .0162015 vels[108]= 1595 ' duur= .0167475 vels[109]= 1649 ' duur= .0173145 vels[110]= 1705 ' duur= .0179025 vels[111]= 1762 ' duur= .018501 vels[112]= 1822 ' duur= .019131 vels[113]= 1884 ' duur= .019782 vels[114]= 1947 ' duur= .0204435 vels[115]= 2013 ' duur= .0211365 vels[116]= 2081 ' duur= .0218505 vels[117]= 2151 ' duur= .0225855 vels[118]= 2224 ' duur= .023352 vels[119]= 2299 ' duur= .0241395 vels[120]= 2377 ' duur= .0249585 vels[121]= 2457 ' duur= .0257985 vels[122]= 2541 ' duur= .0266805 vels[123]= 2626 ' duur= .027573 vels[124]= 2715 ' duur= .0285075 vels[125]= 2807 ' duur= .0294735 vels[126]= 2902 ' duur= .030471 vels[127]= 3000 ' duur= .0315 For i = 1 To 127 vels[i] = vels[i] >> 1 Next i Return Kleppen_lookup: ' lookup for the solenoids steered by the pulse-hold board For i = 0 To 47 Kleppen[i] = 0 Next i Kleppen[48] = %01111111 Kleppen[49] = %01111111 Kleppen[50] = %01111110 Kleppen[51] = %01111110 Kleppen[52] = %01111100 Kleppen[53] = %01111000 Kleppen[54] = %01110010 Kleppen[55] = %01110000 Kleppen[56] = %01110000 Kleppen[57] = %01100000 Kleppen[58] = %01001000 Kleppen[59] = %01000000 Kleppen[60] = Kleppen[48] Kleppen[61] = Kleppen[49] Kleppen[62] = Kleppen[50] Kleppen[63] = Kleppen[51] Kleppen[64] = Kleppen[52] Kleppen[65] = Kleppen[53] Kleppen[66] = Kleppen[54] Kleppen[67] = Kleppen[55] Kleppen[68] = Kleppen[56] Kleppen[69] = Kleppen[57] Kleppen[70] = Kleppen[58] Kleppen[71] = Kleppen[59] Kleppen[72] = %01000000 Kleppen[73] = 0 Kleppen[74] = %00111110 Kleppen[75] = %00111110 Kleppen[76] = %01111100 Kleppen[77] = %01111000 Kleppen[78] = %01110010 Kleppen[79] = %01110000 Kleppen[80] = %01110000 Kleppen[81] = %01100000 Kleppen[82] = %01001000 Kleppen[83] = %01000000 Kleppen[84] = %01000000 Kleppen[85] = 0 Kleppen[86] = %00110000 Kleppen[87] = %01111110 Kleppen[88] = %01101100 Kleppen[89] = %01011000 Kleppen[90] = %01010010 Kleppen[91] = %01110000 Kleppen[92] = %00110000 Kleppen[93] = %00101000 Kleppen[94] = %00001000 ' here we also need the d# valve! Kleppen[95] = %11010000 Kleppen[96] = %01111000 Kleppen[97] = 0 Kleppen[98] = %00110000 Kleppen[99] = %01111110 Kleppen[100] = %01101100 Kleppen[101] = %01011000 Kleppen[102] = %01010010 Kleppen[103] = %01110000 Kleppen[104] = %00110000 Kleppen[105] = %00101000 For i = 106 To 127 Kleppen[i] = 0 Next i Return '[EOF]