DAPL - Length Control

Shown below is sample DAPL code for a hypothetical ktr experiment during which the muscle is held at its original length for 10 ms, shortened by a fixed amount for 20 ms and then returned to its original length. Recording continues for a total of 100 ms.

Note that the formatting of the DAPL code has been slightly altered for HTML display purposes. One of the processing calculations wrap over two lines and would initiate a DAP error if passed to the interpreter in its 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 operation
OPTION QUANTUM=100

;************************************************************

// Header

pipes pfl MAXSIZE=65500                                           // Define all the pipes used in the processing
pipes ptarget 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

;************************************************************

variables zeroclamp                                               // Define zeroclamp variable

;************************************************************

let zeroclamp=0                                                   // Set the value of zeroclamp, in this case to 0
                                                                  // This indicates that sarcomere length changes should
                                                                  // be imposed relative to the prevailing value of SL
                                                                  // A value of 1 indicates that SL length changes
                                                                  // should be imposed relative to zero volts

;************************************************************

                                                                  // This section of the code fills the processing pipes
                                                                  // with all 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 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0               // 0 implies sarcomere length 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 sarcomere length 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 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 0 0 0 0 0 0 0 0 0 0 0      // 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 SL value 
fill poffset_marker 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0      //   (in case it is required for SL control)
fill poffset_marker 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0      // 0 implies leave poffset unaltered
fill poffset_marker 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

fill pfl 0 0 0 0 0 0 0 0 0 0 64 64 64 64 64 64 64 64 64 64       // pfl values (1 per data point)
fill pfl 64 64 64 64 64 64 64 64 64 64 0 0 0 0 0 0 0 0 0 0       // These are the desired DAC1 output values (the
fill pfl 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0                 // motor command values) if SL control is not operating
fill pfl 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
fill pfl 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 

fill ptarget 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0             // ptarget values (1 per data point)
fill ptarget 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0             // These are the desired SL values (relative to
fill ptarget 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0             // poffset) if SL control is operating
fill ptarget 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
fill ptarget 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*ip1)  // Update poffset with current SL as required
  plastoffset=poffset                                            // Update plastoffset which is used above

  pfeedback=plastout-                                            // Calculate pfeedback, the desired motor command value
      (5*(ip1-ptarget-((1-zeroclamp)*poffset))/10000)            // if SL control is operating.  The value, 5/10000
                                                                 // corresponds to the amount of proportional gain set
                                                                 // by the user
  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 400                                                      // Record a total of 400 points
                                                                 // i.e. 100 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                  // Start the trial


Last updated on 3rd June, 2003 by Ken.