esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% dac_macmot.mac
#%NAME%
# Macros to control a dac device server (VME card ICV712), optionally with a
# ADC (VME card ICV150) input to display the position.
#%DESCRIPTION%
# This macro file allows to define dac channels as motors in SPEC.
# Optionally one may define an ADC channel as position readout. 
# %BR% %BR%
# In order to allow for adequate feedback, one may define an ADC ds name in the
# motor parameter %B%ADC%B% of the motor definition (hit "p", enter the word
# "ADC" to the left and the ADC channel name to the left).
# %BR% %BR%
# The config values %B%factor%B% (hit "p", enter the word "factor" to the left
# and the value to the left) and %B%encoder_factor%B% can be set to reflect the
# gain of the DAC and ADC channels.
# %BR% %BR%
#In the config editor create a motor controller like follows:
# %BR%
#MOTORS\0\0\0\0\0\0\0\0\0\0DEVICE\0\0\0\0\0\0\0\0\0\0ADDR\0\0<>MODE\0\0NUM\0\0\0\0\0\0\0\0\0\0\0\0\0<>TYPE%BR%
#\0\0\0YES\0\0\0\0\0\0\0\0\0\0DAC\0\0\0\0\0IDXX/DAC/\f\*(#B00_\f1\0\0\0\0\0\0\0\0\0\0\0\02\0\0\0\0\0\0\0Macro\0Motors
# %BR%
#%ATTENTION%
#The DAC device server offers one device per channel. Leave the channel part of
#the name away, it will be completed with the unit number of your motor.
# %BR% %BR%
#Then create the motor(s):
#%PRE%
#Number:\0<>Controller\0\0\0\0\0\0\0\0\0\0\00:\0MAC_MOT
#%BR%
#Unit/[Module/]Channel\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00/1
#%BR%
#Name\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0current
#%BR%
#Mnemonic\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0iout
#%BR%
#Steps\0per\0degree/mm\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\040
#%BR%
#Sign\0of\0user\0*\0dial\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01
#%BR%
#Backlash\0[steps]\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00
#%BR%
#Steady-state\0rate\0[Hz]\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01
#%BR%
#Base\0rate\0[Hz]\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01
#%BR%
#Acceleration\0time\0[msec]\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\01
#%BR%
#Motor\0accumulator\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00
#%BR%
#Restrictions\0<>\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0NONE
#%BR%
#
#%BR%
#Dial\0=\0accumulator\0/\0steps
#%BR%
#\0\0High\0limit\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\05.0000
#%BR%
#\0\0Current\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00.0000
#%BR%
#\0\0Low\0limit\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00.0000
#%BR%
#User\0=\0sign\0*\0dial\0+\0offset
#%BR%
#\0\0Offset\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00.0000
#%BR%
#\0\0`High'\0limit\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\05.0000
#%BR%
#\0\0Current\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00.0000
#%BR%
#\0\0`Low'\0limit\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\00.0000
#%BR%
#%EXAMPLE%
#%DL%
#%DT%  mv dac1 50  %DD% Move the motor to 50
#        This value converted to dac output depending on the ICV712 settings.
#%XDL%
# In order to avoid the message "Motor didn't reach final position." set the
# slop parameter in the spec config to a small number of steps (10).
#%BR%
#$Revision: 1.1 $, $Date: 2008/03/18 08:31:44 $
#%END%
# Modifications history:
#  1/02/2008 Creation 

#%IU%
#%MDESC%
# Called by spec
def DAC_config(mne,type,unit,mod,chan) '{
  global ESRF_ERR ESRF_ERR_MSG
  ESRF_ERR_MSG = ""
  local dsname
  if (mne != "..") {
    if (DEBUG & 128) print "Configuring a DAC encoder channel on " DAC_ADDR
  } else {
    ESRF_ERR = 0; ESRF_ERR_MSG = ""
    # just read channel 0 to check presence
    dsname = DAC_ADDR "0"
    esrf_io(dsname , "DevReadValue")
    if (ESRF_ERR){
      eprint "DAC Macro counter/motor: esrf_io() failed!", ESRF_ERR_MSG
      return ".error."
    }
  }
} '

#%IU%
#%MDESC%
# Called by spec
def DAC_cmd(mne, cmd, p1, p2, unit) '{
  local dsname, chan, value, factor
  local hl, ll, numint, idx, intidx, flidx, num, arnam
  value  = p1
  if (mne != "..") {
    factor = motor_par(mne, "factor")
    if (factor == 0) { factor = 1 }
    ESRF_ERR = 0; ESRF_ERR_MSG = ""
    chan = motor_par(mne, "channel")
    dsname = DAC_ADDR chan
    if ((cmd == "start_one") || (cmd == "set_position")) {
    # make a move
      esrf_io(dsname, "DevSetValue", p1 * factor)
      if (ESRF_ERR){
        eprint "DAC Macro motor: esrf_io() failed!", ESRF_ERR, ESRF_ERR_MSG
        return ".error."
      }
    }
    else if (cmd == "position") {
    # get angle
      chan   = motor_par(mne, "channel")
      dsname = DAC_ADDR chan
      # check first if there is an ADC assigned
      local ADC
      if (ADC = motor_par(mne, "ADC")) {
        local aux[] # split it to dsname and channel
        split(ADC, aux)
        local adcvals[]
        esrf_io(aux[0], "DevReadSigValues", adcvals)
        value = adcvals[aux[1]]
      } else {
        value = esrf_io(dsname, "DevReadValue")
        if (ESRF_ERR){
          eprint "DAC Macro motor: esrf_io() failed!", ESRF_ERR_MSG
          return ".error."
        }
      }
      return(value / factor)
    }
  }
} '

#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
#The file dac_macmot.mac has to be read in.
#%AUTHOR% BLISS - ESRF, H. Witsch%BR%
#$Revision: 1.1 $, $Date: 2008/03/18 08:31:44 $
#%TOC%