Skip to content

EPICS module for the Nikola 3K/5K chiller from the Solid State Cooling Systems company

Notifications You must be signed in to change notification settings

slac-epics/nikola

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nikola

EPICS module for the Nikola 3K/5K chiller from the Solid State Cooling Systems company.

This EPICS module provides:

  • a database file db/nikola.db
  • a protocol file db/nikola.proto
  • a library lib//libnikola.a
  • an example PyDM GUI nikolaApp/displays/nikolaMain.ui
  • a simulator written in Python in the directory nikolaApp/test_util/. You can run an IOC against it to test features. The operation of the simulator is explained in the file README.simulator.md.
  • an IOC example application located in the iocs directory

The provided library contains an Asyn Interpose Interface that limits the output of messages to the chiller controller to a maximum of 500 ms. According to the manual, this is the maximum rate which the controller can handle messages. So, the library is not optional.

The IOC example application

If you want to start immediately to check if your Nikola chiller is communicating with the software, build the module together with the IOC example application by using:

make BUILD_IOCS=YES

Modify the file iocs/nikolaIOC/iocBoot/iocnikolaIocExample/st.cmd editing the variables DEVICE_IP and DEVICE_PORT to match your Nikola controller. Save the file and just run ./st.cmd. The PVs will have the TEMP:OUTS:123: base name. If you have PyDM installed, you can open the PyDM example display by going to nikolaApp/displays/ and running:

pydm -m "P=TEMP:OUTS:123" nikolaMain.ui &

The easiest way to start a new IOC application for the Nikola chiller is to copy the IOC example application iocs/nikolaIOC and modify it for your needs. It contains all configuration for configure/RELEASE and Makefiles. Make sure you define the appropriate path to the Nikola module in configure/RELEASE after it is built and released. Otherwise, if you want to integrate this module to an existent IOC application, follow the instructions in the next section.

Integrating the module to an IOC application

configure/RELEASE

Must define the location for asyn, streamdevice, and the nikola module as described below. Adapt the paths to your case.

# ==========================================================
# Define the version strings for all needed modules
# Use naming pattern:
#   FOO_MODULE_VERSION = R1.2
# so scripts can extract version strings
# Don't set your version to anything such as "test" that
# could match a directory name.
# ==========================================================
STREAM_MODULE_VERSION=R2.8.9-1.2.2
ASYN_MODULE_VERSION=R4.39-1.0.2
NIKOLA_MODULE_VERSION=R1.0.0

# ==========================================================
# External Support module path definitions
#
# If any of these macros expand to a path which
# contains an "include" directory, that directory will be
# included in the compiler include path.
#
# If any of these macros expand to a path which
# contains a "lib/<arch>" directory, that directory will be
# included in the compiler link path for that architecture.
#
# If your build fails, look for these paths in your build output
# ==========================================================
STREAM=$(EPICS_MODULES)/streamdevice/$(STREAM_MODULE_VERSION)
ASYN=$(EPICS_MODULES)/asyn/$(ASYN_MODULE_VERSION)
NIKOLA=$(EPICS_MODULES)/nikola/$(ASYN_MODULE_VERSION)

configure/CONFIG_SITE

As PCRE is used by Stream Device, we need to add its path as described below. Adapt the path to your case.

PCRE=YES
PCRE_PACKAGE_NAME=pcre
PCRE_VERSION=8.39
PCRE_TOP=$(PACKAGE_SITE_TOP)/$(PCRE_PACKAGE_NAME)/$(PCRE_VERSION)
PCRE_LIB=$(PCRE_TOP)/$(PKG_ARCH)/lib
PCRE_INCLUDE=$(PCRE_TOP)/$(PKG_ARCH)/include

nikolaApp/Db/Makefile

Add the following:

DB_INSTALLS += $(NIKOLA)/db/nikola.db
DB_INSTALLS += $(NIKOLA)/db/nikola.proto

nikolaApp/src/Makefile

Here we defined PROD_IOC = nikolaIOC. You need to change it for your case in the instructions below. PCRE is used by Stream Device. Add the following:

# Support Perl C regular expression library
USR_INCLUDES += -I$(PCRE_INCLUDE)
pcre_DIR = $(PCRE_LIB)
USR_LIBS_Linux += pcre

# nikola.dbd will be made up from these files:
nikolaIOC_DBD += base.dbd

# Include dbd files from all support applications:
nikolaIOC_DBD += nikola.dbd
nikolaIOC_DBD += stream.dbd
nikolaIOC_DBD += drvAsynIPPort.dbd
nikolaIOC_DBD += asyn.dbd

# Add all the support libraries needed by this IOC
nikolaIOC_LIBS += nikola
nikolaIOC_LIBS += stream
nikolaIOC_LIBS += asyn

iocBoot/<IOC name>/st.cmd

You need to create the Asyn port, activate the interpose interface which will limit messages to the chiller controller to a maximum of 500 ms, and load the database. Change the PV base name, and IP address and port of the chiller to your needs.

