EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025 
<== Date ==> <== Thread ==>

Subject: RE: EPICS support for SAES NEG POWER pump controller
From: "Dr. Simon Friederich via Tech-talk" <tech-talk at aps.anl.gov>
To: <lee.hudson at diamon.ac.uk>, "tech-talk at aps.anl.gov" <tech-talk at aps.anl.gov>
Date: Tue, 26 Nov 2024 15:36:04 +0100

Dear Lee,

Yes, we have the device support for the (old) NIOPS as well as the new SIP (originally by J. Dobbins, slightly modified).

Both devices do have ethernet connection but the SIP requires UDP, i.e.

##=====  SAES SIP =====
drvAsynIPPortConfigure("saessip_PORT","<the.ip.of.sip>:<hardcoded_port_see_manual> UDP",0,0,0)
dbLoadRecords("db/saessip.db", "P=$(P), R=$(R), PORT=saessip_PORT")

Best regards
Simon

-- 
Dr. Simon Friederich
Institut für Kernphysik
Kollaboration B | MESA
Johannes Gutenberg-Universität Mainz
Johann-Joachim-Becher-Weg 45
D 55128 Mainz

Tel.: +49 (0)6131 39-23160
E-Mail: s.friederich at uni-mainz.de
record(stringout, "$(P)$(R)debug") {
        field (DTYP, "stream")
        field (OUT, "@niops.proto debug $(PORT)")
}

record (stringin, "$(P)$(R)idn_get")
{
        field (SCAN, "Passive")
        field (DTYP, "stream")
        field (INP, "@niops.proto idn_get $(PORT)")
        field (PINI, "YES")
}

# Common
record (stringout, "$(P)$(R)msg_send")
{
        field (DESC, "Message to receive status")
        field (DTYP, "stream")
        field (SCAN, "5 second")
        field (OUT, "@niops.proto NIOPS_stat_get $(PORT)")
}

# Ion Pump Control
record(bi, "$(P)$(R)on_get") {
        field (DESC, "Get IonPump status")
        field (DTYP, "stream")
        field (INP,  "@niops.proto IP_on_get $(PORT)")
        field (SCAN, "I/O Intr")
        field (ZNAM, "off")
        field (ONAM, "on")
}

record (bo, "$(P)$(R)on_set")
{
        field (SCAN, "Passive")
        field (DTYP, "stream")
        field (OUT, "@niops.proto IP_on_set $(PORT)")
        field (ZNAM, "Off")
        field (ONAM, "On")
        field (SEVR, "NO_ALARM")
        field (STAT, "NO_ALARM")
}

record (ai, "$(P)$(R)i_getRaw")
{
        field (SCAN, "5 second")
        field (DTYP, "stream")
        field (INP, "@niops.proto IP_i_get $(PORT)")
        field (FLNK, "$(P)$(R)i_get")
}

record (calc, "$(P)$(R)i_get")
{
        field (SCAN, "Passive")
        field (INPA, "$(P)$(R)i_getRaw CP")
        field (CALC, "(A & 0x3fff) * 1e-9 * 10^(2 * (A >> 14))")
        field (EGU, "A")
        field (LOPR, 1e-9)
        field (HOPR, 1e-1)
}

record (ai, "$(P)$(R)u_get")
{
        field (SCAN, "10 second")
        field (DTYP, "stream")
        field (INP, "@niops.proto IP_u_get $(PORT)")
        field (EGU, "V")
        field (LOPR, 0)
        field (HOPR, 6000)
        field (PREC, 0)
}

record (ai, "$(P)$(R)PressureRaw")
{
        field (SCAN, "5 second")
        field (DTYP, "stream")
        field (INP, "@niops.proto IP_p_get $(PORT)")
        field (EGU, "mbar")
        field (LOPR, 1e-10)
        field (HOPR, 1e-5)
        field (PREC, 2)
        field (FLNK, "$(P)$(R)p_get")
}

record(calc, "$(P)$(R)p_get")
{
        field (SCAN, "Passive")
        field (INPA, "$(P)$(R)PressureRaw CP")
        field (CALC, "A < 1e-10 ? 1e-10 : A")
        field (EGU, "mbar")
        field (LOPR, 1e-10)
        field (HOPR, 1e-5)
        field (PREC, 2)
}


