I recently (about six months ago) had to update a high power test rig. The original test rig had been in service for over 25 years and was showing its age. It wasn't working properly due to interference from external sources which was causing the control of the test equipment to malfunction.
The rig was used to control a power converter product during temperature and vibration stress testing. The power converter itself would receive electrical energy from an external source and then use this electricity to generate a very stable 28 V dc which was then used to power sub systems. I cannot provide the specific function as it is proprietary.
I won't share a photo of the units under test as that is also proprietary. I can however discuss how the test rig was originally implemented using some custom hardware and various pieces of off the shelf instrumentation to achieve the various test signals and routines required as this is fairly standard for any test rig.
The device under test is essentially a very high power switch mode buck boost converter which takes in a range of voltage inputs and provides a steady output at a range of power requirements as needed. Various outputs are also monitored to ensure that the device under test does not change state whilst under test.
The test regime required several different test conditions to be satisfied but essentially relied on the control of two HP 6681A power supplies to provide the simulated electrical supply from the external source. The unit under test was powered by these supplies and combined with a switch box which would satisfy the input signals needed. A large external load provided the standard operating conditions the unit would be exposed to and the outputs present would be monitored by a data-logger.
The original test rig is below:
The image shows several pieces of test equipment - 5x lab power supplies which were used to power and control the test rig, the 2x high power power supplies used to provide the power to the devices under test and 2x high power resistive loads. A Keysight data-logger is used to monitor the device under test outputs and the data is displayed on the fly on the computer monitor on the top shelf.
The critical part of the system was the device which provided the voltage profile to control the 2x large high power supplies which we shall call the profile generator.
A rough diagram of the test rig is below:
The profile generator is the key part of the system as it is that which controls the power supply to the device under test. The signal required was a slowly changing ramp signal which began at 24.5 V dc and reduced to 12 V dc in a second and then slowly increased over 18 seconds back up to 24.5 V dc simulating a specific start condition. The unit under test had to maintain its 28 V dc output under load during this ramp without any of the outputs being affected.
The original profile generator was in a very sorry state. It had been constructed on strip board and was showing its age. The circuitry used was also very out-dated and contained 555 timers (one of my favourite devices), 741 Operational amplifiers and an TTL logic counters used to create the time period needed to produce the ramp. The profile of the ramp itself was hard coded with a UV erasable EEPROM, the output of which was passed to a DAC08 digital to analogue converter. I should state that I have no issue with this implementation as it had worked for many many years without issue. It was only recently found to be affected by external interference due to the test rig being moved from one part of the building to another. A photo of the original profile generator is below:
There was unfortunately not a great deal of documentation for the profile generator and it had been repaired on several occasions. The operational amplifier circuitry required positive and negative supplies which had been mis-connected a few times which destroyed the linear regulators and often took out the 555 timer and the op-amps as well.
For weeks I attempted to find out what was causing the issue with the test rig. The profile generator output was a negative voltage signal between 0 and -5 V dc. This signal was passed to the voltage control input of the HP 6681A which in turn controlled the output between 12 V dc and 24.5 V dc. Various probing of points within the system with an oscilloscope showed some spurious signals which no amount of filtering or cable screening could remove. A photo of an oscilloscope trace showing the spurious signal is below:
The Arduino R4 had a 10 bit DAC and an op-amp which I could use to buffer the signal if needed. It was helpfully a 5 V dc device as well which meant I could interface it with the HP Power supply without any extra circuitry or voltage manipulation required.
The first thing I did was write some code to create the voltage profile required. I had to convert the recorded 5 V dc CSV data to 1023 bit values to be able to produce the profile required but this was easily achieved with a spreadsheet formula. The microcontroller firmware worked like this:
1. Check if a trigger signal has been received.
2. If trigger is present output the voltage ramp over 18 seconds creating the ramp from hard coded bit values calculated from comma separated values recorded.
3. Light an LED to show that the profile generator is active to provide visual feedback to an operator.
4. Loop back to number 1.
I then tested the system and found it worked perfectly. I then re-read all of the test requirements and specifications to ensure I had missed something critically required. Luckily there didn't appear to be anything insurmountable and I proceeded to write the code:
Click here to view the Arduino Code
//Profile Generator Mk2
//Alex Lang
// constants won't change. They're used here to set pin numbers:
const int outputPin = A0; // DAC output pin on R4 (Analog pin A0)
const int dataSize = 51;
const unsigned long totalRampTime = 48000;
const int buttonPin = 3; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
int buttonState = 0; // variable for reading the pushbutton status
//Voltage data (scaled to 10 bits: 0-1023)
uint16_t voltageData[dataSize] = {
352,773,749,722,696,667,640,614,587,561,534,507,481,452,426,399,
372,346,319,293,293,293,293,293,293,293,293,293,293,293,293,293,
293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,293,352
};
void setup() {
analogWriteResolution(10); // Set analogWrite resolution to 10 bits
pinMode(ledPin, OUTPUT); // initialize the LED pin as an output
pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input
}
void loop() {
analogWrite(outputPin, 352); // Output 10-bit value directly: equates to -1.71 V dc
read_Trigger();
}
void read_Trigger(){
buttonState = digitalRead(buttonPin); // read the state of the pushbutton value
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
Profile_start();
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}
void Profile_start(){
unsigned long startTime = millis();
unsigned long currentTime = startTime;
unsigned long elapsedTime = 0;
unsigned long delayTime = totalRampTime / dataSize;
for (int i = 0; i < dataSize; i++) {
analogWrite(outputPin, voltageData[i]); // Output 10-bit value directly
elapsedTime = millis() - startTime;
while(elapsedTime < (i+1) * delayTime){
elapsedTime = millis() - startTime;
}
}
delay(100);
}
I ended up modifying the code somewhat as it transpired that two profiles were required for the testing with two separate triggers:
Click here to view the full Arduino Code
//Test code for analogue voltage output via pin A0 // Author: Alexander Lang // Date 14/05/2025 // Updated after changing PSU 1 as there appeared to be an issue. // Variables const int outputPin = A0; // DAC output pin on R4 (Analog pin A0). const int apuTrigger = 5; // Trigger input from APU signal const int pp3Trigger = 6; // Trigger input from PP3 Signal const int dataSize = 40; // Number of steps in APU Ramp. const int ledPin = 13; // Using built in LED to show when an APU trigger has been received. const unsigned long totalRampTime = 19000; // Time period for ramp in milli-seconds float originalVoltageData[dataSize] = { -2.75,-2.75,-2.7,-2.65,-2.60,-2.55,-2.50,-2.45,-2.40,-2.35, -2.30,-2.25,-2.20,-2.15,-2.10,-2.05,-2.00,-1.95,-1.90,-1.85, -1.80,-1.75,-1.70,-1.65,-1.60,-1.55,-1.50,-1.45,-1.40,-1.35, -1.30,-1.25,-1.20,-1.15,-1.10,-1.10,-1.10,-1.10,-1.10,-1.10, }; //Scaled 10-bit voltage data (0-1023) uint16_t scaledVoltageData[dataSize]; // Setup function to set pin states void setup() { Serial.begin(9600); // Set serial Monitor Running at 9600 baud //analogWriteResolution(12); // Set analogWrite resolution to 12 bits pinMode(apuTrigger, INPUT); // Configure pin as an input pinMode(pp3Trigger, INPUT); // Configure pin as an input pinMode(ledPin, OUTPUT); // Configure pin as an output analogWriteResolution(10); // Set analogWrite resolution to 10 bits //Scale the original voltage data to the 10-bit range (0-1023) float minValue = 0; // Find the minimum voltage float maxValue = -4.75; // Find the maximum voltage for (int i = 0; i < dataSize; i++) { //Use the map function to linearly scale the voltage to the 0-1023 range scaledVoltageData[i] = map(originalVoltageData[i] * 100, minValue * 100, maxValue * 100, 0, 1023); //We multiply by 100 to work with integers in the map function for better precision } } void loop() { analogWrite(outputPin, 336); //Set output 336 to default to -1.564 V to ensure a 20.5 Volt output at the agilent PSU - CR16514 delay(100); //Delay to ensure no issues readAPUTriggerState(); //Read the APU trigger state. If a trigger has been received output the profile. readPP3TriggerState(); //Read the APU trigger state. If a trigger has been received output the profile. } void readAPUTriggerState(){ byte apuTriggerState = digitalRead(apuTrigger); if (apuTriggerState == HIGH) { Serial.println("APU Trigger Received"); digitalWrite(ledPin, HIGH); APU_start(); } else { Serial.println("APU Trigger not received"); digitalWrite(ledPin, LOW); } delay(100); } void readPP3TriggerState(){ byte pp3TriggerState = digitalRead(pp3Trigger); if (pp3TriggerState == HIGH) { Serial.println("PP3 Trigger Received"); digitalWrite(ledPin, HIGH); PP3_start(); } else { Serial.println("PP3 Trigger not received"); digitalWrite(ledPin, LOW); } delay(100); } void PP3_start(){ unsigned long startTime = millis(); unsigned long elapsedTime = 0; unsigned long delayTime = totalRampTime / dataSize; for (int i = 0; i < dataSize; i++) { Serial.print("PP3 in operation"); Serial.println(); analogWrite(outputPin, 200); //Set profile generator to provide 0.93 V dc which equates to a 24.5 V dc output at the agilent PSU CR delay(300); elapsedTime = millis() - startTime; while (elapsedTime < (i + 1) * delayTime) { elapsedTime = millis() - startTime; } } delay(10); // Small delay at the end } void APU_start(){ unsigned long startTime = millis(); unsigned long elapsedTime = 0; unsigned long delayTime = totalRampTime / dataSize; for (int i = 0; i < dataSize; i++) { Serial.print(scaledVoltageData[i]); Serial.println(); analogWrite(outputPin, scaledVoltageData[i]); delay(300); elapsedTime = millis() - startTime; while (elapsedTime < (i + 1) * delayTime) { elapsedTime = millis() - startTime; } } delay(10); // Small delay at the end }
I then switched to designing an enclosure for the new profile generator. As time was of the essence and I didn't have access to machining services I couldn't use an off the shelf enclosure. I designed something bespoke which could be 3D printed. There are distinct benefits to doing this. Everything fits first time without needing any machining or post processing and all the internal components should fit perfectly.
I used Freecad to design the enclosure as I didn't have access to a commercial cad package although I could have used Solidworks if more time had been available. In previous projects I have created a parametric box design where I can set the required internal dimensions and a program then creates an enclosure and lid for me. All that is then left to do is to create some internal support for the arduino R4 development board and holes for the various 4 mm banana connectors and LEDS present.
The 3D printer was then pressed into service and a case was created in less than a day. Construction took less than 30 minutes and for once no further iterations were required...I will admit I often need more than one attempt at mechanical design...but that is the beauty of rapid prototyping, further iterations are cheap and easy to achieve assuming one has the time available.
The final result looks like this:
It has been in use ever since and I not heard of any issues or anything other than positive feedback from the production test department.
Because my profile generator used an off the shelf USB C power supply it was possible to remove 4x of the external lab power supplies from the test rig as these were being used to satisfy the positive and negative power requirements from the original profile generator. These power supplies are being used in other areas within the test department.
I have been informed that the HP power supplies used originally in the test rig are to be replaced as they are 'long in the tooth'. The new power supplies have been selected to work with the profile generator as it works exactly as intended - quite the endorsement!
That's all for now - Langster!