epicsEnvSet( "DEVICE_IP",  "127.0.0.1" )
epicsEnvSet( "DEVICE_PORT",  "22222" )
epicsEnvSet( "LOCA", "OUTS" )
epicsEnvSet( "POS", "123" )
epicsEnvSet( "PV_BASE", "TEMP:$(LOCA):$(POS)" )
epicsEnvSet( "STREAM_PROTOCOL_PATH", "$(TOP)/db" )

drvAsynIPPortConfigure( "P0", "$(DEVICE_IP):$(DEVICE_PORT)", 0, 0, 0 )
#asynSetTraceMask("P0", 0, "0x08")
#asynSetTraceIOMask("P0", 0, "0x01")

# Limit messages to the port at this maximum number of seconds
# rateLimitInterposeInit( asyn_port, limit_in_s )
rateLimitInterposeInit("P0", "0.5")

## Load record instances
dbLoadRecords("db/nikola.db","device=$(PV_BASE),port=P0")

Available PVs

Normal operation PVs:

PV name Type Description
$(device):TEMP ai Read the current temperature. SCAN is set to 2 seconds to avoid overwhelming the chiller controller.
$(device):TEMPSETPT ao Define a new setpoint in °C. FLNK to $(device):TEMPSETPTACT.
$(device):TEMPSETPTACT ai Readback the setpoint to make sure it was set correctly.
$(device):START bo Write 1 to start the chiller or 0 to stop it. FLNK to $(device):STARTSTATE.
$(device):RESTART bo Clear alarms and restart the chiller.
$(device):STARTSTATE bi Check if the chiller is running or not. SCAN is set to 10 seconds, but it is also updated after $(device):START is changed (see the next table).

Utilitary PVs:

PV name Type Description
$(device):TIMER_10 bo We want to process $(device):STARTSTATE at 2 moments:
1 - Every 10 seconds;
2 - Every time $(device):START processes.
Setting a SCAN in \$(device):STARTSTATE doesn't allow $(device):START to use a FLNK, so we need this intermediary record. If the chiller is started from the physical button, the status PV will occasionally be updated, too. At the same time the user doesn't have to wait for 10 seconds to see that the button press was effective.

Device status PVs:

PV name Type Bit # of
DEVICESTATUS_RAW
Description
$(device):DEVICESTATUS_RAW mbbiDirect SCAN = 5 second. Reads the status byte from the controller, returning a number. This will be decomposed into the the bi records described below.
$(device):RUNSTAT bi B0 Is the chiller running?
$(device):REMOTESTAT bi B1 Remote or local?
$(device):READYSTAT bi B2 Is the chiller ready?
$(device):TEMPLOW_ALARM bi B3 Alarm for low temperature.
$(device):TEMPHIGH_ALARM bi B4 Alarm for high temperature.
$(device):HEATINGSTAT bi B5 Configuration is set to heating or cooling?
$(device):SYSWARNING bi B6 There's a system warning present.
$(device):SYSALARM bi B7 There's a system alarm present.

Fault status PVs:

PV name Type Bit # of
FAULTSTATUS_RAW
Description
$(device):FAULTSTATUS_RAW mbbiDirect SCAN = 5 second. Reads the fault status 16-bit word from the controller, returning a number. This will be decomposed into the the bi records described below.
$(device):RTDSTAT bi B0 RTD fault
$(device):TANK_LVL_LOW bi B1 Tank level low
$(device):VFDSTAT bi B2 VFD fault
B3 Bit 3 is not used. No PV available.
$(device):RTDALARMWIDTH bi B4 RTD < > alarm width
$(device):TANK_LVL_EMPTY bi B5 Tank level empty
B6 Bit 6 is not used. No PV available.
$(device):COOLANT_FLOW_LOW bi B7 Coolant flow low
$(device):COOLANT_FLOW_HIGH bi B8 Coolant flow High
$(device):PCW_FLOW_LOW bi B9 PCW flow low
B10 Bit 10 is not used. No PV available.
$(device):RESIST_HIGH bi B11 Resistivity high
$(device):RESIST_LOW bi B12 Resistivity low
B13 Bit 13 is not used. No PV available.
$(device):PSENSOR bi B14 Pressure sensor fault
B15 Bit 15 is not used. No PV available.

Autosave

Fields that we considered important to autosave are using info(autosaveFields) in the appropriate records. Make sure to use the makeAutosaveFiles function in st.cmd to take advantage of this feature.

Example GUI

A GUI is provided and can be used as an inspiration for IOC applications. It is located in nikolaApp/displays/nikolaMain.ui. To open it, pass the $(P) macro with the PV base name. For example:

pydm -m "P=TEMP:OUTS:123" nikolaMain.ui &

About

EPICS module for the Nikola 3K/5K chiller from the Solid State Cooling Systems company

Resources

Stars

Watchers

Forks

Packages

No packages published