Calorimeter is an instrument to measure the amount of heat emitted or absorbed during a chemical or physical process. The Setaram calorimeter was designed for studying the process of dissolving a substance (so-called solute) in a large amount of solvent. The calorimeter has two identical reaction chambers: vessels for solvent, into which were submerged a temperature sensor, a resistor and and small enclosure for solute encased in glass beads. The chambers are well insulated, which is why the calorimeter is called adiabatic. After setting-up and waiting for the chambers to come to thermal equilibrium, the operator crashes the glass beads releasing the solute, which starts dissolving. The insulation keeps the heat in the reaction chamber, which hence changes its temperature, measured by the sensor. Multiplying the total change in temperature during the reaction by the calibration coefficient (the thermal capacity) gives the amount of heat -- the caloric effect of the reaction. The calibration coefficient is obtained by calibrating before or after the main experiment: releasing a known amount of heat (by briefly passing a certain amount of current through the submerged resistor) and measuring the temperature change just like in the main experiment.
The temperature sensor is connected to a potentiometric strip chart recorder, which draws the temperature vs. time graph on the advancing long strip of paper (chart). When the system is in the equilibrium, the graph is the flat straight line: so-called baseline. When a reaction is going on, the line curves. The area under the curve is the total change in temperature. Measuring this area by hand -- manual integration -- and computing necessary corrections was the most tedious, also time consuming and error-prone, part of the experiment. I was called for help.
The developed control program automates the tedium of conducting the experiment. Only crashing the glass beads and calibration had to be done manually. Concretely, the control program continuously acquires temperature sensor readings and filters them. In the baseline mode, it fits the acquired points to the straight line to obtain the noise level and the baseline parameters. When the experiment/calibration is in progress, the control program continuously integrates the temperature curve, determines the end of the process, computes the total effect and various corrections. The control program ran on a Electronics BK-0010 computer with a color TV monitor, which continuously displays the current status and the baseline parameters. One can see at a glance what is going on and if the equilibrium is reached. The monitor also displays a screen form, whose fields tell the possible actions (such as: start monitoring an experiment, switch to another screen form to show accumulated results) and various parameters, some of which could be changed. The actions are activated by a single keyboard key press, with a visual feedback. The control program occupied 4 Kbytes, of 16 Kbytes of memory available on BK-0010.
The automation was done on the cheap, as necessary in those times, with the minimum of extra hardware. I only needed an analog-to-digital converter (ADC) and a small oscillator circuit, built by a friend of mine. The circuit sends the timer interrupt to the control program every 3 seconds. The ADC is connected to the temperature sensor and the computer, and can be queried to give the current temperature reading, in a peculiar binary-coded decimal format.
The control program runs `on the bare metal': it is the operating system, into which BK-0010 boots. As my other control programs, it is interrupt-driven, with two foreground and a background tasks. The high-priority foreground task is activated by the timer interrupt and runs to completion, thus ensuring accurate sampling frequency and no data loss. The task acquires the temperature reading, filters by the 3-point median filter, and processes according to the current mode. In the baseline mode, it fits the current point, along with some number of previous points, to the baseline. In the reaction (effect) mode, the processing is guided by a 5-state automaton (see the reference below). The lower-priority foreground task is activated by the keyboard interrupt and handles operator commands. Refreshing the display is done by a background task. Computing the caloric effect requires more computation and is also done by a background task. Such tasks are interruptible and run when all urgent processing is completed.
BK-0010, however, has only one interrupt level: interrupt priorities had to be emulated. The high-priority foreground task is run as the timer interrupt handler, with interrupts disabled, to avoid data loss. The processing is typically fast, so that interrupts remain disabled only for a short time. For any longer processing, a background job is submitted. The keyboard interrupt handler only sets a flag that the operator input is pending, and immediately exits. Reading the operator request and acting on it is done in background. The background mode scheduler is activated on return from interrupt. It first checks if keyboard input is pending, and, if so, runs the operator command task. Otherwise, other scheduled background tasks are run.
The control program is written in PDP-11 macro-assembly: Macro-11. It was developed on a "Electronics E-85" computer, a beefier PDP-11 clone; a compiled executable was then transmitted to the target computer via a custom local network.
A notable feature of the control program is structured handling of operator commands, via screen forms, or `menus'. A menu is a structure containing the text to show on screen plus the description of characters (key presses) that are accepted for this menu, and how to interpret them. Here is a typical menu:
Menu.1::
.word 7,10$
.bktext <1,16.>,<\^\g>
.bktext <6,16.>,<Mode: \b\~A\~\guto or \b\~M\~\ganual>
.bktext <6,17.>,<Baseline stability>
.bktext <12.,18.>,<\b\~T\~\ghreshold>
.bktext <6,19.>,<\b\~N\~\g scanned>
.bktext <6,20.>,<Start the effect managing>
.bktext <6,21.>,<for \b\~L\~\geft or \b\~R\~\gight cell>
.bktext <6,23.>,<\b\~O\~\gther>
.bktext ,<\r>
.byte 0
.even
10$: mentry 'A,<12.,16.>,1,SetAuto
mentry 'M,<22.,16.>,1,SetManual
mentry 'T,<10.,18.>,2,<BLs2.thr,<23.+<18.*256.>>>,color=<\r>
mentry 'N,<4,19.>,2,<Nscanned,<23.+<19.*256.>>>,color=<\r>
mentry 'L,<10.,21.>,1,StinLeft
mentry 'R,<20.,21.>,1,StinRight
mentry 'O,<4,23.>,0,Menu.2
Here, .bktext is a macro, whose first argument (in angular brackets)
is the screen position (column,row), and the second is the text to
show at that position. The text may include control code such as \g
for green text and \~ for toggling the inverse video mode. It should
be stressed that the BK-0010 terminal is an ordinary TV monitor
rather than a VT-100 terminal and is not controlled
by escape-codes. To position the cursor or switch colors one has
to make a dedicated BIOS call. The macro mentry describes the key
accepted in the current screen form and what to do if it is
pressed. In Menu.1, key 'A' invokes the SetAuto function to set the Auto mode;
key 'T' lets the operator change
the stability threshold (whose current value is taken from the
variable BLs2.thr and displayed in red on the same line), key 'O'
switches to Menu.2. Compiling such code and expanding macros
took noticeable time: Macro-11 assembler felt as slow as the C
compiler. (C compilation was very slow those days.)
Not only BK-0010 had no floating-point number support -- it also did not provide integer multiplication and division. I had to use fixed-point arithmetic throughout (and implement multiplication, squaring and division). I still remember what a pain it was.