'{$STAMP BS2SX} '' '' Programmer: Craig Stuart Sapp '' Creation Date: Fri 11-Jan-2001 '' Last Modified: Tue 16-Jul-2002 '' Filename: seny2.bsx '' Based On: max1270.bsx and midi8.bsx '' Syntax: Basic Stamp IIsx '' '' Description: This program reads in samples from the Maxim 1270 '' (a 12-bit, 8 channels A/D chip) and sends an on/off '' note trigger for each sensor, if the cutoff value '' has been crossed by the sensor. Piezo sensors connected to '' the max1270 chip, and FSR connected to the rest of the BS2sx '' input pins. '' '' Sensor data storage for checking for on/off triggers: pcount con 8 ' number of piezo sensors to read fcount con 12 ' number of fsr switches to read pdata var byte(pcount) ' previous history value of continuous controllers poffset con 0 ' offset to center the piezo sensors to 64 fdata var bit(fcount) ' previous histroy of binary switches ftime var word ' RC time for FSR states fstate var bit ' current state for FSR (0=off, 1=on) 'fcutoff con 80 ' cut off for on/off state (FSRs) with max1270 chip fcutoff con 2 ' cut off for on/off state (FSRs) with RC circuit (0.0047uF) ' Higher number is more sensitive pcutoff con 1 ' cut off for cont. controllers (Piezo) pdisplay con 0 ' display piezo data on screen fdisplay con 0 ' display fsr data on screen '' Basic Stamp 2x Data I/O variables: midioutpin con 15 ' output from BS2X to MIDI line clockpin con 14 ' synchronous clock pin to control MAXIM 1270 chip outputpin con 13 ' for sending the controlbyte to the MAX1270 chip inputpin con 12 ' for reading data from MAXIM 1270 chip 'chipselect con -1 ' set to zero to activate chip (not needed for one chip) midirate con 60 ' baud mode for MIDI (60 for BS2sx, use 12 for BS2) outpause con 0 ' minimum time between MIDI messages msb con 1 ' mode for shiftout functions: msb behindclock con 2 ' mode for shiftin: msb post clock sleeptime con 50 ' time in milliseconds to wait between samples ' the MAX1270 control byte below is composed of several fields ' listed here from MSB to LSB bits: ' bit7: defines the beginning of the control byte ' bits4-6: selects the A/D channel (0-7). ' bit3: choose the A/D voltage range, 0=5v, 1=10v ' bit2: choose polar/bipolar range, 0=positive, 1=positive/negative ' bit0: choose clock mode: 0=internal, 1=external ' bits0-1: 10=standby, 11=power-down (clock mode unaffected) ' ' the control byte 1,000,00,01 means: channel 0, 0 to +5v, external clock: basiccontrol con %10001001 controlbyte var byte ' control byte for selecting channel on A/D channel var byte ' for selecting the channel to read data from ' (also used for MIDI) bytea var byte ' for holding first 5 MSBs of 12-bit sample byteb var byte ' for holding last 7 LSBs of 12-bit sample ' MIDI Variables: mididatabyte var byte ' for sending out MIDI value midichannel var byte ' which channel to send data on piezochannel con 1 ' piezo controller channel fsrchannel con 0 ' fsr controller channel oldkey var byte ' for debugging piezo data ' According to BASIC Stamp Programming Manual v1.9, page 208: ' "Unused pins that are not connected to circuitry should be set to output" ' to minimize power consumption, which is done here: DIRS = %1110111111111111 ' Don't set pins connected to input circuitry to be output, or you can ' damage the Basic Stamp. gosub ClearData ' initialize data contents to 0 top: ' Read continuous sensor data and send via MIDI if (pdisplay <> 1) then nextline5 debug "Piezo Data: " nextline5: for channel = 0 to pcount - 1 gosub ReadPiezoData next if (pdisplay <> 1) then nextline6 debug cr nextline6: ' Read FSR states and send via MIDI if changed for channel = 0 to fcount - 1 gosub ReadFSRSwitch next ' now wait a while before taking another sample pause sleeptime goto top: '''''''''''''''''''''''''''''' '' '' ReadFsrSwitch -- read states FSRs via RC circuit. '' ReadFsrSwitch: high channel pause 1 ' wait 1 millisecond rctime channel, 1, ftime if (ftime = 0) then nextline ' overflow is indicated with 0 (ignore) if (ftime > fcutoff) then nextline fstate = 1 goto afterline nextline: fstate = 0 afterline: if (fstate = fdata(channel)) then nextline2 fdata(channel) = fstate mididatabyte = fstate * 127 midichannel = fsrchannel gosub SendMidiData if (fdisplay <> 1) then afterline2 debug "FSR ", dec channel+1, " State: ", dec fstate, cr goto afterline2 nextline2: afterline2: return '''''''''''''''''''''''''''''' '' '' ReadPiezoData -- sends a command to the A/D converter chip '' requesting data on the specified channel stored in "channel" '' variable. Then the returning data is stored into the variables '' bytea (upper 7 bits) and byteb (lower 5 bits) '' ' Commands used below: ' ' SHIFTOUT outputpin, clockpin, mode, [data \ bits] ' outputpin = pin to send synchronous data on ' clockpin = pin to send synchronous clock signal ' mode = 0=LSB, 1=MSB ' data = data to send ' bits = number of bits in data field to send (default = 8); ' ' SHIFTIN inputpin, clockpin, mode, [variable \ bits] ' inputin = pin to receive synchronous data on ' clockpin = pin to send synchronous clock signal ' mode = 0=LSB, 1=MSB ' variable = location to store the bits ' bits = number of bits to input (default = 8); ' ReadPiezoData: ' create the control byte with the specified channel to sample controlbyte = basiccontrol ^ (channel << 4) ' clear the storage bytes for the sensor data (useful for debugging) bytea = 0 byteb = 0 ' first tell the MAX1270 that you want a sample shiftout outputpin, clockpin, msb, [controlbyte \ 8] ' wait 4 clock cycles until the sample is ready to be returned shiftout outputpin, clockpin, msb, [0 \ 4] ' read in the returned sample from the MAX1270 chip shiftin inputpin, clockpin, behindclock, [bytea \ 7] ' finish reading in the data (12-bit sample) shiftin inputpin, clockpin, behindclock, [byteb \ 5] midichannel = piezochannel mididatabyte = bytea - poffset if (mididatabyte < 127) then nextline3 mididatabyte = 127 nextline3: if (pdisplay <> 1) then nextline7 debug dec mididatabyte, " " nextline7: gosub SendMidiData ' debug dec ? bytea ' debug dec ? byteb ' debug cr return '''''''''''''''''''''''''''''' '' '' ClearData -- set all of the data to 0 (useful for debugging) '' ClearData: for channel = 0 to pcount - 1 pdata(channel) = 0 next fdata = 0 return '''''''''''''''''''''''''''''' '' '' SendMidiData -- send sensor data via a MIDI command through '' a TTL (5 volt) serial line at 31.25 kBit speed. '' chan var byte SendMidiData: chan = channel + 1 serout midioutpin, midirate, outpause, [$B0+midichannel, chan, mididatabyte] ' alternate MIDI test for playing the piano: ' serout midioutpin, midirate, outpause, [$80, oldkey, 64] ' serout midioutpin, midirate, outpause, [$90, mididatabyte, 64] ' oldkey = mididatabyte ' debug "MIDI SEND: ", dec chan, " ", dec mididatabyte, cr return '''''''''''''''''''''''''''''' '' '' CheckForTriggers -- if the data have crossed the trigger boundaries '' then send a note on/off. '' '' ''CheckForTriggers: '' for channel = 0 to scount - 1 '' if (datan(channel) > cutoff) and (datap(channel) > cutoff) then endit '' if (datan(channel) < cutoff) and (datap(channel) < cutoff) then endit '' if (datan(channel) > cutoff) and (datap(channel) < cutoff) then triggeron '' midibyte = 0 '' gosub SendMidiData '' goto endit '' triggeron: '' ' midibyte = 127 '' midibyte = datan(channel) '' gosub SendMidiData '' endit: '' next '' ''return