# NEG Pump Control
record(bi, "$(P)$(R)neg_on_get") {
        field (DESC, "Get IonPump status")
        field (DTYP, "stream")
        field (INP,  "@niops.proto NP_on_get $(PORT)")
        field (SCAN, "I/O Intr")
        field (ZNAM, "off")
        field (ONAM, "on")
}

# Temperatures
# Maybe only needed during bakeout
# record (ao, "$(P)$(R)t_get_trigger")
# {
#         field (SCAN, "Passive")
#         field (DTYP, "stream")
#         field (OUT, "@niops.proto t_get_trigger $(PORT)")
# }

# record (ai, "$(P)$(R)ip_t_get")
# {
#         field (DTYP, "stream")
#         field (DESC, "Temperature of Ion Pump")
#         field (INP, "@niops.proto ip_t_get $(PORT)")
#         field (SCAN, "I/O Intr")
#         field (EGU, "DegreeCelsius")
# }

# record (ai, "$(P)$(R)np_t_get")
# {
#         field (DTYP, "stream")
#         field (DESC, "Temperature of NP generator")
#         field (INP, "@niops.proto np_t_get $(PORT)")
#         field (SCAN, "I/O Intr")
#         field (EGU, "DegreeCelsius")
# }

# record (ai, "$(P)$(R)ge_t_get")
# {
#         field (DTYP, "stream")
#         field (DESC, "Temperature of getter")
#         field (INP, "@niops.proto ge_t_get $(PORT)")
#         field (SCAN, "I/O Intr")
#         field (EGU, "DegreeCelsius")
# }


Terminator = CR;
ReadTimeout = 2000;
WriteTimeout = 200;
ExtraInput = Ignore;

wait_ms = 500;
@replytimeout { wait 10000; }

idn_get {
        out "V";
        in "%#s";
}

# Common
NIOPS_stat_get {
        out "TS";
        wait $wait_ms;
        # Example 
        # IP ON, Switch 2 ON, Switch 3 ON, NP OFF, Alarm OFF;
        # IP OFF, NP ON, ALARM OFF;
}

# Ion Pump Control
IP_on_get {
        in "IP %{OFF|ON}";
}

IP_on_set {
        out "%{B|G}";
        in "$";
}

IP_i_get {
        out "i";
        in "%x";
}

IP_u_get {
        out "u";
        in "%x";
}

IP_p_get {
        out "Tb";
        in "%e";
}

# NEG Pump Control
NP_on_get {
        in "NP %{OFF|ON}";
}

t_get_trigger {
        out "TC";
}

ip_t_get {
        # Ion pump temperature
        in "Temperature %d C, %*d C, %*d C";
}

np_t_get {
        # Device temperature
        in "Temperature %*d C, %d C, %*d C";
}

ge_t_get {
        # Getter Temperature
        in "Temperature %*d C, %*d C, %d C";
}

debug {
        out "%s";
        in "%39c";
}
#wird nicht benötigt
#record(waveform, $(P)$(R)all_get) {
#  field(DTYP, stream)
#  field(INP, "@sip_power.proto test($(P)$(R)) $(PORT)")
#  field(SCAN, "5 second")
#  field(FTVL, UCHAR)
#  field(NELM, 500)
#}

record(bo, $(P)$(R)on_set) {
  field(DESC, "Deactivate/Activate output power")
  field(DTYP, stream)
  field(OUT, "@sip_power.proto start($(P)$(R)) $(PORT)")
}

#record(bo, $(P)$(R)off_set) {
#  field(DESC, "Stop to deactivate output power")
#  field(DTYP, stream)
#  field(OUT, "@sip_power.proto stop($(P)$(R)) $(PORT)")
#}

record(bo, $(P)$(R)reset) {
  field(DESC, "Rest stat af 3 arcals or ovcurals<45sec")
  field(DTYP, stream)
  field(OUT, "@sip_power.proto reset($(P)$(R)) $(PORT)")
}

record(bo, $(P)$(R)clear_alarms) {
  field(DESC, "Reset all alarm latches")
  field(DTYP, stream)
  field(OUT, "@sip_power.proto clear_alarm($(P)$(R)) $(PORT)")
}

