Automated testing of the PE 2 Stirling engine

Stirling engine test setup

As you can see from the photo, I’ve switched over from manually taking data from sensors to semi-automated testing of the 3D printed Stirling engine. I’m still manually controlling the heat input so I wouldn’t call this fully automated testing.

This article will cover the test setup details including a schematic and a listing of the Arduino program I’m using. In the next article I’ll cover speed versus temperature testing of the engine using this setup. After that I’ll use the same test setup with a different program to measure the frictional power loss of the engine versus speed.

Computer-controlled data acquisition provides much higher quality data than is possible by taking data manually. After the initial system is built it takes much less of your time to run tests too. The automated measurement system I’m using is relatively simple to build and the components are not expensive.

Semi-automated test hardware

Arduino Uno or Boarduino ($25 to $29.95)This microcontroller connects through a USP port to your computer. I simply have the Arduino or Boarduino write the collected data to a serial port on my computer via the USB port.
TMP36 temperature sensors ($2.00 each)I use three of these temperature sensors. They provide an analog voltage output that is converted to a digital temperature by the microcontroller. The three temperatures I measure are ambient air temperature (Tambient), cold plate temperature (Tc), and hot plate temperature (Th).
US5881LUA Hall-effect sensor ($4.00)This sensor is used to provide the rotational period of the engine crankshaft so that I can derive the engine speed. I typically use Hz (cycles/second) = (1/ period), but you can multiply the cycles/second by 60 to get the RPM. A magnet attached to the flywheel actuates the Hall-effect sensor once each revolution. The output of the sensor drives a digital input to the microcontroller. The input causes the microcontroller to run an interrrupt routine that computes the time interval since the last interrupt to determine the period.

Not including the wiring or the optional fan, the total cost of the parts was $40 from Adafruit. You can buy the parts elsewhere, but I highly recommend you visit and use the excellent tutorial material at Adafruit’s site to learn how to use the microcontroller and sensors. With this small outlay for electronics and some time spent learning how to use the microcontroller and sensors, you can get a lot of really useful performance information on this Stirling engine (or any Stirling engine). The only difference is that on a high-temperature engine you will need to use temperature sensors that work at higher temperatures.

Stirling engine test system schematic

The schematic is quite simple. This entire circuit is powered by the USB port that connects the circuit to your computer. You’ll need to connect the power and ground to the four sensors as shown. The one resistor shown should be between 2k and 10k ohms.

Temperature correction for Th

Even though the temperature sensors you are using may be reasonably accurate, they may not record the temperature you want. This was the case for the Th temperature sensor (see photo).

hot end test setup

The Th sensor was epoxied to aluminum that was screwed to the engine’s hot plate. Besides being heated by thermal conduction from the hot plate, the sensor was also cooled by surround air so that it measured less than the actual temperature of the hot plate as measured with in IR (infrared) optical temperature sensor. To minimize this problem I isolated the hot end of the engine using an acrylic sheet, an ABS tube, and some cardboard (see photo). This helped to reduce convection cooling of the sensor, but it still did not measure the temperature of the hot plate as accurately as I wanted.

To correct for this temperature error I took a set of data with the engine running where I monitored the Th sensor, the Tambient sensor, and also made IR measurements of the engines’s hot plate. I plotted the data with the ambient temperature subtracted from both the Th sensor measurement and from the IR measurement (ThIR) of Th. I reasoned that the temperature offset should be close to a linear function of (Th – Tambient). If the ambient temperature was the same as Th there should be no offset.

The data is plotted below. The plot shows the true temperature difference (ThIR – Tambient) is 1.091(Th-Tambient). I now apply this correction to my data when I put it into a spreadsheet, but leave the raw data unchanged.

Th temperature correction

Of course nothing ever comes out perfectly in the experimental world. The 2.28 offset in the above equation probably indicates an offset in one or more of my sensors. I’m currently not including the 2.28 correction factor offset in my temperature corrections while I try to find out why it shows up in the plot.

Originally I needed a similar temperature correction for the Tc sensor, but I found I could dispense with it by using the small cooling fan shown in the first photo. The fan cools the cold plate so that the sensor and plate end up with almost identical temperatures.

Program listing for the Arduino

The following listing is for the program I used for speed vs temperature testing of the engine. The program may be used on either the Arduino Uno or the Boarduino. The two microcontrollers boards are very similar. The advantage in using the Boarduino in trial applications is that you can plug it into a solderless breadboard, easily connect the wires and have room for some additional circuitry such as the Tambient sensor. For a more permanent setup I would connect all the wiring to a shield that can be plugged into an Ardunio.

