PWM for 3-phase Inverter

As an alternative to DDS this code shows a way to generate 3 phase sine PWM using a recursion equation rather than a lookup table. Because computation is slower than a lookup table it cannot go as high as 1KHz for the sine output. I have tested it to 500Hz and it can probably go a little higher.

// Generates three equally spaced phases of a PWM sine signal
//    on an Arduino Mega

#include <TimerOne.h>

#define phase0  11    // Timer1 sets pwm on 11, 12, and 13 on Mega (9 and 10 on Uno)
#define phase1  12
#define phase2  13
#define delayPin  10    // use this optional signal for info on compute time

const float pi = 3.14159 ;
float T = 150 ;    // sample time in microseconds
volatile float freq = 50 ;  // frequency of tone in hertz
float omega = 2*pi*freq ;
float A = 490 ;  // amplitude
float omegaT = omega*T/1000000.0 ;
// next line initializes oscillation with amplitude A
volatile float a[]={0.0, A*sin(omegaT),0.0}; 
float bb0 = A*sin(2.0*pi/3.0);
float bb1 = A*sin(omegaT + 2.0*pi/3.0);
float cc0 = A*sin(4.0*pi/3.0);
float cc1 = A*sin(omegaT + 4.0*pi/3.0);
volatile float b[]={bb0, bb1 ,0.0}; 
volatile float c[]={cc0, cc1 ,0.0};
// c1 is the difference equation coefficient
float c1 = (8.0 - 2.0*pow(omegaT,2))/(4.0+pow(omegaT,2));


void setup()                 
{
  Timer1.initialize(T);  // set sample time for discrete tone signal
  Timer1.pwm(phase0, 0,T);
  Timer1.pwm(phase1, 0,T);
  Timer1.pwm(phase2, 0,T);    
  Timer1.attachInterrupt(compute);
  pinMode(delayPin, OUTPUT);
}

void loop()                   
{ 
  delay(1000);
  changeFreq(10);
  delay(1000);
  changeFreq(50);
  delay(1000);
  changeFreq(200);
  
}

void compute()    // called by Timer Interrupt
{
  digitalWrite(delayPin, HIGH);
  
  a[2] = c1*a[1] - a[0] ;  // recursion equation
  a[0] = a[1] ;            // shift
  a[1] = a[2] ; 

  b[2] = c1*b[1] - b[0] ;  // recursion equation
  b[0] = b[1] ;
  b[1] = b[2] ; 
  
  c[2] = c1*c[1] - c[0] ;  // recursion equation
  c[0] = c[1] ;
  c[1] = c[2] ;  
     
  Timer1.setPwmDuty(phase0, int(a[2])+512);
  Timer1.setPwmDuty(phase1, int(b[2])+512);
  Timer1.setPwmDuty(phase2, int(c[2])+512);    
  digitalWrite(delayPin, LOW); 
}

void changeFreq(float _freq){  // changes frequency
  noInterrupts();
  freq = _freq;
  omega = 2*pi*freq ;
  omegaT = omega*T/1000000.0 ;
  a[0] = 0.0 ;
  a[1] = A*sin(omegaT);
  b[0] = A*sin(2.0*pi/3.0);
  b[1] = A*sin(omegaT + 2.0*pi/3.0);
  c[0] = A*sin(4.0*pi/3.0);
  c[1] = A*sin(omegaT + 4.0*pi/3.0);
  c1 = (8.0 - 2.0*pow(omegaT,2))/(4.0+pow(omegaT,2));    
  interrupts();
}