Shown below is sample DAPL code for a hypothetical tension control experiment during which the muscle is
1) - held at its original length for 20 ms
2) - released to a target force -0.1 V below the prevailing level for 20 ms
3) - shortened rapidly to a fixed length for another 20 ms
4) - returned to its original length for the remaining 40 ms of the record.
Please note that the formatting of the DAPL code has been slightly altered for HTML display purposes. Several of the 'fill' commands and a few of the processing calculations wrap over several lines and would initiate a DAP error if passed to the interpreter in their present form.
RESET // Resets DAP OPTION UNDERFLOWQ=OFF // Disable underflow error messages OPTION ERRORQ=OFF // Disable all other warnings and error messages // to prevent problems reading data back to the PC OPTION SCHEDULING=FIXED // Scheduling, buffering and quantum options OPTION BUFFERING=OFF // set for minimum latency OPTION QUANTUM=100 ;************************************************************ // Header pipes pfl MAXSIZE=65500 // Define all the pipes used in the processing pipes ptarget_force MAXSIZE=65500 // functions and set their maximum size pipes pservo MAXSIZE=65500 pipes poffset_marker MAXSIZE=65500 pipes poffset MAXSIZE=65500 pipes plastoffset MAXSIZE=65500 pipes pout MAXSIZE=65500 pipes plastout MAXSIZE=65500 pipes pfeedback MAXSIZE=65500 pipes ptrigger MAXSIZE=65500 pipes pdifference MAXSIZE=65500 pipes pamplified_diff MAXSIZE=65500 pipes pintegral MAXSIZE=65500 ;************************************************************ // The section of the code fills the processing pipes // with all of the required data fill ptrigger 32439 // The first value (TTL high) for the DAC0 channel // This channel is intended as a trigger pulse fill plastout 0 // Initial values for plastout and plastoffset fill plastoffset 0 // (required to initiate the control loop) fill pdifference 0 // Initial values for pdifference (proportional error) fill pintegral 0 0 0 0 0 0 0 0 0 // and pintegral (integral error) // required to initiate the control loop fill pservo 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // pservo values (1 per data point) fill pservo 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 // 0 implies tension control is off fill pservo 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // 1 implies tension control is on fill pservo 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 fill poffset_marker 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 // poffset_marker values (1 per data point) fill poffset_marker 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // 1 implies update poffset with current force value fill poffset_marker 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 // 0 implies leave poffset unaltered fill poffset_marker 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 fill pfl 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // pfl values (1 per data point) fill pfl 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // These are the desired DAC1 output values (the fill pfl 64 64 64 64 64 64 64 64 64 64 64 64 64 64 ... // motor command values) if tension control is off 64 64 64 64 64 64 fill pfl 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 fill ptarget_force 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // ptarget_force values (1 per data point) fill ptarget_force -65 -65 -65 -65 -65 -65 -65 -65 -65 -65 ... // These are the desired target_force points when the -65 -65 -65 -65 -65 -65 -65 -65 -65 -65 // tension control is in operation fill ptarget_force 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 fill ptarget_force 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ;************************************************************ pdef create_pipes // Create_pipes procedure ptrigger=0 // Set every ptrigger value (other than the first one) // to zero (i.e. trigger fires once, then stays low) // Simple Channel waveforms could be created on the fly // during this procedure if required end ;************************************************************ pdef control // Main control procedure // (calculates output values and sends acquired data // back to the host PC) poffset=((1-poffset_marker)*plastoffset)+(poffset_marker*ip0) // Update poffset with current force as required plastoffset=poffset // Update plastoffset which is used above pdifference=pservo*(ip0-ptarget_force-poffset) // Calculate pdifference // (the proportional error if servo is on, 0 otherwise) pamplified_diff=5*pdifference // Amplify difference to improve S/N for integral term raverage(pamplified_diff,10,pintegral) // Calculate the running average of the proportional // error and store as the integral error term pfeedback=plastout+ ... // Calculate pfeedback, the desired motor command value (1*(2000*(ip0-ptarget_force-poffset)/10000))+ ... // if tension control is operating. The 2000 and 200 (1*(200*pintegral)/10000) // terms reflect the amount of (user-set) proportional // and integral gain respectively. The 1 values // reflect the FL_POLARITY calibration factor pout=((1-pservo)*pfl)+(pservo*pfeedback) // Set pout to either pfeedback or pfl as required copy(pout,plastout,op1) // Send pout to op1 (DAC1 channel) and plastout // (for the next cycle) copy(ptrigger,op0) // Send ptrigger to op0 (DAC0 channel) merge(ip0,ip1,ip2,ip3,$binout) // Send data back to the host PC through the binary // communication pipe end ;************************************************************ odef outputproc 2 // Output procedure (2 channels of output) outputwait 2 // Don't change the output values until there are 2 // values waiting to be set. This prevents underflow // at the beginning of the trial update burst // Prevents an underflow error message. Output values // update only when 2 or more values are waiting set op0 a0 // Send op0 to DAC0 set op1 a1 // Send op1 to DAC1 time 500 // Update data values for each channel every 500 µs // i.e. total update rate = 1 kHz end ;************************************************************ idef inputproc 4 // Input procedure (4 channels of input data) set ip0 s0 // Set ip pipes to the appropriate ADC channels set ip1 s1 set ip2 s2 set ip3 s3 count 320 // Record a total of 320 points // i.e. 80 points/channel time 250 // Read values for every channel every 250 µs // i.e. total update rate = 1 kHz // (This has to match the output rate or the input and // output procedures get out of synch.) end ;************************************************************ start create_pipes,control,inputproc,outputproc