It's time to add the finishing touches to our op amp circuit with push-pull stage. Let's improve its efficiency.
In the last part of this project, we significantly increased the output power of our AC source by adding an external push-pull stage. While the solution already worked quite well, there is still room for improvements, especially regarding the efficiency of the circuit. Today, improving the efficiency is going to be our main objective.
Where do we start? Currently, a lot of power is wasted by the voltage divider, that we use to generate the artificial ground reference for the AC circuit. We still use two 220 Ω resistors for this and in consequence a current of 23 mA is constantly flowing right through both resistors, regardless of how small the load is. The only reason for such low resistor values was, that we directly powered the AC part of the circuit from this voltage divider, in an early part of this project. As we use an amplifier circuit now, we can safely replace these with 10 kΩ resistors, as shown below.
Is this all we can do? No, we can go even further and get rid of the whole 5 V artificial ground reference once and for all. In the last part of this project, we saw that a lot of power is wasted just to keep the artificial ground reference at 5 V. We can significantly increase the efficiency with a simple trick: we replace the fixed voltage with an inverted sine wave. This allows us to double both amplitude and efficiency.
The image below shows the basic concept. The load is connected in between the two amplifier outputs. Therefore, the resulting AC signal is defined by the voltage difference between the amplifier outputs. In our case the amplitude of the individual sine wave signals is 3.5 V. Because both signals are inverse to each other the voltage difference between both signals is 7 V.
Of course this new solution requires some changes to our circuit. As shown in the image below, one of the inputs to our amplifier circuit needs to be provided with the normal sine wave signal and the other one with the inverted sine wave signal.
How do we generate the inverted sine wave? Well, the straight forward solution is to duplicate our signal generation circuit. For the PWM DAC this is quite easy. We just replace the voltage divider with a second RC filter and use a second PWM output to generate the inverted sine wave. For the solution with the MCP4725 DAC module, you would need a second DAC module. For the sake of simplicity, however, I will focus on the PWM DAC solution here.
Here is how the adjusted circuit with the second signal generation circuit looks like:
Now, all that's left to do is adjusting the code to generate the inverted sine wave signal. I chose pin 10
as second PWM pin. This PWM output is driven by the same timer as pin 9
and for this reason our adjustments to increase the PWM frequency are effective for this pin as well. The only thing left to do is setting the output voltage for our second PWM DAC. Since our sine wave signal is symmetrical, this can be done by adding a single line of code:
analogWrite(10, 255-voltages[current_step]);
Here is how the complete program looks after applying this change:
#include <EEPROM.h>
// PWM frequency is 62.5 kHz so we can update every 16 us
const int usPerCommand = 100;
// Precalculated Voltage Buffer
const int BUFFER_SIZE = 256;
unsigned int voltages[BUFFER_SIZE];
unsigned int steps;
unsigned int usPerStep;
unsigned int current_step = 0;
unsigned long start_time;
// Setup frequency
void setup() {
// Read desired frequency
Serial.begin(9600);
Serial.print("Enter Frequency (Hz): ");
// Wait 10s for input otherwise take stored value
Serial.setTimeout(10000);
float frequency = Serial.parseFloat();
if(frequency == 0) EEPROM.get(0, frequency);
else EEPROM.put(0, frequency);
Serial.println(frequency);
// Calculate number of possible steps
int possible_steps = 1000000/usPerCommand/frequency;
// Steps need to be a multiple of 4 to keep the sine form
steps = (possible_steps / 4) * 4;
if(steps > BUFFER_SIZE) steps = BUFFER_SIZE;
if(steps < 4) steps = 4;
// Time per Step
usPerStep = 1000000 / (frequency * steps);
if(usPerStep < usPerCommand) usPerStep = usPerCommand;
// Precalculate Sine Values 0.75 V - 4.25 V (38.25 - 216.75)
for(int i = 0; i < steps; i++) {
voltages[i] = sin(i*3.14*2/steps) * 89.25 + 127.5;
}
Serial.print("Number of output steps: ");
Serial.println(steps);
Serial.print("Microseconds per step: ");
Serial.println(usPerStep);
Serial.print("Archieved Frequency (Hz): ");
Serial.println(1000000.0/float(steps)/float(usPerStep));
// Enable the fastest possible frequency for timer 1
TCCR1B = (1<<WGM12) | (1<<CS10);
// Initially set start time
start_time = micros();
}
// Output values
void loop() {
analogWrite(9, voltages[current_step]);
analogWrite(10, 255-voltages[current_step]);
current_step++;
if(current_step >= steps) current_step = 0;
while(micros()-start_time < usPerStep);
start_time += usPerStep;
}
Let's have a look at the result. The amplitude of our sine wave signal is now 7 V and the new RMS voltage is almost 5 V. But what about the maximum output power and efficiency?
To answer this question I updated the tool, from the last part of this project. As we are able to generate a sine wave with an amplitude twice as high in our previous solution, from the same 12 V, much less power is lost in our new circuit. The efficiency doubled. Due to the higher efficiency and thus lower voltage drop over the transistors, less energy is wasted and more importantly the transistors won't overheat that fast anymore. For this reason, we also significantly increased the maximum output power.
The new circuit is able to drive an 18 Ω load at and RMS voltage of roughly 5 V. If we just compare the resistance value it might seem odd, that we were able to drive 14 Ω with our previous circuit. We need to take the higher voltage into account as well. For a fixed load resistor, twice the output voltage equals to four times the output power. If the biggest possible load for our new circuit is 18 Ω, this means we were not quite able to increase output power by a factor of 4, however, we still increased it from 0.4 W to now almost 1.4 W. If you build the circuit yourself, please make sure to use a load resistor that is rated for the output power. Depending on the resistance value, a small 1/4 W resistor might overheat and catch fire, otherwise.
Are we done now? Yes and no. We reached a point where we have quite a powerful low voltage AC source and I won't improve this circuit a further. However, I want to show you an alternative amplifier solution that only works with the digital PWM DAC, but is also much simpler. So this is going to be the topic for the next part of this project series.