From 8fbe8b29d068810c560745e47bc1627a95140b1d Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Fri, 16 Apr 2010 09:45:27 +1000 Subject: [PATCH] Adding script context MODBUS protocol and Eurotherm 2000 series driver r2886 | dcl | 2010-04-16 09:45:27 +1000 (Fri, 16 Apr 2010) | 2 lines --- site_ansto/hardsup/makefile | 2 +- site_ansto/hardsup/sct_modbusprot.c | 200 ++++++++++ .../temperature/sct_eurotherm_2000.tcl | 358 ++++++++++++++++++ .../instrument/rsd/config/INSTCFCOMMON.TXT | 1 + .../instrument/rsd/kowari_configuration.tcl | 1 + site_ansto/site_ansto.c | 2 + 6 files changed, 563 insertions(+), 1 deletion(-) create mode 100644 site_ansto/hardsup/sct_modbusprot.c create mode 100644 site_ansto/instrument/config/environment/temperature/sct_eurotherm_2000.tcl diff --git a/site_ansto/hardsup/makefile b/site_ansto/hardsup/makefile index 39353c7b..62b1522b 100644 --- a/site_ansto/hardsup/makefile +++ b/site_ansto/hardsup/makefile @@ -10,7 +10,7 @@ SRC = . CC = gcc CFLAGS = -g -DLINUX $(DFORTIFY) -I$(SRC) -I../.. -Wall -Wno-unused -Wextra -HOBJ= nhq200util.o itc4util.o lh45util.o lakeshore340util.o west4100util.o asynsrv_utility.o geterrno.o strjoin.o chopper.o modbustcp.o sct_galilprot.o sct_orhvpsprot.o sct_velselprot.o sct_usbtmcprot.o sct_ansrfamp.o +HOBJ= nhq200util.o itc4util.o lh45util.o lakeshore340util.o west4100util.o asynsrv_utility.o geterrno.o strjoin.o chopper.o modbustcp.o sct_galilprot.o sct_modbusprot.o sct_orhvpsprot.o sct_velselprot.o sct_usbtmcprot.o sct_ansrfamp.o libhlib.a: $(HOBJ) rm -f libhlib.a diff --git a/site_ansto/hardsup/sct_modbusprot.c b/site_ansto/hardsup/sct_modbusprot.c new file mode 100644 index 00000000..d016884c --- /dev/null +++ b/site_ansto/hardsup/sct_modbusprot.c @@ -0,0 +1,200 @@ +/** @file Modbus protocol handler for script-context based controllers. +* +*/ +#include +#include +#include +#include + +static int dbgprintf(char* fmtstr, ...); +static int dbgprintx(const char* msg, const unsigned char* cp, int blen); +static unsigned int debug_modbus = 0; + +/** @brief encode modbus request +* TODO: clean me up +*/ +int ModbusWriteStart(Ascon *a) { + unsigned int dev, cmd, reg; + int len = GetDynStringLength(a->wrBuffer); + char* buff = NULL; + char temp[32]; + char* endp = NULL; + int idx = 6; + temp[0] = 0; /* transaction id */ + temp[1] = 0; + temp[2] = 0; /* protocol id */ + temp[3] = 0; + + DynStringConcatChar(a->wrBuffer, 0); + buff = GetCharArray(a->wrBuffer); + dbgprintf("modbus-wr:%s\n", buff); + dev = strtoul(buff, &endp, 10); + if (endp == buff || dev < 1 || dev > 9) { + dbgprintf("modbus-er: Bad device id: %d from %s\n", dev, buff); + a->state = AsconIdle; + AsconError(a, "Bad device id", 0); + return 0; + } + temp[idx++] = dev; + buff = endp + 1; + cmd = strtoul(buff, &endp, 10); + if (endp == buff || (cmd != 3 && cmd != 16)) { /* read/write registers */ + dbgprintf("modbus-er: Bad command id: %d from %s\n", cmd, buff); + a->state = AsconIdle; + AsconError(a, "Bad command id", 0); + return 0; + } + temp[idx++] = cmd; + buff = endp + 1; + reg = strtoul(buff, &endp, 10); + if (endp == buff || reg < 1 || reg > 65535) { + dbgprintf("modbus-er: Bad register id: %d from %s\n", reg, buff); + a->state = AsconIdle; + AsconError(a, "Bad register id", 0); + return 0; + } + temp[idx++] = (reg >> 8) & 0xFF; + temp[idx++] = reg & 0xFF; + temp[idx++] = 0; /* word count msbyte */ + temp[idx++] = 1; /* word count lsbyte */ + if (cmd == 16) { /* write registers */ + buff = endp + 1; + unsigned int val; + val = strtoul(buff, &endp, 10); + if (endp == buff || val < 0 || val > 65535) { + dbgprintf("modbus-er: Bad value: %d from %s\n", val, buff); + a->state = AsconIdle; + AsconError(a, "Bad value", 0); + return 0; + } + temp[idx++] = 2; /* byte count */ + temp[idx++] = (val >> 8) & 0xFF; + temp[idx++] = val & 0xFF; + } + len = idx - 6; + temp[4] = len >> 8; /* length msbyte */ + temp[5] = len & 0xFF; /* length lsbyte */ + + if (debug_modbus > 0) { + dbgprintx("modbus-xo", (unsigned char*)temp, idx); + } + DynStringReplaceWithLen(a->wrBuffer, temp, 0, idx); + a->state = AsconWriting; + a->wrPos = 0; + return 1; +} + +/** @brief decode modbus response +* TODO: clean me up +*/ +int ModbusReading(Ascon *a) { + int ret, blen, rlen; + char chr = '\0'; + unsigned char* cp = NULL; + + ret = AsconReadChar(a->fd, &chr); + while (ret > 0) { + DynStringConcatChar(a->rdBuffer, chr); + cp = (unsigned char*) GetCharArray(a->rdBuffer); + blen = GetDynStringLength(a->rdBuffer); + if (debug_modbus > 0) { + dbgprintx("modbus-xi", cp, blen); + } + if (blen >= 6) { + int mlen = (cp[4] << 8) + cp[5]; + if (blen - 6 >= mlen) { + char temp[64]; + if (cp[7] == 3 && cp[8] == 2) { + rlen = snprintf(temp, 64, "%d", (((unsigned int)cp[9]) << 8) + (unsigned int)cp[10]); + } + else if (cp[7] == 16 && cp[11] == 1) { + rlen = snprintf(temp, 64, "OK"); + } + else if (((unsigned int)cp[7]) == 0x83) { + rlen = snprintf(temp, 64, "ASCERR:%02x:%d", cp[7], cp[8]); + } + else if (((unsigned int)cp[7]) == 0x90) { + rlen = snprintf(temp, 64, "ASCERR:%02x:%d", cp[7], cp[8]); + } + else { + rlen = snprintf(temp, 64, "ASCERR:%02x:%d", cp[7], cp[8]); + } + if (debug_modbus > 0) { + dbgprintx("modbus-xi", cp, blen); + } + dbgprintf("modbus-rd:%s\n", temp); + DynStringReplaceWithLen(a->rdBuffer, temp, 0, rlen); + a->state = AsconReadDone; + return 1; + } + } + ret = AsconReadChar(a->fd, &chr); + } + return 1; +} + +/** @brief Modbus TCP protocol handler. +* This handler encodes commands and decodes responses +* for the Modbus TCP protocol +*/ +int ModbusProtHandler(Ascon *a) { + int ret; + + switch(a->state){ + case AsconWriteStart: + ret = ModbusWriteStart(a); + return ret; + break; + case AsconReading: + ret = ModbusReading(a); + return ret; + break; + default: + return AsconStdHandler(a); + } + return 1; +} + +void AddModbusProtocoll(){ + AsconProtocol *prot = NULL; + + prot = calloc(sizeof(AsconProtocol), 1); + prot->name = strdup("modbus"); + prot->init = AsconStdInit; + prot->handler = ModbusProtHandler; + AsconInsertProtocol(prot); +} + +#include +#include + +static int dbgprintf(char* fmtstr, ...) { + if (debug_modbus > 0) { + FILE* fp = NULL; + int ret = 0; + fp = fopen("/tmp/modbus.txt", "a"); + if (fp != NULL) { + va_list ap; + va_start(ap, fmtstr); + ret = vfprintf(fp, fmtstr, ap); + va_end(ap); + fclose(fp); + } + return ret; + } + return 0; +} +static int dbgprintx(const char* msg, const unsigned char* cp, int blen) { + if (debug_modbus > 0) { + char tmp[128]; + int i, j; + const char hex[] = "0123456789ABCDEF"; + for (i = 0, j = 0; i < blen && j < 126; ++i) { + tmp[j++] = hex[(cp[i] >> 4) & 0xF]; + tmp[j++] = hex[(cp[i] ) & 0xF]; + } + tmp[j++] = '\0'; + return dbgprintf("%s: %s\n", msg, tmp); + } + return 0; +} diff --git a/site_ansto/instrument/config/environment/temperature/sct_eurotherm_2000.tcl b/site_ansto/instrument/config/environment/temperature/sct_eurotherm_2000.tcl new file mode 100644 index 00000000..a8f4b674 --- /dev/null +++ b/site_ansto/instrument/config/environment/temperature/sct_eurotherm_2000.tcl @@ -0,0 +1,358 @@ +# Define procs in ::scobj::xxx namespace +# MakeSICSObj $obj SCT_ +# The MakeSICSObj cmd adds a /sics/$obj node. NOTE the /sics node is not browsable. + + +namespace eval ::scobj::et2000 { +# Temperature controllers must have at least the following nodes +# /tempcont/setpoint +# /tempcont/sensor/value + proc debug_log {args} { + set fd [open "/home/dcl/et2000.log" a] + puts $fd $args + close $fd + } + + proc getValue {nextState cmd} { + sct send $cmd + return $nextState + } + proc setValue {nextState cmd} { + set par [sct target] + sct send "$cmd $par" +debug_log "setValue $cmd $par" + return $nextState + } + + proc setPoint {tc_root nextState cmd} { + set par [sct target] + + hset $tc_root/status "busy" + if {[sct writestatus] == "start"} { + # Called by drive adapter + hsetprop $tc_root/setpoint driving 1 + } + sct send "$cmd $par" +debug_log "setPoint $cmd $par" + return $nextState + } + + proc rdValue {} { + set data [sct result] + switch -glob -- $data { + "ASCERR:*" { + sct geterror $data + } + default { + if {$data != [sct oldval]} { + sct oldval $data + sct update $data + sct utime readtime + } + } + } + return idle + } + + proc getState {tc_root nextState cmd} { + sct send "$cmd" + return $nextState + } + + proc checktol {tc_root currtime timecheck} { +debug_log "checktol $tc_root $currtime $timecheck" + set temp [hval $tc_root/sensor/value] + set lotemp [hval $tc_root/subtemp_warnlimit] + set hitemp [hval $tc_root/overtemp_warnlimit] + if { $temp < $lotemp || $temp > $hitemp} { + hset $tc_root/emon/isintol 0 + return 0 + } else { + set timeout [hval $tc_root/tolerance/settletime] + if {[expr $currtime - $timecheck] > $timeout} { + hset $tc_root/emon/isintol 1 + } + return 1 + } + } + + ## + # @brief Reads the current et2000 state and error messages. + proc rdState {tc_root} { +set my_driving [SplitReply [hgetprop $tc_root/setpoint driving]] +debug_log "rdState $tc_root: driving=$my_driving" + set val [hval $tc_root/setpoint] +debug_log "rdState $tc_root: setpoint=$val" + if {[hpropexists $tc_root/setpoint target]} { + set tgt [SplitReply [hgetprop $tc_root/setpoint target]] +debug_log "rdState $tc_root: target=$tgt" + } else { + hsetprop $tc_root/setpoint target $val + set tgt [SplitReply [hgetprop $tc_root/setpoint target]] +debug_log "rdState $tc_root: initialised target to: target=$tgt" + } + set data [sct result] +debug_log "rdState $tc_root: result=$data" + if {[string first "ASCERR:" $data] >=0} { + sct geterror $data + } elseif {$data != [sct oldval]} { + sct oldval $data + sct update $data + sct utime readtime + } + if {$my_driving > 0} { + set temp [hval $tc_root/sensor/value] + set tol [hval $tc_root/tolerance] + set lotemp [expr $tgt - $tol] + set hitemp [expr $tgt + $tol] +debug_log "rdState driving $tc_root until $data in ($lotemp, $hitemp)" + if {$data < $lotemp} { + } elseif {$data > $hitemp} { + } else { + hset $tc_root/status "idle" + hsetprop $tc_root/setpoint driving 0 + } + } + return idle + } + + proc noResponse {} { + return idle + } + proc wrtValue {wcmd args} { + } + + proc check {tc_root} { + set setpoint [sct target] + set lolimit [hval $tc_root/lowerlimit] + set hilimit [hval $tc_root/upperlimit] + if {$setpoint < $lolimit || $setpoint > $hilimit} { + error "setpoint violates limits" + } + return OK + } + +## +# @brief Implement the checkstatus command for the drivable interface +# +# NOTE: The drive adapter initially sets the writestatus to "start" and will +# only call this when writestatus!="start" + proc drivestatus {tc_root} { + if [sct driving] { + return busy + } else { + return idle + } + } + + proc halt {tc_root} { +debug_log "halt $tc_root" + hset $tc_root/setpoint [hval $tc_root/sensor/value] + hsetprop $tc_root/setpoint driving 0 + return idle + } + + proc mk_sct_eurotherm_et2000 {sct_controller klass tempobj dev_id tol} { + if [ catch { + set ns ::scobj::et2000 + + MakeSICSObj $tempobj SCT_OBJECT + sicslist setatt $tempobj klass $klass + sicslist setatt $tempobj long_name $tempobj + + set scobj_hpath /sics/$tempobj + hfactory $scobj_hpath/setpoint plain user float + hsetprop $scobj_hpath/setpoint read ${ns}::getValue rdValue "1:3:2" + hsetprop $scobj_hpath/setpoint write ${ns}::setPoint $scobj_hpath noResponse "1:16:2" + hsetprop $scobj_hpath/setpoint check ${ns}::check $scobj_hpath + hsetprop $scobj_hpath/setpoint rdValue ${ns}::rdValue + hsetprop $scobj_hpath/setpoint noResponse ${ns}::noResponse + hsetprop $scobj_hpath/setpoint oldval UNKNOWN + hsetprop $scobj_hpath/setpoint driving 0 + hsetprop $scobj_hpath/setpoint writestatus UNKNOWN + # Drive adapter interface + hsetprop $scobj_hpath/setpoint checklimits ${ns}::check $scobj_hpath + hsetprop $scobj_hpath/setpoint checkstatus ${ns}::drivestatus $scobj_hpath + hsetprop $scobj_hpath/setpoint halt ${ns}::halt $scobj_hpath + + hfactory $scobj_hpath/overtemp_warnlimit plain user float + hsetprop $scobj_hpath/overtemp_warnlimit read ${ns}::getValue rdValue "1:3:14" + hsetprop $scobj_hpath/overtemp_warnlimit write ${ns}::setValue noResponse "1:16:14" + hsetprop $scobj_hpath/overtemp_warnlimit rdValue ${ns}::rdValue + hsetprop $scobj_hpath/overtemp_warnlimit noResponse ${ns}::noResponse + hsetprop $scobj_hpath/overtemp_warnlimit oldval UNKNOWN + + hfactory $scobj_hpath/subtemp_warnlimit plain user float + hsetprop $scobj_hpath/subtemp_warnlimit read ${ns}::getValue rdValue "1:3:13" + hsetprop $scobj_hpath/subtemp_warnlimit write ${ns}::setValue noResponse "1:16:13" + hsetprop $scobj_hpath/subtemp_warnlimit rdValue ${ns}::rdValue + hsetprop $scobj_hpath/subtemp_warnlimit noResponse ${ns}::noResponse + hsetprop $scobj_hpath/subtemp_warnlimit oldval UNKNOWN + + hfactory $scobj_hpath/sensor plain spy none + hfactory $scobj_hpath/sensor/value plain internal float + hsetprop $scobj_hpath/sensor/value read ${ns}::getValue rdValue "1:3:1" + hsetprop $scobj_hpath/sensor/value rdValue ${ns}::rdValue + hsetprop $scobj_hpath/sensor/value oldval UNKNOWN + hsetprop $scobj_hpath/sensor/value units "C" + + hfactory $scobj_hpath/setpoint_slew_rate plain user float + hsetprop $scobj_hpath/setpoint_slew_rate read ${ns}::getValue rdValue "1:3:35" + hsetprop $scobj_hpath/setpoint_slew_rate write ${ns}::setValue noResponse "1:16:35" + hsetprop $scobj_hpath/setpoint_slew_rate rdValue ${ns}::rdValue + hsetprop $scobj_hpath/setpoint_slew_rate noResponse ${ns}::noResponse + hsetprop $scobj_hpath/setpoint_slew_rate oldval UNKNOWN + + hfactory $scobj_hpath/power_limit_low plain user float + hsetprop $scobj_hpath/power_limit_low read ${ns}::getValue rdValue "1:3:31" + hsetprop $scobj_hpath/power_limit_low write ${ns}::setValue noResponse "1:16:31" + hsetprop $scobj_hpath/power_limit_low rdValue ${ns}::rdValue + hsetprop $scobj_hpath/power_limit_low noResponse ${ns}::noResponse + hsetprop $scobj_hpath/power_limit_low oldval UNKNOWN + + hfactory $scobj_hpath/power_limit_high plain user float + hsetprop $scobj_hpath/power_limit_high read ${ns}::getValue rdValue "1:3:30" + hsetprop $scobj_hpath/power_limit_high write ${ns}::setValue noResponse "1:16:30" + hsetprop $scobj_hpath/power_limit_high rdValue ${ns}::rdValue + hsetprop $scobj_hpath/power_limit_high noResponse ${ns}::noResponse + hsetprop $scobj_hpath/power_limit_high oldval UNKNOWN + + hfactory $scobj_hpath/power_slew_rate plain user float + hsetprop $scobj_hpath/power_slew_rate read ${ns}::getValue rdValue "1:3:37" + hsetprop $scobj_hpath/power_slew_rate write ${ns}::setValue noResponse "1:16:37" + hsetprop $scobj_hpath/power_slew_rate rdValue ${ns}::rdValue + hsetprop $scobj_hpath/power_slew_rate noResponse ${ns}::noResponse + hsetprop $scobj_hpath/power_slew_rate oldval UNKNOWN + + hfactory $scobj_hpath/heating_power_percent plain internal float + hsetprop $scobj_hpath/heating_power_percent read ${ns}::getValue rdValue "1:3:3" + hsetprop $scobj_hpath/heating_power_percent rdValue ${ns}::rdValue + hsetprop $scobj_hpath/heating_power_percent oldval UNKNOWN + + hfactory $scobj_hpath/apply_tolerance plain user int + hsetprop $scobj_hpath/apply_tolerance values 0,1 + hset $scobj_hpath/apply_tolerance 1 + + hfactory $scobj_hpath/tolerance plain user float + hsetprop $scobj_hpath/tolerance units "C" + hfactory $scobj_hpath/tolerance/settletime plain user float + hset $scobj_hpath/tolerance/settletime 5.0 + hsetprop $scobj_hpath/tolerance/settletime units "s" + hset $scobj_hpath/tolerance $tol + + hfactory $scobj_hpath/dev_id plain user int + hsetprop $scobj_hpath/dev_id values 1,2,3,4,5,6,7,8,9 + hset $scobj_hpath/dev_id $dev_id + + hfactory $scobj_hpath/status plain spy text + hset $scobj_hpath/status "idle" + hsetprop $scobj_hpath/status values busy,idle + + hfactory $scobj_hpath/et2000_state plain spy text + hsetprop $scobj_hpath/et2000_state read ${ns}::getState $scobj_hpath rdState "1:3:1" + hsetprop $scobj_hpath/et2000_state rdState ${ns}::rdState $scobj_hpath + hsetprop $scobj_hpath/et2000_state oldval UNKNOWN + + hfactory $scobj_hpath/remote_ctrl plain spy text + hset $scobj_hpath/remote_ctrl UNKNOWN + + hfactory $scobj_hpath/et2000_lasterror plain user text + hset $scobj_hpath/et2000_lasterror "" + + hfactory $scobj_hpath/lowerlimit plain mugger float + hsetprop $scobj_hpath/lowerlimit units "C" + hset $scobj_hpath/lowerlimit 1 + + hfactory $scobj_hpath/upperlimit plain mugger float + hsetprop $scobj_hpath/upperlimit units "C" + hset $scobj_hpath/upperlimit 500 + + hfactory $scobj_hpath/emon plain spy none + hfactory $scobj_hpath/emon/monmode plain user text + hsetprop $scobj_hpath/emon/monmode values idle,drive,monitor,error + hset $scobj_hpath/emon/monmode "idle" + hfactory $scobj_hpath/emon/isintol plain user int + hset $scobj_hpath/emon/isintol 1 + hfactory $scobj_hpath/emon/errhandler plain user text + hset $scobj_hpath/emon/errhandler "pause" + + if {[SplitReply [environment_simulation]]=="false"} { + $sct_controller poll $scobj_hpath/setpoint + $sct_controller write $scobj_hpath/setpoint + $sct_controller poll $scobj_hpath/subtemp_warnlimit + $sct_controller write $scobj_hpath/subtemp_warnlimit + $sct_controller poll $scobj_hpath/overtemp_warnlimit + $sct_controller write $scobj_hpath/overtemp_warnlimit + $sct_controller poll $scobj_hpath/heating_power_percent + $sct_controller poll $scobj_hpath/setpoint_slew_rate + $sct_controller write $scobj_hpath/setpoint_slew_rate + $sct_controller poll $scobj_hpath/power_slew_rate + $sct_controller write $scobj_hpath/power_slew_rate + $sct_controller poll $scobj_hpath/power_limit_low + $sct_controller write $scobj_hpath/power_limit_low + $sct_controller poll $scobj_hpath/power_limit_high + $sct_controller write $scobj_hpath/power_limit_high + $sct_controller poll $scobj_hpath/sensor/value + $sct_controller poll $scobj_hpath/et2000_state 5 halt read + } + + ::scobj::hinitprops $tempobj + hsetprop $scobj_hpath klass NXenvironment + ::scobj::set_required_props $scobj_hpath + foreach {rootpath hpath klass priv} " + $scobj_hpath sensor NXsensor spy + $scobj_hpath sensor/value sensor user + " { + hsetprop $rootpath/$hpath klass $klass + hsetprop $rootpath/$hpath privilege $priv + hsetprop $rootpath/$hpath control true + hsetprop $rootpath/$hpath data true + hsetprop $rootpath/$hpath nxsave true + } + hsetprop $scobj_hpath type part + hsetprop $scobj_hpath/sensor type part + hsetprop $scobj_hpath/sensor/value nxalias tc1_sensor_value + hsetprop $scobj_hpath/sensor/value mutable true + hsetprop $scobj_hpath/sensor/value sdsinfo ::nexus::scobj::sdsinfo + + hsetprop $scobj_hpath privilege spy + ::scobj::hinitprops $tempobj setpoint + if {[SplitReply [environment_simulation]]=="false"} { + ansto_makesctdrive ${tempobj}_driveable $scobj_hpath/setpoint $scobj_hpath/sensor/value $sct_controller + } + } message ] { + return -code error $message + } + } + namespace export mk_sct_eurotherm_et2000 +} + +## +# @brief Create a Eurotherm et2000 temperature controller +# +# @param name, the name of the temperature controller (eg tc1) +# @param IP, the IP address of the device, this can be a hostname, (eg ca5-kowari) +# @param port, the IP protocol port number of the device (502 for modbus) +# @param _tol (optional), this is the initial tolerance setting +proc add_et2000 {name IP port dev_id {_tol 5.0}} { + set fd [open "/home/dcl/et2000.log" a] + if {[SplitReply [environment_simulation]]=="false"} { + puts $fd "makesctcontroller sct_et2000 modbus ${IP}:$port" + makesctcontroller sct_et2000 modbus ${IP}:$port + } + puts $fd "mk_sct_eurotherm_et2000 sct_et2000 environment $name $dev_id $_tol" + mk_sct_eurotherm_et2000 sct_et2000 environment $name $dev_id $_tol + puts $fd "makesctemon $name /sics/$name/emon/monmode /sics/$name/emon/isintol /sics/$name/emon/errhandler" + makesctemon $name /sics/$name/emon/monmode /sics/$name/emon/isintol /sics/$name/emon/errhandler + close $fd +} + +puts stdout "file evaluation of sct_eurotherm_2000.tcl" +set fd [open "/home/dcl/et2000.log" w] +puts $fd "file evaluation of sct_eurotherm_2000.tcl" +close $fd + +namespace import ::scobj::et2000::* + +add_et2000 et2000 137.157.201.213 502 1 5 +#add_et2000 et2000 localhost 30502 1 5 diff --git a/site_ansto/instrument/rsd/config/INSTCFCOMMON.TXT b/site_ansto/instrument/rsd/config/INSTCFCOMMON.TXT index 55c528b6..3ba5f3c9 100644 --- a/site_ansto/instrument/rsd/config/INSTCFCOMMON.TXT +++ b/site_ansto/instrument/rsd/config/INSTCFCOMMON.TXT @@ -3,6 +3,7 @@ config/anticollider/anticollider_common.tcl config/plc/plc_common_1.tcl config/counter/counter_common_1.tcl config/environment/temperature/sct_lakeshore_3xx.tcl +config/environment/temperature/sct_eurotherm_2000.tcl config/hipadaba/hipadaba_configuration_common.tcl config/hipadaba/common_instrument_dictionary.tcl config/hipadaba/instdict_specification.tcl diff --git a/site_ansto/instrument/rsd/kowari_configuration.tcl b/site_ansto/instrument/rsd/kowari_configuration.tcl index 25bb633d..68c21449 100644 --- a/site_ansto/instrument/rsd/kowari_configuration.tcl +++ b/site_ansto/instrument/rsd/kowari_configuration.tcl @@ -23,6 +23,7 @@ fileeval $cfPath(motors)/positmotor_configuration.tcl fileeval $cfPath(plc)/plc.tcl fileeval $cfPath(counter)/counter.tcl fileeval $cfPath(environment)/temperature/sct_lakeshore_3xx.tcl +fileeval $cfPath(environment)/temperature/sct_eurotherm_2000.tcl fileeval $cfPath(hmm)/hmm_configuration.tcl fileeval $cfPath(nexus)/nxscripts.tcl fileeval $cfPath(scan)/scan.tcl diff --git a/site_ansto/site_ansto.c b/site_ansto/site_ansto.c index 22d19804..f4b346cd 100644 --- a/site_ansto/site_ansto.c +++ b/site_ansto/site_ansto.c @@ -54,6 +54,7 @@ extern int VelSelTcpFactory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); extern pCodri MakeTcpDoChoDriver(char *tclArray, SConnection *pCon); extern void AddGalilProtocoll(); +extern void AddModbusProtocoll(); extern void AddOrdHVPSProtocoll(); extern void AddVelSelProtocol(); extern void AddUSBTMCProtocoll(); @@ -69,6 +70,7 @@ void SiteInit(void) { INIT(SctEmonInit); INIT(ANSTO_SctDriveInit); AddGalilProtocoll(); + AddModbusProtocoll(); AddOrdHVPSProtocoll(); AddVelSelProtocol(); AddUSBTMCProtocoll();