'**************************************************************** '* Name : Fa_Hub.BAS * '* Author : Godfried-Willem RAES * '* Notice : Copyleft (c) 2011 Logosoft Public Domain * '* Date : 27-04-2011 * '* Version : 1.2 * '* Notes : Based On Ob-hub code model, V3.1 * '**************************************************************** '15.10.2010: First version by us. ' PIC: 18F2525 On MidiHub board, motor, sensors, lites '18.10.2010: Further coding. ' Analog tilt sensor design with Penny + Giles device. ' For -60 degree to + 60 degree we should read values between 102 and 922 from the ADC ' For -45 degree to + 45 degree we should read values between 205 and 819 from the ADC ' reduced to 7 bits, with 64 as center value we get 25 and 102 as extremes for 45 degrees '23.10.2010: V2.1: much better, but we still oscilate on standstill. ' V2.3: try with varying the PWM frequency in function of traject '24.10.2010: V2.7 with integrator and hardware change: 270nF cap. between mosfets. '25.10.2010: V2.8 using trigonometric functions and taking into account climbing or falling ' movement. Integration left out. Suggestion of Kristof Lauwers... '26.10.2010: Further research and development. Works fine as far as traject is conscerned, but ' we still have overshoot.. V2.9: small slowdown added when approaching soll value. ' V3.1: ' This version works, but we have to control maxspeed with CC23 ' on vertical, without oscillation this value has to be 28 (in midi) ' on forward, it can be set to 56 ' speed of movement depends on this controller. '----------------------------------------------------------- '20.04.2011: Ob code, version 3.1 used as model for the Fa hub board ' pin assignations are a bit different though. Ob must have an earlier board version... ' motor parameters have to be changed. Its a very different mechanism after all. '25.04.2011: First tests on the actual robot. ' Lite0 has a strange behaviour. '26.04.2011: Start works on the motor coding. ' CC21 sets the minimum speed for the motor ' CC22 sets the soll-position (destination) ' CC23 sets the maximum speed for the motor Include "18F2525.inc" 'version for the fa board. (40MHz) 'Include "18F2520.inc" 'also possible. (40MHz) 'Include "18F25K20.inc" 'for test & debug on an Amicus board. (64MHz) ' Mapping defines for midi-events on pin outputs and inputs: ' lights: $define Lite122 PORTC.5 ' X11-2 on ob: PORTC.4 $define Lite123 PORTC.4 ' X11-3 on ob: PORTC.5 $define Lite124 PORTB.0 ' X12-2 on ob: PORTC.3 $define Lite125 PORTB.1 ' X12-3 on ob: X12-2 $define Lite126 PORTC.3 ' X15-2 eye right $define Lite127 PORTC.0 ' X15-3 eye left $define BlueLed PORTA.3 'position reached indicator. $define GreenLed PORTA.4 'for code monitoring and debug - movement to the left (backwards) $define YellowLed PORTA.5 'for code monitoring and debug - movement to the right (forwards) $define Sensor PORTA.0 'input port - Penny& Giles tilt sensor 'red LED for debug: $define Debug_Led PORTB.5 ' for testing - red led - watchdog ' configure the input and output pins: TRISA = %01000111 'bits set to 0 are output, 1 = input TRISB = %11100000 TRISC = %11000000 'RC1 en RC2 zijn pwm outputs and must be set to output 'RC6 en RC7 zijn USART I/O and must be set to input 'constant definitions: 'initialisations for the midi input parser: Symbol Midichannel = 15 ' Fa_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 'application specific constants Symbol NrTasks = 6 ' maximum 16 'Symbol PWMFreq2 = PWMminF * 2 ' PWMminF is processor dependent. 'Symbol PWMFreq3 = PWMminF * 3 ' declared in the processor include 'Symbol PWMFreq4 = PWMminF * 4 Symbol MinPos = 36 '50 ' 1.96V op sensor, waarde 401 in 10bits resolutie, = ca 10 degrees backwards Symbol MaxPos = 84 '74 '102 ' 2.89V op sesnor, waarde 592 in 10 bits resolutie, = 10 degrees frontal ' 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 All_Digital = True ' not the case here!!! ' Declare Hserial_Clear = On ' should clear on errors. Bytes get lost of course... This must be 31250 for MIDI ' Create variables Dim CntHw As Word System 'used in the timer0 interrupt, to create a 32 bit timer Dim CntLw As TMR0L.Word 'this is the trick to read both TMR0L and TMR0H 'it makes Cntlw the low word of cnt 'We still have to copy the contents to Cnt ' 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 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 Byte System 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 newtim As Dword System Dim VelFlags As Word System ' bits 0 - 15 used as flags for active timers Dim VelFlags0 As VelFlags.Byte0 ' alias for bits 0-7 Dim VelFlags1 As VelFlags.Byte1 ' bits 8-15 - not used in this code. Dim CC21 As Byte System ' motor minimum speed pwm Dim CC22 As Byte System ' motor soll-position 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 Cnt As Dword System '32 bit counter Dim Lites As Byte System 'bits used as flags ' Dim SensorMin As Word System ' Dim SensorMax As Word System Dim SensorVal As Word System 'holds the 10bit value read from ADC0 Dim TmpVal As Word System Dim nowval As Byte System '7 bit and shifted value of above. Dim oldval As Byte System Dim tBit As Byte System 'for sampling rate bit Dim MinSpeed As Byte System 'minimum pwm value for the motor to rotate Dim MaxSpeed As Byte System 'maximum pwm value for the motor Dim Traj As Word System Dim Speed As Word System Dim angle As Word System ' Dim ud As Byte System 'v2.8 ' Dim falling As ud.0 ' Dim climbing As ud.1 Dim Iangle As Byte 'v2.8 angle in integer radians. '----------------------------------------------------------------------------------------- ' Load the USART Interrupt handler And buffer read subroutines into memory Include "Midi_Irq.inc" ' our own version for UART And Timer0 Interrupt Include "Timers.inc" ' required for velo support with timed pulses and periods. 'Include "DwordArrays.inc" ' support for dword arrays. Include "ADC.inc" ' Load the ADC macros into the program 'framework for a multitasker: Dim Task_rsi[NrTasks] As Word 'task reschedule interval (period), if 0 the task is not active 'max. value limited to 65535. For longer periods, it will have to 'become dword!!! Dim Velmsb[NrTasks] As Word 'the application for velo-timers, is in fact just a one-shot task Dim VelLsb[NrTasks] As Word 'DeclareDwordArray(TimeVals , NrTasks) 'alternative using the macro's. [not yet used] ' assigning values syntax: DwordArray Timvals,[i], value ' reading values syntax: value = DwordArray TimVals,[i] 'make sure we initialize those pins on start up: 'fault?: there should be no executable statements outside the main program. Low Lite122 'midi note 0 Low Lite123 Low Lite124 Low Lite125 Low Lite126 'midi note 4 Low Lite127 'midi note 5 Low Debug_Led HPWM 2, 255, PWMminF 'motor direction - RC1 HPWM 1, 255, PWMminF 'motor speed off - inverted pwm - connected to RC2 Low GreenLED Low YellowLed Low BlueLED Clear CC66 CC22 = 64 'thus on cold boot, the bassoon will go to vertical position MinSpeed = 10 'cc21 MaxSpeed = 10 'cc23 - 56 on ob '----------------------------------------------------------------------------------------- ' Main program starts here MAIN: High Debug_Led DelayMS 50 ' wait for stability Low Debug_Led 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 Opentimer0 (Timer_INT_On & T0_16BIT & T0_SOURCE_INT & T0_PS_1_256) ' Setup the High priorities for the interrupts ' Open the ADC: ' 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 '= 255 'reset value. Cannot be 0 !!! Set release '= 255 '0 is a valid midi note! Case NoteOn_Status statusbyte = Bytein Set noteAan '= 255 Set velo '= 255 Case Keypres_Status 'used for lights - no longer. statusbyte = Bytein Set notePres '= 255 Set pres '= 255 Case Control_Status ' this is the main thing to listen to.... statusbyte = Bytein Set Ctrl '= 255 Set value '= 255 ' Case ProgChange_Status ' statusbyte = Bytein ' prog = 255 ' Case Aftertouch_Status ' statusbyte = Bytein ' aft = 255 ' 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 release = Bytein 'message complete, so we can do the action... Select noteUit Case 0 Clear Lites.0 Clear VelFlags0.0 'Low Lite122 = sets TRIS also Clear Lite122 ' = 0 ' one machine cycle only Case 1 Clear Lites.1 Clear VelFlags0.1 Clear Lite123 '= 0 Case 2 Clear Lites.2 Clear VelFlags0.2 Clear Lite124 '= 0 Case 3 Clear Lites.3 Clear VelFlags0.3 Clear Lite125 '= 0 Case 4 Clear Lites.4 Clear VelFlags0.4 Clear Lite126 '= 0 Case 5 Clear Lites.5 Clear VelFlags0.5 Clear Lite127 '= 0 End Select Set noteUit '= 255 'reset EndIf GoTo Check_Timers Case NoteOn_Status If noteAan = 255 Then noteAan = Bytein Else velo = Bytein If velo = 0 Then Select noteAan Case 0 Clear Lites.0 '= 0 Clear VelFlags0.0 Clear Lite122 '= 0 Case 1 Clear Lites.1 '= 0 Clear VelFlags0.1 Clear Lite123 '= 0 Case 2 Clear Lites.2 '= 0 Clear VelFlags0.2 Clear Lite124 '= 0 Case 3 Clear Lites.3 '= 0 Clear VelFlags0.3 Clear Lite125 '= 0 Case 4 Clear Lites.4 '= 0 Clear VelFlags0.4 Clear Lite126 '= 0 Case 5 Clear Lites.5 '= 0 Clear VelFlags0.5 Clear Lite127 '= 0 End Select Set noteAan '= 255 'reset !!! GoTo Check_Timers 'jump out EndIf 'omleiding van de kode naar keypres: If noteAan < 6 Then If velo < 127 Then notePres = noteAan pres = velo GoSub KeyPres Else ' plain ON without flashing Select noteAan Case 0 Set Lites.0 Clear VelFlags0.0 Set Lite122 '= 1 Case 1 Set Lites.1 Clear VelFlags0.1 'so flashing is reset Set Lite123 '= 1 Case 2 Set Lites.2 Clear VelFlags0.2 Set Lite124 '= 1 Case 3 Set Lites.3 Clear VelFlags0.3 Set Lite125 '= 1 Case 4 Set Lites.4 Clear VelFlags0.4 Set Lite126 '= 1 Case 5 Set Lites.5 Clear VelFlags0.5 Set Lite127 '= 1 End Select EndIf End If Set noteAan '= 255 'reset EndIf GoTo Check_Timers Case Keypres_Status 'used for lite flashing speed modulation 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 ' If prog = 255 Then 'single byte message ' prog = Bytein 'weak coding... ' GoSub ProgChange ' EndIf 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 If VelFlags0.0 = 1 Then veltim.Word1 = Velmsb[0] veltim.Word0 = VelLsb[0] Cnt.Word1 = CntHw Cnt.Word0 = CntLw 'read counter If Cnt >= veltim Then GoSub Task0 'note 0 lite122 EndIf If VelFlags0.1 = 1 Then veltim.Word1 = Velmsb[1] veltim.Word0 = VelLsb[1] Cnt.Word1 = CntHw Cnt.Word0 = CntLw 'read counter If Cnt >= veltim Then GoSub Task1 'note 1 lite123 EndIf If VelFlags0.2 = 1 Then veltim.Word1 = Velmsb[2] veltim.Word0 = VelLsb[2] Cnt.Word1 = CntHw Cnt.Word0 = CntLw 'read counter If Cnt >= veltim Then GoSub Task2 'note 2 lite124 EndIf If VelFlags0.3 = 1 Then veltim.Word1 = Velmsb[3] veltim.Word0 = VelLsb[3] Cnt.Word1 = CntHw Cnt.Word0 = CntLw 'read counter If Cnt >= veltim Then GoSub Task3 'note 3 lite125 EndIf If VelFlags0.4 = 1 Then veltim.Word1 = Velmsb[4] veltim.Word0 = VelLsb[4] Cnt.Word1 = CntHw Cnt.Word0 = CntLw 'read counter If Cnt >= veltim Then GoSub Task4 'note 4 lite126 EndIf If VelFlags0.5 = 1 Then veltim.Word1 = Velmsb[5] veltim.Word0 = VelLsb[5] Cnt.Word1 = CntHw Cnt.Word0 = CntLw 'read counter If Cnt >= veltim Then GoSub Task5 'note 5 lite127 EndIf Else If CntHw > 0xFF Then Clear CntHw EndIf Motor_Check: Cnt.Word0 = CntLw ' read counter If Cnt.10 <> tBit Then ' Cnt.14 sets the sampling rate at 4 S/s ' Cnt.13 at 8 S/s ' Cnt.12 at 16 S/s ' Cnt.11 at 32 S/s ' Cnt.10 at 64 S/s ' was Cnt.12 in code version 2.0 on tBit = Cnt.10 SensorVal = ReadADC(0) ' Read the ADC value from the tilt sensor - using the macro 'SensorVal = ADIn 0 ' Take a reading from AN0 (ADC channel 0) 'this is a 10 bit value, right adjusted. If SensorVal >= 256 Then TmpVal = SensorVal - 256 Else Clear TmpVal 'nowval is byte nowval = TmpVal >> 2 ' divide by 4, to get a 7 bit range again. If nowval > 127 Then nowval = 127 ' make sure we do not overflow ' Coding without integration: 'ADIn should have a 30 us wait between reads! If nowval <> oldval Then 'for monitoring sensor readout via midi-out HRSOut 160 + Midichannel, 60, nowval oldval = nowval EndIf If SensorVal > 511 Then ' forward position of the bassoon angle = SensorVal - 511 'sensorval ought to move between 102 and 922 (10 Bits) for -60 to + 60 degrees 'in this case the normal range will be 401 to 592 (10 bits) for ca. -10 to + 10 degrees Else 'bassoon backwards angle = 512 - SensorVal 'so now we have 9 bits resolution for the absolute value of the angle EndIf 'now compare this with the Soll-value in CC22 'CC22 is only 7 bit Select nowval Case CC22 'switch off motor power. THIS WORKS 'the gears are strong enough to hold the bassoon in place. HPWM 2, 255, PWMminF 'dir HPWM 1, 255, PWMminF 'speed inverted PWM !!! 'we should obtain the same result with: ' High MotorDir ' HPWM 1, 255, PWMminF 'in fact, as long as both PWM values are the same, 'the motor will be stopped. If PowerOn = 0 Then Clear GreenLED Clear YellowLED Else Set GreenLED Set YellowLED EndIf Set BlueLED GoTo LOOP Case > CC22 ' huidige positie groter dan sollpos 'motor CW - achterwaarts 'sensor values must go down. 'motor speed should be function of length of traject to go 'traject is: traj = nowval - CC22 'but, a minimum torque -depending on the angle- is required to start up. 'here we try to implement the effect of the weight of the load. Iangle = angle >>3 'reduce traject to quadrant 0-64 (6-bit resolution) ' Iangle runs from 0 - 64 for a 60 degree traject Isin from 0 - 127 ' from 0 - 48 for a 45 degree traject Isin from 0 - 117 'our values will run from 0 to xx, much smaller Traj = nowval - CC22 If nowval < 64 Then 'falling backwards: whether cc22 > 63 of CC22 < 63 does not matter 'motorforce can be small, as weight helps movement 'speed = traj * (128 - Isin Iangle) ' min: 1 x ( 128 ... 1) ' max: 63 x ( 128 ... 1) Speed = 128 - Isin Iangle Speed = Speed * Traj Else 'motor will be climbing 'motorforce should be large Speed = Traj * 2 * Isin Iangle 'V3.1 End If Speed = Speed Min MaxSpeed 'faster coding for setting the limit Speed = Speed Max MinSpeed ' for testing 26.04.2011 HPWM 2, 0, PWMminF HPWM 1, Speed, PWMminF Clear GreenLED Clear BlueLED Set YellowLED GoTo LOOP Case < CC22 ' seinpos < sollpos Traj = CC22 - nowval Iangle = angle >>3 'reduce traject to quadrant 0-64 If nowval < 64 Then ' < 52 Then 'motor will be climbing 'motorforce must be medium high 'V3.1: 'Speed = Traj * 2 * Isin Iangle Speed = Traj + Isin Iangle ' medium force Else 'motor will be falling 'regardless the value of CC22 'motorforce can be low 'V3.1: 'speed = Traj * (128 - Isin Iangle) Speed = 128 - Isin Iangle Speed = Speed * Traj EndIf Speed = Speed Min MaxSpeed Speed = Speed Max MinSpeed ' for testing 26.04.2011 HPWM 2, Speed, PWMminF HPWM 1, 0, PWMminF Set GreenLED Clear YellowLED Clear BlueLED GoTo LOOP End Select EndIf GoTo LOOP ' end of the main loop KeyPres: 'the note to which the pressure should be applied is passed in NotePres, the value in Pres 'here we use it for flashing lights on Fa. Select notePres Case 0 If Lites.0 = 1 Then Set VelFlags0.0 Cnt.Word0 = CntLw 'read timer Cnt.Word1 = CntHw Task_rsi[0] = (~pres & 127) << 9 veltim = Cnt + Task_rsi[0] 'add the period duration Velmsb[0] = veltim.Word1 VelLsb[0] = veltim.Word0 Else Clear VelFlags0.0 Clear Lite122 EndIf Case 1 If Lites.1 = 1 Then Set VelFlags0.1 Cnt.Word0 = CntLw 'read timer Cnt.Word1 = CntHw Task_rsi[1] = (~pres & 127) << 9 veltim = Cnt + Task_rsi[1] 'add the period duration Velmsb[1] = veltim.Word1 VelLsb[1] = veltim.Word0 Else Clear VelFlags0.1 Clear Lite123 EndIf Case 2 If Lites.2 = 1 Then Set VelFlags0.2 Cnt.Word0 = CntLw 'read timer Cnt.Word1 = CntHw Task_rsi[2] = (~pres & 127) << 9 veltim = Cnt + Task_rsi[2] 'add the period duration Velmsb[2] = veltim.Word1 VelLsb[2] = veltim.Word0 Else Clear VelFlags0.2 Clear Lite124 EndIf Case 3 If Lites.3 = 1 Then Set VelFlags0.3 Cnt.Word0 = CntLw 'read timer Cnt.Word1 = CntHw Task_rsi[3] = (~pres & 127) << 9 veltim = Cnt + Task_rsi[3] 'add the period duration Velmsb[3] = veltim.Word1 VelLsb[3] = veltim.Word0 Else Clear VelFlags0.3 Clear Lite125 EndIf Case 4 If Lites.4 = 1 Then Set VelFlags0.4 Cnt.Word0 = CntLw 'read timer Cnt.Word1 = CntHw Task_rsi[4] = (~pres & 127) << 9 veltim = Cnt + Task_rsi[4] 'add the period duration Velmsb[4] = veltim.Word1 VelLsb[4] = veltim.Word0 Else Clear VelFlags0.4 Clear Lite126 EndIf Case 5 If Lites.5 = 1 Then Set VelFlags0.5 Cnt.Word0 = CntLw 'read timer Cnt.Word1 = CntHw Task_rsi[5] = (~pres & 127) << 9 veltim = Cnt + Task_rsi[5] 'add the period duration Velmsb[5] = veltim.Word1 VelLsb[5] = veltim.Word0 Else Clear VelFlags0.5 Clear Lite127 EndIf End Select Set notePres '= 255 Return ProgChange: Set prog '= 255 'this is not realy required Return Pitchbend: 'only implemented on dsPIC based robots Set pblsb '= 255 Return Aftertouch: 'this is the channel aftertouch, affecting all notes Set aft '= 255 'not mandatory Return Controller: Select Ctrl Case 21 ' maybe it would be better not to allow users to send this controller.. CC21 = value 'HRSout Control_Status, 21, CC21 ' for development we use this controller to steer the minimum speed required ' for the motor to run. MinSpeed = value Case 22 CC22 = value If CC22 < MinPos Then CC22 = MinPos '36-84 for 20 degree traject If CC22 > MaxPos Then CC22 = MaxPos Case 23 'for code development only MaxSpeed = 1 + value Case 66 'on/off for the robot If value = 0 Then Clear PowerOn 'CC66.0 GoSub PowerDown Else Set PowerOn 'CC66.0 CC22 = 64 'start with vertical position EndIf Case 123 GoSub AllNotesOff End Select Set Ctrl '= 255 'mandatory reset Return AllNotesOff: 'should this do something to the motor??? NO. 'maybe just reduce maxspeed to 56 'MaxSpeed = 56 Clear VelFlags0 'stop all running timers Clear Lite122 Clear Lite123 Clear Lite124 Clear Lite125 Clear Lite126 Clear Lite127 'no change on motor speed!!! 'no motor turn off Low Debug_Led Clear Lites Return PowerDown: 'should return the motor to vertical position and than switch off Clear VelFlags0 'stop all running timers Clear Lite122 '= 0 Clear Lite123 '= 0 Clear Lite124 '= 0 Clear Lite125 '= 0 Clear Lite126 '= 0 Clear Lite127 '= 0 CC22 = 64 'this should make the motor move ' MaxSpeed = 56 'making sure we have no oscillations. ' CC23 = 27 Low Debug_Led Clear Lites Return Task0: If Lites.0 = 0 Then Clear VelFlags0.0 'stop task, as lite is switched off Clear Lite122 '= 0 Else 'reload task0 - light Set VelFlags0.0 'can just stay set veltim = Cnt + Task_rsi[0] 'add the period duration Velmsb[0] = veltim.Word1 VelLsb[0] = veltim.Word0 Toggle Lite122 EndIf Return Task1: If Lites.1 = 0 Then Clear VelFlags0.1 'stop task, as lite is switched off Clear Lite123 ' = 0 Else 'reload task1 light: Set VelFlags0.1 'can just stay set veltim = Cnt + Task_rsi[1] 'add the period duration in Task_rsi[1] Velmsb[1] = veltim.Word1 VelLsb[1] = veltim.Word0 Toggle Lite123 EndIf Return Task2: If Lites.2 = 0 Then Clear VelFlags0.2 'stop task, as lite is switched off Clear Lite124 Else 'reload task2 - light Set VelFlags0.2 'can just stay set veltim = Cnt + Task_rsi[2] 'add the period duration Velmsb[2] = veltim.Word1 VelLsb[2] = veltim.Word0 Toggle Lite124 EndIf Return Task3: If Lites.3 = 0 Then Clear VelFlags0.3 'stop task, as lite is switched off Clear Lite125 Else 'reload task3 - light Set VelFlags0.3 'can just stay set veltim = Cnt + Task_rsi[3] 'add the period duration Velmsb[3] = veltim.Word1 VelLsb[3] = veltim.Word0 Toggle Lite125 EndIf Return Task4: If Lites.4 = 0 Then Clear VelFlags0.4 'stop task, as lite is switched off Clear Lite126 Else 'reload task4 - light Set VelFlags0.4 'can just stay set veltim = Cnt + Task_rsi[4] 'add the period duration Velmsb[4] = veltim.Word1 VelLsb[4] = veltim.Word0 Toggle Lite126 EndIf Return Task5: If Lites.5 = 0 Then Clear VelFlags0.5 'stop task, as lite is switched off Clear Lite127 Else 'reload task5 - light Set VelFlags0.5 'can just stay set veltim = Cnt + Task_rsi[5] 'add the period duration Velmsb[5] = veltim.Word1 VelLsb[5] = veltim.Word0 Toggle Lite127 EndIf Return '[EOF]