'**************************************************** '* Armite Software * '* data acquisition code for midi controllers * '* triple PIR sensor * '* by * '* dr.Godfried-Willem Raes * '* version 1.1 * '**************************************************** ' Program history: ' 15.11.2007: first version ' 17.11.2007: first debugging session. ' 23.11.2007: 8x oversampling applied. 'pin definitions DIR(0) = 1 ' output pin - for midi output DIR(1) = 0 ' nc DIR(2) = 0 ' nc DIR(3) = 0 ' nc DIR(4) = 0 ' nc DIR(5) = 0 ' pulse output from left PIR DIR(6) = 0 ' pulse output from central PIR DIR(7) = 0 ' pulse output from right PIR DIR(8) = 0 ' midi channel select msb (bit3) - sw1 DIR(9) = 0 ' midi channel select bit2 - sw2 DIR(10) = 0 ' midi channel select bit1 - sw3 DIR(11) = 0 ' midi channel select bit0 - sw4 DIR(12) = 0 ' switch bit 1 - sw5 select number of program in flash DIR(13) = 0 ' switch bit 0 - sw6 DIR(14) = 0 ' tied to +5 with 10k DIR(15) = 0 ' tied to +5 with 10k ' analog inputs: 'DIR(16) = 0 ' ref channel AD(0) 'DIR(17) = 0 ' left channel AD(1) 'DIR(18) = 0 ' center channel AD(2) 'DIR(19) = 0 ' right y channel AD(3) DIR(20) = 0 ' nc AD(4) DIR(21) = 0 ' nc AD(5) DIR(22) = 0 ' nc AD(6) DIR(23) = 0 ' nc 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 aftertouch - high nibble status byte 'ref = AD(0) ' reference voltage 'lef = AD(1) 'cen = AD(2) 'rig = AD(3) lsb = 0 msb = 0 ref = 0 lef = 0 cen = 0 rig = 0 old_lef = 0 old_rig = 0 old_cen = 0 train = 0 leftcont = 0 centercnt = 0 rightcnt = 0 pdl = 0 pdc = 0 pdr = 0 lflag = 0 cflag = 0 rflag = 0 cnt = 0 ' for examination of the data rate starttime = 0 ' const overflow = 2048 ' read dip switches for midi channel used for transmit ' note: this is signed integer basic: true = -1 ' now big endian! IF IN(11) > -1 THEN kanaal = kanaal - 1 ' lsb IF IN(10) > -1 THEN kanaal = kanaal - 2 IF IN(9) > -1 THEN kanaal = kanaal - 4 IF IN(8) > -1 THEN kanaal = kanaal - 8 ' msb statusbyte = statusbyte + kanaal ' other two input pins can be used for program selection on startup program = 3 IF IN(12) > -1 THEN program = program - 2 ' msb IF IN(13) > -1 THEN program = program - 1 ' for debug: PRINT kanaal PRINT statusbyte PRINT BAUD(0) ' for debug PRINT program SELECT CASE program CASE 0 ' send channel as set with the dip switches. - 25S/s GOTO Three_sensors CASE 1 ' send channel as set with the dip switches - maximum data rate GOTO Very_Fast CASE 2 ' central sensor only GOTO One_Sensor CASE 3 GOTO Debug_mode ENDSELECT END Three_sensors: starttime = TIMER ' for data rate measurement only cnt = 0 ' idem. ' midi coding: data kanaal 0 = analog left 0000 dddd 0ddd dddd ' data kanaal 1 = analog center 0001 dddd 0ddd dddd ' data kanaal 2 = analog right 0010 dddd 0ddd dddd ' data kanaal 3 = digital left 0100 dddd 0ddd dddd ' data kanaal 4 = digital center 0101 dddd 0ddd dddd ' data kanaal 5 = digital right 0110 dddd 0ddd dddd ' data kanaal 6 = combi digital 0111 0000 0000 0nnn DO ref = AD(0) ' scaling factor to be determined! wait 1 ref = ref + AD(0) wait 1 ref = ref + AD(0) wait 1 ref = ref + AD(0) ref = ref >> 8 ' 0-1023 offset = 512 - ref wait 1 lef = AD(1) ' 10 bits cen = AD(2) rig = AD(3) wait 10 lef = lef + AD(1) ' 11 bits -we will sample each channel 8 times to get to 13 bits cen = cen + AD(2) ' 11 bits rig = rig + AD(3) ' 11 bits IF IN(5) = 0 THEN IF leftcnt < 1023 THEN leftcnt = leftcnt + 1 ELSE ' eindtellerstand bereikt - we sturen de waarde alvast uit: TXD(0) = statusbyte TXD(0) = 48 + 7 ' msb alle drie data bits geset TXD(0) = 127 ' alle bits geset leftcnt = 0 endif train = train OR 1 lflag = -1 ELSE ' wanneer de detektor geen beweging meer geeft, sturen we de duur uit: IF lflag < 0 THEN pdl = leftcnt ' store for output leftcnt = 0 lsb = pdl AND 127 ' lowest 7 bits msb = pdl >> 7 ' highest 3 bits msb = msb OR 48 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' 0 and 48 = left channel ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) lflag = 0 endif train = train AND 6 ' &B110 ENDIF lef = lef + AD(1) + AD(1) ' 12 bits cen = cen + AD(2) + AD(2) rig = rig + AD(3) + AD(3) IF IN(6) = 0 THEN IF centercnt < 1023 THEN centercnt = centercnt + 1 'INCR centercnt ELSE TXD(0) = statusbyte TXD(0) = 64 + 7 TXD(0) = 127 centercnt = 0 endif train = train OR 2 cflag = -1 ELSE IF cflag < 0 THEN pdc = centercnt centercnt = 0 lsb = pdc AND 127 ' lowest 7 bits msb = pdc >> 7 ' highest 3 bits msb = msb OR 64 ' or 0,16,32,48,64,80,96 for each data channel ' 16 and 64 = center PIR channel - transmit midi: TXD(0) = statusbyte TXD(0) = msb TXD(0) = lsb cflag = 0 endif train = train AND 5 '&B101 ENDIF lef = lef + AD(1) wait 1 lef = lef + AD(1) ' 12.5 bits wait 1 cen = cen + AD(2) wait 1 cen = cen + AD(2) wait 1 rig = rig + AD(3) wait 1 rig = rig + AD(3) IF IN(7) = 0 THEN IF rightcnt < 1023 THEN rightcnt = rightcnt + 1 'INCR rightcnt ELSE TXD(0) = statusbyte TXD(0) = 80 + 7 TXD(0) = 127 rightcnt = 0 endif train = train OR 4 rflag = -1 ELSE IF rflag < 0 THEN pdr = rightcnt rightcnt = 0 lsb = pdr AND 127 ' lowest 7 bits msb = pdr >> 7 ' highest 3 bits msb = msb OR 80 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' 32 and 80 = right PIR channel ' transmit midi: TXD(0) = statusbyte TXD(0) = msb TXD(0) = lsb rflag = 0 ENDIF train = train AND 3 ' &B011 ENDIF lef = lef + AD(1) wait 1 lef = lef + AD(1) ' 13 bits lef = lef >> 9 ' reduce back to 10 bits lef = lef + offset ' unipolar now centered around 512 IF lef <> lef_old THEN lef = lef MAX 1023 lef = lef MIN 0 lsb = lef AND 127 ' lowest 7 bits msb = lef >> 7 ' highest 3 bits msb = msb OR 0 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) lef_old = lef ENDIF cen = cen + AD(2) wait 1 cen = cen + AD(2) cen = cen >> 9 cen = cen + offset IF cen <> cen_old THEN cen = cen MAX 1023 cen = cen MIN 0 lsb = cen AND 127 ' lowest 7 bits msb = cen >> 7 ' highest 3 bits msb = msb OR 16 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) cen_old = cen ENDIF rig = rig + AD(3) wait 1 rig = rig + AD(3) rig = rig >> 9 rig = rig + offset IF rig <> rig_old THEN rig = rig MAX 1023 rif = rig MIN 0 lsb = rig AND 127 ' lowest 7 bits msb = rig >> 7 ' highest 3 bits msb = msb OR 32 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) rig_old = rig ENDIF ' now output the pulstrain: (this is a periodic output. Unconditional and data independent. lsb = train AND 127 ' lowest 7 bits - only the lowest 3 bits are used. msb = 0 ' always 0 msb = msb OR 96 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) wait 14 ' 14 + 8 + 22 = 36 ms pacing ' zonder pacing is de lustijd 4ms (scan rate = 250 scans/second) ' deze waarde moet ons doen uitkomen op een scanrate van 25S/s ' for debug: 'print pdl,pdc,pdr, train AND 7 cnt = cnt + 1 IF (cnt MOD 1000) = 0 THEN 'PRINT lef_old, cen_old, rig_old, pdl, pdc, pdr 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. ' midi coding: data kanaal 0 = analog left 0000 dddd 0ddd dddd ' data kanaal 1 = analog right 0001 dddd 0ddd dddd ' data kanaal 2 = analog right 0010 dddd 0ddd dddd ' data kanaal 4 = digital left 0100 dddd 0ddd dddd ' data kanaal 5 = digital center 0101 dddd 0ddd dddd ' data kanaal 6 = digital right 0110 dddd 0ddd dddd ' data kanaal 7 = combi digital 0111 0000 0000 0nnn DO ref = AD(0) ' scaling factor to be determined! ref = ref >> 6 ' 0-1023 offset = 512 - ref lef = AD(1) lef = lef >> 6 lef = lef + offset ' unipolar now centered around 512 cen = AD(2) cen = cen >> 6 cen = cen + offset rig = AD(3) rig = rig >> 6 rig = rig + offset ' ca. 24 microseconds IF IN(5) = 0 THEN IF leftcnt < 1023 THEN leftcnt = leftcnt + 1 ELSE TXD(0) = statusbyte TXD(0) = 48 + 7 ' msb alle drie data bits geset TXD(0) = 127 ' alle bits geset leftcnt = 0 endif train = train OR 1 lflag = -1 ELSE IF lflag < 0 THEN pdl = leftcnt ' store for output leftcnt = 0 lsb = pdl AND 127 ' lowest 7 bits msb = pdl >> 7 ' highest 3 bits msb = msb OR 48 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' 0 and 48 = left channel ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) lflag = 0 endif train = train AND 6 ' &B110 ENDIF IF IN(6) = 0 THEN IF centercnt < 1023 THEN centercnt = centercnt + 1 'INCR centercnt ELSE TXD(0) = statusbyte TXD(0) = 64 + 7 TXD(0) = 127 centercnt = 0 endif train = train OR 2 cflag = -1 ELSE IF cflag < 0 THEN pdc = centercnt centercnt = 0 lsb = pdc AND 127 ' lowest 7 bits msb = pdc >> 7 ' highest 3 bits msb = msb OR 64 ' or 0,16,32,48,64,80,96 for each data channel ' 16 and 64 = center PIR channel - transmit midi: TXD(0) = statusbyte TXD(0) = msb TXD(0) = lsb cflag = 0 endif train = train AND 5 '&B101 ENDIF IF IN(7) = 0 THEN IF rightcnt < 1023 THEN rightcnt = rightcnt + 1 ELSE TXD(0) = statusbyte TXD(0) = 80 + 7 TXD(0) = 127 rightcnt = 0 endif train = train OR 4 rflag = -1 ELSE IF rflag < 0 THEN pdr = rightcnt rightcnt = 0 lsb = pdr AND 127 ' lowest 7 bits msb = pdr >> 7 ' highest 3 bits msb = msb OR 80 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' 32 and 80 = right PIR channel ' transmit midi: TXD(0) = statusbyte TXD(0) = msb TXD(0) = lsb rflag = 0 ENDIF train = train AND 3 ' &B011 ENDIF IF lef <> lef_old THEN lef = lef MAX 1023 lef = lef MIN 0 lsb = lef AND 127 ' lowest 7 bits msb = lef >> 7 ' highest 3 bits msb = msb OR 0 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) lef_old = lef ENDIF IF cen <> cen_old THEN cen = cen MAX 1023 cen = cen MIN 0 lsb = cen AND 127 ' lowest 7 bits msb = cen >> 7 ' highest 3 bits msb = msb OR 16 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) cen_old = cen ENDIF IF rig <> rig_old THEN rig = rig MAX 1023 rif = rig MIN 0 lsb = rig AND 127 ' lowest 7 bits msb = rig >> 7 ' highest 3 bits msb = msb OR 32 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) rig_old = rig ENDIF ' now output the pulstrain: (this is a periodic output. Unconditional and data independent. lsb = train AND 127 ' lowest 7 bits - only the lowest 3 bits are used. msb = 0 ' always 0 msb = msb OR 96 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) ' zonder pacing is de lustijd 4ms (scan rate = 250 scans/seconds '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 One_Sensor: ' code for the central PIR sensor alone. starttime = TIMER ' for data rate measurement only cnt = 0 ' idem. ' midi coding: data kanaal 0 = analog left 0000 dddd 0ddd dddd ' data kanaal 1 = analog center 0001 dddd 0ddd dddd ' data kanaal 2 = analog right 0010 dddd 0ddd dddd ' data kanaal 4 = digital left 0100 dddd 0ddd dddd ' data kanaal 5 = digital center 0101 dddd 0ddd dddd ' data kanaal 6 = digital right 0110 dddd 0ddd dddd ' data kanaal 7 = combi digital 0111 0000 0000 0nnn DO ref = AD(0) ' scaling factor to be determined! ref = ref >> 6 ' 0-1023 offset = 512 - ref cen = AD(2) cen = cen >> 6 cen = cen + offset IF IN(6) = 0 THEN IF centercnt < 1023 THEN centercnt = centercnt + 1 ELSE TXD(0) = statusbyte TXD(0) = 64 + 7 TXD(0) = 127 centercnt = 0 endif train = train OR 2 cflag = -1 ELSE IF cflag < 0 THEN pdc = centercnt centercnt = 0 lsb = pdc AND 127 ' lowest 7 bits msb = pdc >> 7 ' highest 3 bits msb = msb OR 64 ' or 0,16,32,48,64,80,96 for each data channel ' 16 and 64 = center PIR channel - transmit midi: TXD(0) = statusbyte TXD(0) = msb TXD(0) = lsb cflag = 0 endif train = train AND 5 '&B101 ENDIF IF cen <> cen_old THEN cen = cen MAX 1023 cen = cen MIN 0 lsb = cen AND 127 ' lowest 7 bits msb = cen >> 7 ' highest 3 bits msb = msb OR 16 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) cen_old = cen ENDIF ' now output the pulstrain: (this is a periodic output. Unconditional and data independent. lsb = train AND 127 ' lowest 7 bits - only the lowest 3 bits are used. msb = 0 ' always 0 msb = msb OR 96 ' or 0,16,32,48,64,80,96 for each data channel 0 = channel 0 ' transmit midi: TXD(0) = statusbyte 'CHR$(statusbyte) TXD(0) = msb 'CHR$(msb) TXD(0) = lsb 'CHR$(lsb) ' zonder pacing is de lustijd 4ms (scan rate = 250 scans/seconds wait 50 cnt = cnt + 1 IF (cnt MOD 1000) = 0 THEN PRINT "Sampling 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 Debug_Mode: ref_max = 0 ref_min = 1023 ref_avg = 652 '512 DO ref = AD(0) ref = ref >> 6 ref_avg = ((ref_avg * 63) + ref) / 64 ' 17.11.07: convergeert naar 652 lef = AD(1) lef = lef >> 6 cen = AD(2) cen = cen >> 6 rig = AD(3) rig = rig >> 6 IF ref > ref_max THEN ref_max = ref IF ref < ref_min THEN ref_min = ref PRINT ref,lef - ref_avg,cen - ref_avg,rig - ref_avg, IN(5),IN(6),IN(7), ref_avg '(ref_max + ref_min) / 2 WAIT 9 LOOP END