Bespoke Software for Oscillating Bob Viscometry
Eric Lengyel • April 12, 2026
I’m going to be speaking at the career connection series for the Virginia Tech math department next week, and it got me thinking about my first professional gig. As the title of this post suggests, it had nothing to do with computer graphics or game development, but I thought I’d tell the story of where I got started.
While I was in college in 1992, I was lucky enough to find a summer job at a small chemistry laboratory in the Columbus, Ohio area called Imagination Resources, Inc. (IRI). They did a lot of work with refrigerants and lubricants, particularly for automotive air conditioners. This was a time when ozone-destroying CFC refrigerants were being replaced by HFC refrigerants, and there was a need for data about the material compatibilities and certain properties of refrigerant-lubricant mixtures under various operating conditions. The refrigerant we worked with the most was called 1,1,1,2-tetrafluoroethane, more commonly known as R-134a, with chemical formula \(\mathrm{CF_3CH_2F}\). One of the most important properties of refrigerant-lubricant mixtures we measured was viscosity across a wide range of pressures, temperatures, and refrigerant concentrations.
I was a general lab technician for the first two summers that I worked at IRI. One of the more complicated tasks I had learned to perform involved building vacuum sealed test tubes that contained some metal or plastic material to be tested with a mixture of a lubricant and high-pressure refrigerant. These would be cooked in an oven for days to weeks so we could observe any corrosive effects on the materials. Once in a while, I would exercise my software engineering skills by writing a little program that performed a lengthy calculation or helped automate some kind of equipment. It wasn’t until the summer of 1994 that I convinced IRI that I could design a software package that would drastically reduce the amount of time-consuming repetitive work their method for measuring viscosity had required. It was to become the first major software project that I was ever paid to create, and despite its immense scope, it ended up being a success that I was very happy with. I’ll talk about how viscosity measurements were performed first, and then I’ll describe what my software did.
Measuring Viscosity
The viscometer was a tall, mostly cylindrical apparatus that had an internal pressurized test vessel surrounded by an ethylene glycol bath in a glass housing. As shown in the diagram below, the test vessel contained a cylindrical bob with hemispherical caps (a capsule) suspended from a wire that was attached to a spring at the top of the apparatus. A magnet was attached near the top of the wire so that an electric pulse sent through an external coil could pull up on the wire and set the bob in motion. Just below this was a linear variable differential transformer (LVDT) that produced a high-precision voltage reflecting the position of a second magnetic core attached to the wire. The vessel was filled with an oil to be tested, pressurized with refrigerant, and brought to a target temperature. Once the bob was set in motion, its oscillations in the fluid could be observed by monitoring the voltage output from the LVDT.
As shown in the next figure, the bob experiences several different forces as it moves through the fluid. First, the bob is pulled downward under gravity by the constant force \(-mg\), where \(g\) is the positive acceleration of gravity, and \(m\) is the total mass of all the objects on the wire suspended from the spring, including the bob, the LVDT core, and the pulser magnet. The bob is also pushed upward by a constant buoyant force of \(\rho Vg\), where \(\rho\) is the density of the fluid, and \(V\) is the volume of the bob by itself. Next, the bob is acted upon by the spring restoring force of \(-k(z - z_0)\), where \(k\) is the spring constant, and \(z_0\) is the rest position of the bob in the absence of other forces. Finally, a drag force of \(-h\,{dz/dt}\) opposes the motion of the bob, where the value of \(h\) depends on the dynamic viscosity \(\mu\) and density \(\rho\) of the fluid. A complicated analysis of the fluid motion within the cylindrical vessel as the bob oscillates shows that \(h\) is proportional to \(\sqrt{\mu\rho\mathstrut}\). (This analysis is not reproduced here, and I don’t have a reference for it, unfortunately.)
Taking these forces into consideration, the equation of motion for the vertical position \(z(t)\) of the bob is
\(m\dfrac{d^2z}{dt^2} = -h \dfrac{dz}{dt} - k(z - z_0) + (\rho V - m)g.\)(1)
In an underdamped system where \(h^2 < 4mk\), the general solution to this equation is
\(z(t) = A_0\exp\left(-\dfrac{h}{2m}t\right) \cos\left(\dfrac{\sqrt{4mk - h^2}}{2m}t + \phi\right) + \dfrac{(\rho V - m)g}{k} + z_0\)(2)
This function has the form of an exponentially decaying oscillation with the initial amplitude \(A_0\), as shown in the following graph. This is characteristic of damped oscillatory motion in a viscous fluid.
The angular frequency of the oscillations is a constant given by
\(\omega = \dfrac{\sqrt{4mk - h^2}}{2m},\)(3)
and the period \(P\) is thus
\(P = \dfrac{2\pi}{\omega} = \dfrac{4\pi m}{\sqrt{4mk - h^2}}.\)(4)
Shifting so that the phase \(\phi\) is zero, the amplitude \(A_n\) of the n-th peak is
\(A_n = z(Pn) - \dfrac{(\rho V - m)g}{k} - z_0 = A_0\exp\left(-\dfrac{h}{2m}Pn\right).\)(5)
The ratio of the amplitudes at peaks \(n_1\) and \(n_2\) can be expressed as
\(\dfrac{A_{n_1}}{A_{n_2}} = \exp\left(\delta(n_1 - n_2)\right),\)(6)
where \(\delta\) is the decrement defined as \(\delta = ({h / 2m})P\). The decrement is experimentally determined by measuring the amplitudes of two peaks separated by many oscillations, as shown in the graph above, and calculating
\(\delta = \dfrac{\ln A_{n_1} - \ln A_{n_2}}{n_1 - n_2}.\)(7)
We then solve for the drag constant \(h\) to arrive at
\(h = 4m^2\delta\sqrt{\dfrac{mk}{4m^4\delta^2 - \pi^2}}.\)(8)
The fluid density is calculated from the equilibrium position \(z_{\mathrm{eq}}\) of the bob, which is given by
\(\displaystyle z_{\mathrm{eq}} = \lim_{t\to\infty} z(t) = \dfrac{(\rho V - m)g}{k} + z_0.\)(9)
We can easily solve this for the density to get
\(\rho = \dfrac{({k/g})(z_{\mathrm{eq}} - z_0) + m}{V}.\)(10)
In practice, the values of \(m\), \(V\), \(k\), and \(z_0\) were not plugged directly into these formulas and weren’t necessarily known at all. Instead, because \(h\) is proportional to \(\sqrt{\mu\rho\mathstrut}\), we calculated the viscosity \(\mu\) with the formula
\(\sqrt{\mu\rho\mathstrut} = \dfrac{A\delta + B}{\sqrt{C\delta^2 + D\delta + E}},\)(11)
which is a generalization of the expression for \(h\) in Equation (8) above. The coefficients \(A\), \(B\), \(C\), \(D\), and \(E\) were determined by calibrating the viscometer against fluids of known viscosity and density. Since the density \(\rho\) given by Equation (10) is a linear function of the equilibrium position \(z_{\mathrm{eq}}\), it was calculated with
\(\rho = F z_{\mathrm{eq}} + G,\)(12)
where the coefficients \(F\) and \(G\) were also determined by calibration.
Before 1994, the LVDT was hooked up to a chart recorder that would plot the position of the bob on a roll of pin-fed paper. A technician would start the recorder, press a button to activate the magnetic pulser, let the recorder plot bob oscillations until a sufficient number of peaks were drawn, and then stop the recorder. They would then tear off the paper, manually measure the amplitudes of two peaks, and count the number of peaks in between them. Using a hand calculator, they would determine the decrement and compute a viscosity using the a big calibration curve plotted on graph paper taped to the wall. Each viscosity data point, along with its temperature, pressure, density, and refrigerant concentration, was entered into a Lotus 1-2-3 spreadsheet. Once enough data points had been collected, Lotus was used to generate charts that showed isothermal and isobaric viscosity curves. Each data point had to be measured several times to ensure consistency. Needless to say, this whole process was very tedious and error-prone.
The Software
At the time, I was extremely knowledgeable about Macintosh programming, so I chose the Apple platform for the software that I would write. I used the Symantec THINK C development environment to write all of the code. Everything was built and deployed on a Mac Centris with a 25 MHz Motorola 68040 processor running the “System 7” operating system. I added an analog-to-digital converter board made by a company called Strawberry Tree that would be used to read the voltage from the LVDT. This board also had digital outputs, so I wired one of them up to a mechanical relay that controlled the electromagnetic pulser.
The first thing I did was implement an oscilloscope window that would graph the LVDT voltage to make sure all the I/O was working properly. I then started working on the code that would actually take measurements. It was able to calculate the fluid density by measuring the equilibrium position of the bob and applying Equation (12). Once that was done, the user could click a button to generate a pulse of consistent duration that set the bob in motion. As the bob oscillated, the software detected peaks in real time, and once enough of them had appeared, it instantly calculated the decrement with Equation (7) and applied Equation (11) to compute the viscosity. This part of the application could be configured to take multiple measurements without user interaction. After one viscosity measurement, it would wait for the bob’s oscillations to settle down beneath a resting threshold, and then it would send another pulse to the viscometer to start up the next measurement.
The calibration data needed to calculate the viscosity and density was determined by measuring the decrements and equilibrium positions for several fluids with known properties. These data points were collected in a separate window where the software calculated the values of the coefficients \(A\), \(B\), \(C\), \(D\), and \(E\) in Equation (11) representing the best fit curve for \(\sqrt{\mu\rho\mathstrut}\) in terms of the decrement \(\delta\) and saved it to a special calibration file. The linear density coefficients \(F\) and \(G\) in Equation (12) representing the best fit line in terms of the equilibrium position \(z_{\mathrm{eq}}\) were also calculated and saved in the same file.
After the data acquisition parts of the software were complete, my attention turned toward graphing and printing. The software had to take many viscosity measurements over a range of temperatures and pressures and fit empirical curves to the data. It could generate a variety of plots, the most important of which was a plot of log viscosity as a function of temperature showing isobaric curves at several different pressures. The last thing to be finished was the printing code, which allowed data and plots to be printed directly from the software.
After a few months of development, tasks that used to take a couple hours could now be done in about ten minutes. Viscosity measurements were more precise, and the potential for human error was reduced considerably. It was an extremely fun and rewarding experience to develop this software, and I was told it was still in service for many years after I moved to California in 1996.
See Also
- Cavestri, Richard. Measurement of viscosity, density, and gas solubility of refrigerant blends in selected synthetic lubricants. Department of Energy Office of Scientific and Technical Information, 1995.