This program averages the speed (Hz) and temperature readings over 30 seconds (30000 milliseconds). You can set the averaging period to other values.

/*
Instrumentation controller for PE2 engine tests 1/09/13
Update 1/22/13
Features:
1. Measures the ambient, hot, and cold plate temperatures. 
   All display values in degrees F
2. Measures the crankshaft speed in hertz or RPM and display. 
 */

//Hardware Pin assignments ************************************

int T_ambient_pin = 0; // Analog input pin for ambient sensor
int Tc_pin = 1; 
int Th_pin = 2;

int speedPin = 2; // Digital pin for Hall Effect sensor

//Variable declarations ***************************************

int readingC;
int readingH;
int readingAmb;
int val = 0;

const float ThOffset = 0;
const float TcOffset = 0;
const float TambientOffset = 0;

#define aref_voltage 5.0  
unsigned long time;
unsigned long oldTime =  0;
unsigned long oldLoopTime =  0;
unsigned long deltaTime;

float Hz;
int N_Hz = 0; // number of Hz readings to average
float sum_Hz = 0; // sum of Hz readings over period
float print_Hz = 0; //

//Function definitions *********************************************

//The function is called for engine speed by interrupt on hall sensor
void hertz(){ //Interrupt routine to track Hz or RPM
  time = (millis());
  deltaTime = time - oldTime;
  Hz = 1000/float(deltaTime); 
  sum_Hz += Hz;
  N_Hz ++;
  oldTime = time;
}

//converts temp analog input to temp degF with corrections for tmp36 sensor 
//inputs: analog reading, analog ref voltage, offset correction
float tempDegF(int analogIn, float aRef, float offset){
  float tempC = float(((analogIn * aRef/1024) -0.5) * 100);
  return(((tempC + offset)*(9.0/5.0)+ 32.0));
}

// begin setup function *********************************

void setup() {
Serial.begin(9600); //Start the serial connection to view results
  
// Hardware intitialization
   pinMode(speedPin, INPUT); // Hall effect sensor, is used as an interrupt
   attachInterrupt(0, hertz, FALLING); // calls the function to use on interrupt   

// Print column heads
  Serial.print("Test name: ");
  Serial.println("PE 2 test");
  Serial.print("sec"); 
  Serial.print(", ");
  Serial.print("T_ambient"); 
  Serial.print(", ");
  Serial.print("Tc"); 
  Serial.print(", ");  
  Serial.print("Th"); 
  Serial.print(", ");
  Serial.println("Hz");

}

// Begin loop function ***************************************

void loop(){
  //Average  readings, declare and zero variables first
  
  int i = 0; // loop variable
  int settle = 0; // first read is for reading to settle.
  float temperatureFC = 0;
  float temperatureFH = 0;
  float temperatureFAmb = 0;

  while ((millis() - oldLoopTime) < 30000){ // average readings for 30 sec
     settle = analogRead(Tc_pin); // dummy reading to settle voltage. Don't use 
     readingC = analogRead(Tc_pin);
     temperatureFC += tempDegF(readingC, aref_voltage, TcOffset);
     settle = analogRead(Th_pin);
     readingH = analogRead(Th_pin);
     temperatureFH += tempDegF(readingH, aref_voltage, ThOffset);
     settle = analogRead(T_ambient_pin);     
     readingAmb = analogRead(T_ambient_pin);
     temperatureFAmb += tempDegF(readingAmb, aref_voltage, TambientOffset);
     i++;
     delay(20); // optionaly msec delay between reading sets
  }
 oldLoopTime = millis();
 
 temperatureFC /= i; //average readings
 temperatureFH /= i;
 temperatureFAmb /= i;
 
 print_Hz = 0; // If the engine isn't running default to zero Hz
 if(N_Hz > 0){
   print_Hz = sum_Hz/N_Hz;
 }
 
  Serial.print((float)oldLoopTime/1000);  
  Serial.print(",");
  Serial.print(temperatureFAmb);
  Serial.print(",");
  Serial.print(temperatureFC);   
  Serial.print(",");
  Serial.print(temperatureFH);   
  Serial.print(","); 
  Serial.println(print_Hz);
  
  // zero sums for the next set
  N_Hz = 0;
  sum_Hz = 0;
}