Using an Arduino Uno to drive single phase inverter w/ frequency synchronization

Hello Arduino forums,

Currently working on my final year engineering project. The goal is creating an inverter circuit with grid frequency matching capabilities using a Phase Locked Loop (PLL).

The inverter circuit is up and running, ran perfectly with a 20V DC source. During the debug phase I wrote a script which used digitalWrite and delayMicroseconds to output a PWM sine signal. The delays were measured in matlab from a single phase inverter sample.

I’m now attempting to implement the pll control. I am running into trouble getting PWM generation code going with a set 60 Hz frequency. The math compares a sine wave to a triangle wave with a very small step size ( 1E-5) due to the carrier signal being at 3000Hz. I did not think this would be an issue but running the code with my circuit, it takes a whole second for the arduino to finish outputting one cycle.

const float pi = 3.14159265359;
float f,c,nf;
int A,B;
for (float i=0; i<=1/60; i=i+0.00001) { 	//  @0.00001 - 1667 iterations

	f = sin(60*2*pi*i); 		//60 hz sine wave function
	nf = -1*sin(60*2*pi*i);
	c = 2.8/pi * asin( sin(pi*i*6000) ); //carrier triangle wave function with frequency 3000
	
	// switching logic
	if (f > c) { 
		A = 1;
	}
	else {
		A = 0;	
		}
	}
	If (nf >c ) {
		B = 1;
	}
Else {
	B=0;
}
If (A-B ==1){
DigitalWrite(5, HIGH);
}
If (A-B == -1){
	DigitalWrite(6,HIGH);
}
Else {
	DigitalWrite(5,LOW);
	DigitalWrite(6,LOW);
}
}

I did a bit of searching and saw that the digitalWrite function behaves slowly. I switched to port manipulation but it did not decrease signal output speed.

DDRD  =  B01100000; //SET PINS 6 and 5 to OUTPUT
//If  sine > carrier
PORTD &= B01000000;	//turn off pin 6
PORTD =  B00100000;	//turn on pin 5
//else 
PORTD &= B00100000; //turn off pin5
PORTD =  B01000000;	//turn on pin 6

I’m a bit stumped now, if I cant get just the pwm generation going then if I included the pll code which has to read the analog pins and do a lot more math it may slow down the output signals even more. Is the arduino powerful enough to do what I described above?

Could you put more words, why do you think it’s necessary?

The math compares a sine wave to a triangle wave with a very small step size ( 1E-5) due to the carrier signal being at 3000Hz.

It’s quite easy to generate 60Hz using DDS, and synchronization with grid also should not be difficult, you just need zero-cross detector for mains.

snakemanuver: I'm a bit stumped now, if I cant get just the pwm generation going then if I included the pll code which has to read the analog pins and do a lot more math it may slow down the output signals even more. Is the arduino powerful enough to do what I described above?

IF someone else stumbles upon this thread ...

It may be better to pre-calculate all of the PWM values one time during an INIT phase. And stuff the PWM values into an array. Then in a LOOP ... Let a Timer create the actual PWM signal. When the Timer Overflows then use the CPU to quickly load the next PWM Compare Value into the Timer.

The "Looping through Floating Point Math", shown in the original post, is just killing the CPU.