record(ai, $(P)$(R)idn_get) {
  field(DESC, "Show device serial number")
  field(DTYP, stream)
  field(INP,  "@sip_power.proto read_all $(PORT)")
  field(SCAN, "1 second")
}

record(ai, $(P)$(R)i_get) {
  field(DESC, "Show output current in A")
  field(DTYP, stream)
  field(INP,  "@sip_power.proto read_i $(PORT)")
  field(SCAN, "I/O Intr")
  field(EGU,  "nA")
  #field(FLNK, "$(P)$(R)calc_press")
  field(FLNK, "$(P)$(R)p_get")
}

#record(calcout, $(P)$(R)calc_press) {
#  field(DESC, "Calculate pressure in mbar")
#  field(INPA, "$(P)$(R)i_get MS")
#  field(CALC, "A*1e-9*0.0142")   #fehlt Antwort von Simon
#  field(OUT,  "$(P)$(R)p_get PP MS")
#}

record(ai, $(P)$(R)p_get) {
  field(DESC, "Show pressure in mbar")
  field(LINR, "LINEAR")
  field(ASLO, 0.0142e-9) #fehlt Antwort von Simon Umrechnung für torr
  #field(EGU,  "torr")
  field(EGU,  "mbar")
  field(PREC, "2")
}

record(ai, $(P)$(R)u_get) {
  field(DESC, "Show output voltage in V")
  field(DTYP, stream)
  field(INP,  "@sip_power.proto read_u $(PORT)")
  field(SCAN, "I/O Intr")
  field(EGU,  "V")
}

record(ai, $(P)$(R)t_get) {
  field(DESC, "Read temperature")
  field(DTYP, stream)
  field(INP,  "@sip_power.proto read_t $(PORT)")
  field(SCAN, "I/O Intr")
  field(LINR, "LINEAR")
  field(AOFF, -273.15)
  field(EGU,  "Celsius")
}

record(ai, $(P)$(R)arcs_get) {
  field(DESC, "Show number of arcing events")
  field(DTYP, stream)
  field(INP,  "@sip_power.proto read_a $(PORT)")
  field(SCAN, "I/O Intr")
}

record(mbbiDirect, $(P)$(R)stat_get) {
  field(DESC, "Show power supply status")
  field(DTYP, stream)
  field(INP,  "@sip_power.proto read_st $(PORT)")
  field(SCAN, "I/O Intr")
  field(MASK, "0xFFFF")
  field(FLNK, "$(P)$(R)on_get")
}

record(mbbiDirect, $(P)$(R)swstat_get) {
  field(DESC, "Show switches output status")
  field(DTYP, stream)
  field(INP,  "@sip_power.proto read_swst $(PORT)")
  field(SCAN, "I/O Intr")
  field(MASK, "0xFFFF")
}

#mit dieser Vorgehensweise kann man mit caget die Statusbits einzeln abfragen
#bit 0
record(bi, $(P)$(R)on_get) {
  field(DESC, "Get status of ps is started or not")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B0")
  field(ZNAM, "Stop")
  field(ONAM, "Start")
  field(FLNK, "$(P)$(R)restart_get")
}

#bit 1
record(bi, $(P)$(R)restart_get) {
  field(DESC, "Get status of ps needs a restart")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B1")
  field(ZNAM, "No need restart")
  field(ONAM, "Need restart")
  field(FLNK, "$(P)$(R)currgrad1_get")
}

#bit 2
record(bi, $(P)$(R)currgrad1_get) {
  field(DESC, "Get status of ps output current gradient")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B2")
  field(ZNAM, "No current gradient")
  field(ONAM, "Output current gradient")
  field(FLNK, "$(P)$(R)currgrad2_get")
}

#bit 3
record(bi, $(P)$(R)currgrad2_get) {
  field(DESC, "Get status of ps output current gradient")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B3")
  field(ZNAM, "No current gradient")
  field(ONAM, "Output current gradient")
  field(FLNK, "$(P)$(R)global_alarm_get")
}

#bit 4
record(bi, $(P)$(R)global_alarm_get) {
  field(DESC, "At least one alarm latch is set")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B4")
  field(ZNAM, "No global alarm")
  field(ONAM, "Global alarm")
  field(FLNK, "$(P)$(R)safe_alarm_get")
}

