'**************************************************** '* Armite Software * '* data acquisition code for midi controllers * '* octal FSR pads * '* '* by * '* dr.Godfried-Willem Raes * '* version 1.1 * '**************************************************** ' Program history: ' 04.12.2007: first sketch ' 29.12.2007: Hardware finished and tested. Software version 1.0 ' 09.01.2008: Bug cleared discovered by Kristof Lauwers... 'pin definitions DIR(0) = 1 ' output pin - for midi output DIR(1) = 0 ' right thumb switch DIR(2) = 0 ' left thumb switch DIR(3) = 0 ' nc DIR(4) = 0 ' nc DIR(5) = 0 ' nc DIR(6) = 0 ' switch 1 - no pull-up here DIR(7) = 0 ' switch 2 midi channel select msb (bit3) DIR(8) = 0 ' switch 3 midi channel select bit2 DIR(9) = 0 ' switch 4 midi channel select bit1 DIR(10) = 0 ' switch 5 midi channel select bit0 DIR(11) = 0 ' switch 6 DIR(12) = 0 ' switch 7 select number of program in flash DIR(13) = 0 ' switch 8 DIR(14) = 0 ' switch 9 DIR(15) = 0 ' switch 10 ' analog inputs: - wanneer deze declares er staan, werkt de AD(x) instruktie niet meer!!! 'DIR(16) = 0 ' right little finger AD(0) 'DIR(17) = 0 ' right AD(1) 'DIR(18) = 0 ' right middle finger AD(2) 'DIR(19) = 0 ' right index finger AD(3) 'DIR(20) = 0 'left index finger AD(4) 'DIR(21) = 0 'left middle finger AD(5) 'DIR(22) = 0 'left AD(6) 'DIR(23) = 0 'left little finger AD(7) ' initialisation parameters and variable declarations BAUD(0) = 31250 ' midi baudrate, transmit using pin 0 kanaal = 15 ' midi channel - low nibble status byte ' read from dip switch setting statusbyte = 160 ' 160 voor poly key aftertouch - high nibble status byte switchbyte = 176 ' controller status byte - high nibble status byte lsb = 0 msb = 0 cnt = 0 ' for examination of the data rate starttime = 0 oa0 = 0 oa1 = 0 oa2 = 0 oa3 = 0 oa4 = 0 oa5 = 0 oa6 = 0 os7 = 0 a0 = 0 a1 = 0 a2 = 0 a3 = 0 a4 = 0 a5 = 0 a6 = 0 a7 = 0 ' read dip switches for midi channel used for transmit ' note: this is signed integer basic: true = -1 IF IN(10) > -1 THEN kanaal = kanaal - 1 ' lsb IF IN(9) > -1 THEN kanaal = kanaal - 2 IF IN(8) > -1 THEN kanaal = kanaal - 4 IF IN(7) > -1 THEN kanaal = kanaal - 8 ' msb statusbyte = statusbyte + kanaal ' other input pins can be used for program selection on startup program = 31 IF IN(11) > -1 THEN program = program -16 IF IN(12) > -1 THEN program = program -8 IF IN(13) > -1 THEN program = program - 4 IF IN(14) > -1 THEN program = program - 2 IF IN(15) > -1 THEN program = program - 1 ' lsb ' for debug: PRINT kanaal PRINT statusbyte PRINT BAUD(0) ' for debug PRINT program SELECT CASE program CASE 0 ' nothing PRINT "No program selected on start up!" END CASE 1 ' send via midi channel as set with the dip switches. - 32Scans/s GOTO Octal_Ctrl CASE 2 ' send channel as set with the dip switches - maximum data rate ' output data only if changing - 125 scans/smax. GOTO Very_Fast CASE 3 GOTO Continuous_Sampling ' constant sampling rate - good for FFT transforms on data CASE 4 ' left hand pads only GOTO Left_Hand CASE 5 ' right hand pads only GOTO Right_Hand CASE 6 GOTO Drumpad1 ' here we use note + velo implementation for direct control of percussion intruments ' TO DO: add specific progs. for Troms, Vacca, Vitello, Rotomoton, Snar... CASE 7 GOTO Debug_Mode CASE ELSE PRINT "Not yet implemented program selected on startup!" END ENDSELECT END Octal_Ctrl: starttime = TIMER ' for data rate measurement only cnt = 0 ' idem. ' midi coding: data kanaal 0 = 0000 dddd 0ddd dddd ' data kanaal 1 = 0001 dddd 0ddd dddd ' data kanaal 2 = 0010 dddd 0ddd dddd ' data kanaal 3 = 0011 dddd 0ddd dddd ' data kanaal 4 = 0100 dddd 0ddd dddd ' data kanaal 5 = 0101 dddd 0ddd dddd ' data kanaal 6 = 0110 dddd 0ddd dddd ' data kanaal 7 = 0111 dddd 0ddd dddd ' right hand: ' pink = bruin - a0 ' ringvinger = rood - a1 ' middelvinger = oranje - a2 ' wijsvinger = geel - a3 ' duim = rood - IN(1) ' left hand: ' pink = grijs - a7 ' ringvinger = purper - a6 ' middelvinger = blauw - a5 ' wijsvinger = groen - a4 ' duim = oranje - IN(2) DO a0 = AD(0) a0 = a0 >> 6 IF a0 <> oa0 THEN msb = a0 >> 7 ' shift 7 bits, so 3 bits remain in the low nibble lsb = a0 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 0 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa0 = a0 endif a1 = AD(1) a1 = a1 >> 6 IF a1 <> oa1 THEN msb = a1 >> 7 lsb = a1 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 16 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa1 = a1 endif a2 = AD(2) a2 = a2 >> 6 IF a2 <> oa2 THEN msb = a2 >> 7 lsb = a2 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 32 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa2 = a2 endif a3 = AD(3) a3 = a3 >> 6 IF a3 <> oa3 THEN msb = a3 >> 7 lsb = a3 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 48 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa3 = a3 endif a4 = AD(4) a4 = a4 >> 6 IF a4 <> oa4 THEN msb = a4 >> 7 lsb = a4 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 64 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa4 = a4 endif a5 = AD(5) a5 = a5 >> 6 IF a5 <> oa5 THEN msb = a5 >> 7 lsb = a5 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 80 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa5 = a5 endif a6 = AD(6) a6 = a6 >> 6 IF a6 <> oa6 THEN msb = a6 >> 7 lsb = a6 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 96 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa6 = a6 endif a7 = AD(7) a7 = a7 >> 6 IF a7 <> oa7 THEN msb = a7 >> 7 lsb = a7 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 112 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa7 = a7 endif ' nu juist nog de schakelaars samplen ( digitaal I/O) ' te mappen op switch controllers: bvb .70, 71 swleft = IN(1) IF swleft <> oswleft THEN IF swleft = 0 THEN TXD(0) = switchbyte TXD(0) = 70 TXD(0) = 0 ELSE TXD(0) = switchbyte TXD(0) = 70 TXD(0) = 127 endif oswleft = swleft endif swright = IN(2) IF swright <> oswright THEN IF swright = 0 THEN TXD(0) = switchbyte TXD(0) = 71 TXD(0) = 0 ELSE TXD(0) = switchbyte TXD(0) = 71 TXD(0) = 127 endif oswright = swright endif wait 31 ' deze waarde moet ons doen uitkomen op een scanrate van 32S/s 'if (cnt mod 10)= 0 then print a0,a1,a2,a3,a4,a5,a6,a7 - for debug only cnt = cnt + 1 IF (cnt MOD 1000) = 0 THEN 'PRINT swleft, swright PRINT "Scanning rate=", 1000 / ((TIMER - Starttime)/ 1000000) ,"S/s" ' note that the midi data rate may be different, since we send only changes of data! Starttime = TIMER ' in microsecond units endif LOOP END Very_Fast: starttime = TIMER ' for data rate measurement only cnt = 0 ' idem. DO a0 = AD(0) a0 = a0 >> 6 IF a0 <> oa0 THEN msb = a0 >> 7 lsb = a0 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 0 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa0 = a0 endif a1 = AD(1) a1 = a1 >> 6 IF a1 <> oa1 THEN msb = a1 >> 7 lsb = a1 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 16 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa1 = a1 endif a2 = AD(2) a2 = a2 >> 6 IF a2 <> oa2 THEN msb = a2 >> 7 lsb = a2 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 32 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa2 = a2 endif a3 = AD(3) a3 = a3 >> 6 IF a3 <> oa3 THEN msb = a3 >> 7 lsb = a3 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 48 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa3 = a3 endif a4 = AD(4) a4 = a4 >> 6 IF a4 <> oa4 THEN msb = a4 >> 7 lsb = a4 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 64 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa4 = a4 endif a5 = AD(5) a5 = a5 >> 6 IF a5 <> oa5 THEN msb = a5 >> 7 lsb = a5 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 80 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa5 = a5 endif a6 = AD(6) a6 = a6 >> 6 IF a6 <> oa6 THEN msb = a6 >> 7 lsb = a6 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 96 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa6 = a6 endif a7 = AD(7) a7 = a7 >> 6 IF a7 <> oa7 THEN msb = a7 >> 7 lsb = a7 AND 127 'msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 112 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa7 = a7 endif ' nu juist nog de schakelaars samplen ( digitaal I/O) ' te mappen op switch controllers: bvb .70, 71 swleft = IN(1) IF swleft <> oswleft THEN IF swleft = 0 THEN TXD(0) = switchbyte TXD(0) = 70 TXD(0) = 0 ELSE TXD(0) = switchbyte TXD(0) = 70 TXD(0) = 64 endif oswleft = swleft endif swright = IN(2) IF swright <> oswright THEN IF swright = 0 THEN TXD(0) = switchbyte TXD(0) = 71 TXD(0) = 0 ELSE TXD(0) = switchbyte TXD(0) = 71 TXD(0) = 64 endif oswright = swright endif cnt = cnt + 1 IF (cnt MOD 1000) = 0 THEN PRINT "Scanning rate=", 1000 / ((TIMER - Starttime)/ 1000000) ,"S/s" ' note that the midi data rate may be different, since we send only changes of data! Starttime = TIMER ' in microsecond units endif LOOP END Continuous_Sampling: Starttime = TIMER cnt = 0 DO a0 = AD(0) a0 = a0 >> 6 lsb = a0 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 0 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb a1 = AD(1) a1 = a1 >> 6 lsb = a1 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 16 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb a2 = AD(2) a2 = a2 >> 6 lsb = a2 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 32 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb a3 = AD(3) a3 = a3 >> 6 lsb = a3 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 48 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb a4 = AD(4) a4 = a4 >> 6 lsb = a4 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 64 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb a5 = AD(5) a5 = a5 >> 6 lsb = a5 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 80 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb a6 = AD(6) a6 = a6 >> 6 lsb = a6 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 96 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb a7 = AD(7) a7 = a7 >> 6 lsb = a7 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 112 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb ' hier laten we de schakelaars achterwege. cnt = cnt + 1 IF (cnt MOD 1000) = 0 THEN PRINT "Scanrate=", 1000 / ((TIMER - Starttime)/ 1000000) ,"S/s" ' 1000S/s or 125 Scans/s Starttime = TIMER ' in microsecond units endif LOOP END Left_Hand: ' code for the left hand alone ' pink = grijs - a7 ' ringvinger = purper - a6 ' middelvinger = blauw - a5 ' wijsvinger = groen - a4 ' duim = IN(2) 'starttime = TIMER ' for data rate measurement only 'cnt = 0 ' idem. DO a4 = AD(4) a4 = a4 >> 6 IF a4 <> oa4 THEN lsb = a4 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 64 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa4 = a4 endif a5 = AD(5) a5 = a5 >> 6 IF a5 <> oa5 THEN lsb = a5 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 80 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa5 = a5 endif a6 = AD(6) a6 = a6 >> 6 IF a6 <> oa6 THEN lsb = a6 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 96 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa6 = a6 endif a7 = AD(7) a7 = a7 >> 6 IF a7 <> oa7 THEN lsb = a7 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 112 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa7 = a7 endif swright = IN(2) IF swright <> oswright THEN IF swright = 0 THEN TXD(0) = switchbyte TXD(0) = 71 TXD(0) = 0 ELSE TXD(0) = switchbyte TXD(0) = 71 TXD(0) = 127 endif oswright = swright endif LOOP END Right_Hand: ' code for the right hand alone ' pink = bruin - a0 ' ringvinger = rood - a1 ' middelvinger = oranje - a2 ' wijsvinger = geel - a3 ' duim - IN(1) DO a0 = AD(0) a0 = a0 >> 6 IF a0 <> oa0 THEN lsb = a0 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 0 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa0 = a0 endif a1 = AD(1) a1 = a1 >> 6 IF a1 <> oa1 THEN lsb = a1 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 16 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa1 = a1 endif a2 = AD(2) a2 = a2 >> 6 IF a2 <> oa2 THEN lsb = a2 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 32 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa2 = a2 endif a3 = AD(3) a3 = a3 >> 6 IF a3 <> oa3 THEN lsb = a3 AND 127 msb = msb >> 7 TXD(0) = statusbyte TXD(0) = msb OR 48 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 TXD(0) = lsb oa3 = a3 endif swleft = IN(1) IF swleft <> oswleft THEN IF swleft = 0 THEN TXD(0) = switchbyte TXD(0) = 70 TXD(0) = 0 ELSE TXD(0) = switchbyte TXD(0) = 70 TXD(0) = 127 endif oswleft = swleft endif LOOP END Drumpad1: ' right hand: ' pink = bruin - a0 ' ringvinger = rood - a1 ' middelvinger = oranje - a2 ' wijsvinger = geel - a3 ' duim - IN(1) ' left hand: ' pink = grijs - a7 ' ringvinger = purper - a6 ' middelvinger = blauw - a5 ' wijsvinger = groen - a4 ' duim = IN(2) DO LOOP END Debug_Mode: ' no midi output. ' USB monitoring only starttime = TIMER ' for data rate measurement only cnt = 0 ' idem. DO a0 = AD(0) a0 = a0 >> 6 a1 = AD(1) a1 = a1 >> 6 a2 = AD(2) a2 = a2 >> 6 a3 = AD(3) a3 = a3 >> 6 a4 = AD(4) a4 = a4 >> 6 a5 = AD(5) a5 = a5 >> 6 a6 = AD(6) a6 = a6 >> 6 a7 = AD(7) a7 = a7 >> 6 PRINT a0,a1,a2,a3,a4,a5,a6,a7 ' hier laten we de schakelaars achterwege. cnt = cnt + 1 IF (cnt MOD 1000) = 0 THEN PRINT "Scanning rate=", 1000 / ((TIMER - Starttime)/ 1000000) ,"S/s" ' note that the midi data rate may be different, since we send only changes of data! Starttime = TIMER ' in microsecond units endif LOOP END