#%NAME%
# nd287cnt.mac
#
#%DESCRIPTION%
# Macrocounter for reading the ND287 Heidenhain controller, via ethernet
#%BR% Spec configuration:
#%BR% The controller nd287 must be declared in the SCALERS part
#%BR%- When the device has two interfaces X1 & X2 use the controller nd287x2
#%BR%\0
#%BR%SCALERS\0\0\0\0\0\0DEVICE\0\0\0\0ADDR\0\0<>MODE\0\0NUM\0\0\0\0<>TYPE
#%BR%\0\0\0\0YES\0\0\0\0\0\0\0nd287\0\0\0\0nd2-28710\0\0\0\0\0\0\01\0\0\0\0\0\0Macro Counter (for 1 interface)
#%BR%\0
#%BR%\0\0\0\0YES\0\0\0\0\0\0\0nd287x2\0\0nd287id011\0\0\0\0\0\01\0\0\0\0\0\0Macro Counter (for 2 interfaces)
#%BR%
#%BR%- ADDR: controller IP (host)
#%BR%\0
#%BR%The device is defined in the Scaler (Counter) Configuration
#%BR%\0
#%BR%Number\0\0\0\0\0\0Name\0\0\0Mnemonic\0\0<>Device\0\0Unit\0\0Chan\0\0<>Use\0As\0\0Scale\0Factor
#%BR%\0\0\0\010\0\0\0\0\0\0enc1\0\0\0\0\0\0\0enc1\0\0\0MAC_CNT\0\0\0\00\0\0\0\00\0\0\0\0\0counter\0\0\0\0\0\0\0\0\0\01 (for 1 interface)
#%BR%
#%BR%\0\0\0\010\0\0\0\0\0\0enc1\0\0\0\0\0\0\0enc1\0\0\0MAC_CNT\0\0\0\00\0\0\0\01\0\0\0\0\0counter\0\0\0\0\0\0\0\0\0\01 (for 2 interfaces)
#%BR%\0\0\0\011\0\0\0\0\0\0enc2\0\0\0\0\0\0\0enc2\0\0\0MAC_CNT\0\0\0\00\0\0\0\02\0\0\0\0\0counter\0\0\0\0\0\0\0\0\0\01 (for 2 interfaces)
#%BR%
#%BR%- Unit refers to the macrocounter index in the SCALERS part
#%BR%
#%END%
#==================================================================
#==================================================================q
# 2017/05/04 rh
# - added macrocounter nd287x2 for 2 interfaces
# - fixed bug in decoding of position/channel (cmd 0-x501)
# - some cosmetics in debug
#==================================================================
#==================================================================q
global nd287_SIMUL nd287_DEBUG
global ND287_ARR[]
global nd287_PORT ; nd287_PORT = 1050
#==================================================================
#==================================================================
#%UU%
#%MDESC% toggle the debug mode
if (!(whatis("__nd287_debug") & 2)) rdef __nd287_debug \'#$*\'
def nd287_debug '{
if ((whatis("__nd287_debug")>>16) <= 3) { # macro length is 3 bytes: comment
rdef __nd287_debug "eprint"
print "nd287 macro debug mode is ON"
nd287_DEBUG = 1
}
else {
rdef __nd287_debug \'#\$*\'
print "nd287 macro debug mode is OFF"
nd287_DEBUG = 0
}
}'
# some programmer help
#%UU%
#%MDESC% toggle simul mode for the present macros.
def nd287_simul '{
if (nd287_SIMUL) { # if present should be true
nd287_SIMUL = 0
print "nd287 simulation is OFF"
} else {
nd287_SIMUL = 1
print "nd287 simulation is ON"
}
}
'
#==================================================================
#==================================================================
#%IU%(mne,type,p1,p2,p3)
#%MDESC%Macro counter mechanism (1 encoder): config
def nd287_config(mne,type,p1,p2,p3)'{
local lcmd
# .. ctrl or mne cnt
__nd287_debug ">>> nd287: ",mne, type, p1, p2, p3
if (type == "ctrl") {
__nd287_debug ">>> new controller "
lcmd = sprintf ("ping %s -c 1", nd287_ADDR)
if (unix(lcmd) != 0) {
eprintf ("Controller %s not responding, disabling its motors\n", \
nd287_ADDR)
return ".error."
}
#removed as it takes a long time
#nd287_flush(nd287_ADDR)
return 0
}
if (type == "cnt") {
# add a new parameter, to store the value when read
counter_par(cnt_num(mne), "mypos", 0, "add")
return 0
}
}'
#%IU%(mne,type,p1,p2,p3)
#%MDESC%Macro counter mechanism (1 encoder): cmd
def nd287_cmd(mne,key,p1,p2,p3)'{
local resp myval
__nd287_debug ">>> nd287: ",mne, key, p1, p2, p3
if (key == "halt_one") {
resp = _nd287_dispos(nd287_ADDR)
__nd287_debug ">>> nd287: returns", resp
counter_par(cnt_num(mne),"mypos",resp)
return 0
}
if (key == "counts"){
local mypos
mypos = counter_par(cnt_num(mne),"mypos")
return mypos
}
# returns .error. if an error
}'
#==================================================================
#==================================================================
#%IU%(mne,type,p1,p2,p3)
#%MDESC%Macro counter mechanism (2 encoders): config
def nd287x2_config(mne,type,p1,p2,p3)'{
local lcmd
local fnId ; fnId = "nd287x2_config"
# .. ctrl or mne cnt
__nd287_debug ">>> nd287: ",fnId, mne, type, p1, p2, p3
if (type == "ctrl") {
__nd287_debug ">>> new controller ", fnId
lcmd = sprintf ("ping %s -c 1", nd287x2_ADDR)
if (unix(lcmd) != 0) {
eprintf ("Controller %s not responding, disabling its motors\n", \
nd287x2_ADDR)
return ".error."
}
#removed as it takes a long time
#nd287_flush(nd287_ADDR)
return 0
}
if (type == "cnt") {
# add a new parameter, to store the value when read
counter_par(cnt_num(mne), "mypos", 0, "add")
return 0
}
}'
#%IU%(mne,type,p1,p2,p3)
#%MDESC%Macro counter mechanism (2 encoders): cmd
def nd287x2_cmd(mne,key,p1,p2,p3)'{
local fnId ; fnId = "nd287x2_cmd"
local resp myval
__nd287_debug ">>> nd287: ",fnId, mne, key, p1, p2, p3
local _addr
_addr = nd287x2_ADDR
if (key == "halt_all") {
ND287_ARR[_addr][1]=nd287_posbytes(_addr,1)
ND287_ARR[_addr][2]=nd287_posbytes(_addr,2)
return 0
}
if (key == "counts"){
local mypos ch
ch = counter_par(cnt_num(mne),"channel")
return ND287_ARR[_addr][ch]
}
# returns .error. if an error
}'
#==================================================================
#==================================================================
#%UU% (host)
#%MDESC% flushes
def nd287_flush(host) '{
local val
p sock_get(sprintf("%s:%d",host,nd287_PORT))
}'
#%UU% (host)
#%MDESC% flushes one byte
def nd287_flushbytes(host) '{
local val
val = sock_get(sprintf("%s:%d",host,nd287_PORT),"byte")
printf("%x %d\n",val,val)
}'
#%IU% (host,cmd,framework_length,command_number)
#%MDESC% send a command without arguments (not verbose)
def nd287_put(host,cmd,nb,id)'{
local long array aa[3]
# command
aa[0]=cmd
# framework lenght in bytes
aa[1]=nb
# command number
aa[2]=id
sock_put(sprintf("%s:%d",host,nd287_PORT),aa,3)
}'
#%IU% (host,cmd,framework_length,command_number,argument)
#%MDESC%send a command with arguments (not verbose)
def nd287_putarg(host,cmd,nb,id,arg)'{
long array aa[4]
# command
aa[0]=cmd
# framework lenght in bytes
aa[1]=nb
# command number
aa[2]=id
# argument
aa[3] = arg
sock_put(sprintf("%s:%d",host,nd287_PORT),aa,4)
}'
#==================================================================
#==================================================================
#%IU% (host)
#%MDESC% reads the header of a response
#%BR%- return the theoretical number of remaining bytes (verbose)
def nd287_getheader(host)'{
local rcmd, rlen, rid rnbytes
local fnId ; fnId = "nd287_getheader"
# response code
rcmd = sock_get(sprintf("%s:%d",host,nd287_PORT),"long_swap")
# length in bytes
rlen = sock_get(sprintf("%s:%d",host,nd287_PORT),"long_swap")
# command number
rid = sock_get(sprintf("%s:%d",host,nd287_PORT),"long_swap")
__nd287_debug ">>> nd287: ", fnId, sprintf("response code : %x\n",rcmd)
__nd287_debug ">>> nd287: ", fnId, sprintf("length in bytes: %d\n",rlen)
__nd287_debug ">>> nd287: ", fnId, sprintf("command number : %d\n",rid)
rnbytes = rlen - 12
return rnbytes
}'
#%IU% (host)
#%MDESC% reads the header of a response (not verbose)
#%BR%- return the theoretical number of remaining bytes
def _nd287_getheader(host)'{
local rcmd, rlen, rid rnbytes
# response code
rcmd = sock_get(sprintf("%s:%d",host,nd287_PORT),"long_swap")
# length in bytes
rlen = sock_get(sprintf("%s:%d",host,nd287_PORT),"long_swap")
# command number
rid = sock_get(sprintf("%s:%d",host,nd287_PORT),"long_swap")
rnbytes = rlen - 12
return rnbytes
}'
#%IU% (host,cmd,framework_lengh, command_number)
#%MDESC%sends a command without arguments,
# reads the header
# and the remaining bytes. verbose
def nd287_putget(host,cmd,nb,id)'{
local rbytes mb
nd287_put(host,cmd,nb,id)
rbytes = nd287_getheader(host)
printf("%d remaining bytes: \n",rbytes)
# data:
for (ii=0; ii<rbytes; ii++) {
mb = sock_get(sprintf("%s:%d",host,nd287_PORT),"byte")
printf("byte %d: 0x%x (%d)\n",ii,mb,mb)
}
}'
#%IU% (host,cmd,framework_length,command_number,argument)
#%MDESC% sends a command with argument,
# reads the header
# and the remaining bytes. verbose
def nd287_putgetarg(host,cmd,nb,id,arg)'{
local rbytes mb
nd287_putarg(host,cmd,nb,id,arg)
rbytes = nd287_getheader()
printf("%d remaining bytes: \n",rbytes)
# data:
for (ii=0; ii<rbytes; ii++) {
mb = sock_get(sprintf("%s:%d",host,nd287_PORT),"byte")
printf("byte %d: 0x%x (%d)\n",ii,mb,mb)
}
}'
#%IU% (host)
#%MDESC% read nn bytes
def nd287_get(host,nn)'{
local ii val
for (ii=0; ii<nn; ii++) {
val = sock_get(sprintf("%s:%d",host,nd287_PORT),"byte")
printf("%d: 0x%x (%d)\n",ii,val,val)
}
}'
#%UU% (host)
#%MDESC% get version reading long words
def nd287_ver(host)'{
local rdata rbytes
nd287_put(host,0x401,12,1)
rbytes = _nd287_getheader(host)
# data: we know it is 4 bytes
# read it as an integer
rdata = sock_get(sprintf("%s:%d",host,nd287_PORT),"long_swap")
printf("version : %x\n",rdata)
}'
#%IU% (host)
#%MDESC% get version reading bytes
def nd287_verbytes(host)'{
nd287_putget(host,0x401,12,1)
}'
#%UU% (host)
#%MDESC% get displayed position reading string.
#%BR%- returns numerical value
def nd287_dispos(host)'{
local rdata rbytes numval
nd287_put(host,0x61b,12,2)
rbytes = nd287_getheader(host)
# read it as a string
rdata = sock_get(sprintf("%s:%d",host,nd287_PORT))
printf("data : %s\n",rdata)
numval = _nd287_extractpos(rdata)
return numval
}'
#%IU% (host)
#%MDESC% get displayed position reading string (without printing)
#%BR%- returns numerical value
def _nd287_dispos(host)'{
local rdata rbytes numval
nd287_put(host,0x61b,12,2)
rbytes = _nd287_getheader(host)
# read it as a string
rdata = sock_get(sprintf("%s:%d",host,nd287_PORT))
numval = _nd287_extractpos(rdata)
return numval
}'
#%IU% (host)
#%MDESC% get display position reading bytes
def nd287_disposbytes(host)'{
nd287_putget(host,0x61b,12,2)
}'
#%UU% (host)
#%MDESC% read error messages as string
def nd287_err(host)'{
local rbytes rdata numval
nd287_put(host,0x605,12,3)
rbytes = nd287_getheader(host)
# read it as a string
rdata = sock_get(sprintf("%s:%d",host,nd287_PORT))
printf("data : %s\n",rdata)
}'
#%IU% (host)
#%MDESC% read error messages as bytes
def nd287_errbytes(host)'{
local rbytes
nd287_putget(host,0x605,12,3)
}'
#==================================================================
#==================================================================
#%IU% (host)
#%MDESC% read encoder position as integers
def nd287_posbytes(host,ch)'{
local rbytes data1 data2 mstatus mdata posr posx globdata msg
local fnId ; fnId = "nd287_posbytes"
nd287_putarg(host,0x501,13,4,ch)
rbytes = nd287_getheader(host)
__nd287_debug ">>> nd287: ", fnId, sprintf("remaining bytes: %d\n",rbytes)
#data: read 2 integers
data1 = sock_get(sprintf("%s:%d",host,nd287_PORT),"long_swap")
data2 = sock_get(sprintf("%s:%d",host,nd287_PORT),"long_swap")
__nd287_debug ">>> nd287: ", fnId, sprintf("data1: 0x%08llx\n",data1)
__nd287_debug ">>> nd287: ", fnId, sprintf("data2: 0x%08llx\n",data2)
mstatus = data1 & 0x0ffff
__nd287_debug ">>> nd287: ", fnId, sprintf("status: 0x%04llx\n",mstatus)
datapos = (data2 << 16) | (data1 >> 16)
__nd287_debug ">>> nd287: ", fnId, sprintf("datapos: 0x%012llx\n", datapos)
factor = 1.0e-4
_pos = (datapos & 0x800000000000) ? factor * (datapos - 0x1000000000000) : factor * datapos
__nd287_debug ">>> nd287: ", fnId, sprintf("position : %10.4f (0x%012llx) \n", _pos, datapos)
return _pos
}'
#%IU% (string)
#%MDESC% extracting numerical value
def _nd287_extractpos(mystr)'{
local sign nn mya
if (asc(mystr) == asc("-")) {
#p "negative value"
sign = -1
}
else {
#p "positive value"
sign = 1
}
nn = split(mystr,mya)
return (mya[1]*sign)
}'
#%MACROS%
#%IMACROS%
#%LOG%
#$Revision: 1.2 $
#$Log: nd287cnt.mac,v $
#Revision 1.2 2017/05/04 13:50:56 homsrego
#- added macrocounter nd287x2 for 2 interfaces
#- fixed bug in decoding of position/channel (cmd 0-x501)
#- some cosmetics in debug
#
#Revision 1.1 2012/11/28 07:40:39 domingue
#Initial revision
#
#
#%AUTHOR% mcd november 2012
#%TOC%
|