#bit 5
record(bi, $(P)$(R)safe_alarm_get) {
  field(DESC, "Input signal is missing")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B5")
  field(ZNAM, "No safe alarm")
  field(ONAM, "Safe alarm")
  field(FLNK, "$(P)$(R)interl_alarm_get")
}

#bit 6
record(bi, $(P)$(R)interl_alarm_get) {
  field(DESC, "Interlock input signal is missing")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B6")
  field(ZNAM, "No interlock alarm")
  field(ONAM, "Interlock alarm")
  field(FLNK, "$(P)$(R)tmp_alarm_get")
}

#bit 7
record(bi, $(P)$(R)tmp_alarm_get) {
  field(DESC, "Internal temperature > 80 Celsius")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B7")
  field(ZNAM, "No over temperature alarm")
  field(ONAM, "Over temperature alarm")
  field(FLNK, "$(P)$(R)inpvolt_alarm_get")
}

#bit 8
record(bi, $(P)$(R)inpvolt_alarm_get) {
  field(DESC, "Over/under-volt 25% the rated input volt")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B8")
  field(ZNAM, "No input voltage alarm")
  field(ONAM, "Input voltage alarm")
  field(FLNK, "$(P)$(R)outvolt_alarm_get")
}

#bit 9
record(bi, $(P)$(R)outvolt_alarm_get) {
  field(DESC, "Over/under-volt 5% the rated output volt")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B9")
  field(ZNAM, "No output voltage alarm")
  field(ONAM, "Ouput voltage alarm")
  field(FLNK, "$(P)$(R)outcur_alarm_get")
}

#bit 10
record(bi, $(P)$(R)outcur_alarm_get) {
  field(DESC, "Output over current event")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B10")
  field(ZNAM, "No output over-cur alarm")
  field(ONAM, "Ouput over-cur alarm")
  field(FLNK, "$(P)$(R)arcing_alarm_get")
}

#bit 11
record(bi, $(P)$(R)arcing_alarm_get) {
  field(DESC, "Arcing event is detected")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B11")
  field(ZNAM, "No arcing alarm")
  field(ONAM, "Arcing alarm")
  field(FLNK, "$(P)$(R)com_alarm_get")
}

#bit 12
record(bi, $(P)$(R)com_alarm_get) {
  field(DESC, "No request for KEEPALIVE ms")
  field(DTYP, "Soft Channel")
  field(INP,  "$(P)$(R)stat_get.B12")
  field(ZNAM, "No communication alarm")
  field(ONAM, "Communication alarm")
  #field(FLNK, "$(P)$(R)bit_13")
}
#LockTimeout   = 10000;
#ReplyTimeout  = 1500;
#ReadTimeout   = 1500;
#WriteTimeout  = 300;
ExtraInput = Ignore;

#test
#{
#  out "\x01\x05";
#  in "%r";
#}

# Stop or start
start
{
  #out "\x01\x01";
  out "%{\x01\x02|\x01\x01}";
}

#stop
#{
#  out "\x01\x02";
#}

reset
{
  out "\x01\x03";
}

clear_alarm
{
  out "\x01\x04";
}

read_all
{
  out "\x01\x05";
  in "\x01\x80%*6r%4r";
  ExtraInput= Ignore;
}

read_i
{
  # out "\x01\x05";
  in "\x01\x80%*10r%4r";
  ExtraInput= Ignore;
}

read_u
{
  in "\x01\x80%*14r%2r";
  ExtraInput= Ignore;
}

read_t
{
  in "\x01\x80%*20r%2r";
  ExtraInput= Ignore;
}

read_a
{
  in "\x01\x80%*22r%2r";
  ExtraInput= Ignore;
}

read_st
{
  in "\x01\x80%*32r%2r";
  ExtraInput= Ignore;
}

read_swst
{
  in "\x01\x80%*34r%r";
  ExtraInput= Ignore;
}

Navigate by Date:
Prev: Email configuration issue LONG FENG via Tech-talk
Next: Re: adl2ui segmentation fault - Needs contacts for CaQTDM development Brands Helge via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025 
Navigate by Thread:
Prev: RE: EPICS support for SAES NEG POWER pump controller Mark Rivers via Tech-talk
Next: Email configuration issue LONG FENG via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025 
ANJ, 28 Nov 2024 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions ·
· Download · Search · IRMIS · Talk · Documents · Links · Licensing ·