I found this great article on SPWM inverters where they used a (albeit faster) FPGA system to generate a SPWM signal to convert DC into AC. I wanted to do the same thing with an Arduino, and my code (which is based off of their approach) can be found here:
// Credit for procedures in code goes to the 2008 paper
// "Digital SPWM synthesis for the design of single phase inverters"
// By Lucien Ngalamou and Leary Myers
#define A1_PIN 5
#define A2_PIN 4
#define B1_PIN 3
#define B2_PIN 2
#define CLK_SPEED 16000000.0 //MAY NOT BE 16MHZ EXACT
#define FREQUENCY 500.0
#define PULSE_COUNT 512
#define OUTPUT_VOLTAGE_PERCENTAGE 100.0
long N = round(1/(2*FREQUENCY*PULSE_COUNT*(1/CLK_SPEED)));
long m = 0;
long D_m = 0;
long cnt = 0;
long sin_lookup[PULSE_COUNT];
void setup() {
pin_init();
generate_lookups();
}
void loop() {
noInterrupts();
if(cnt==N){
cnt=0;
m%=PULSE_COUNT;
m++;
D_m=sin_lookup[m];
}
if(D_m > 0){
digitalWrite(B1_PIN, LOW);
digitalWrite(B2_PIN, LOW);
digitalWrite(A1_PIN, HIGH);
digitalWrite(A2_PIN, HIGH);
D_m--;
}
else{
digitalWrite(A1_PIN, LOW);
digitalWrite(A2_PIN, LOW);
digitalWrite(B1_PIN, HIGH);
digitalWrite(B2_PIN, HIGH);
}
cnt++;
}
void generate_lookups(){
for(long i=0; i<PULSE_COUNT; i++){
sin_lookup[i]=round((OUTPUT_VOLTAGE_PERCENTAGE/100)*N*sin((i*PI)/PULSE_COUNT));
}
}
void pin_init(){
pinMode(A1_PIN, OUTPUT);
pinMode(A2_PIN, OUTPUT);
pinMode(B1_PIN, OUTPUT);
pinMode(B2_PIN, OUTPUT);
}
The A1, A2, B1, and B2 pins correspond to the sets of diagonals on an h bridge where I have connected a resistor and capacitor to an oscilloscope to measure the readings.
Its a nice sine wave, however the frequency is not 1:1 with what is in my code, and I suspect that this is because the code in my loop() function is not being executed in one clock cycle exactly.
How could I better optimize the section contained in loop() to run faster, other than getting a faster Arduino? (I'm currently using an Arduino mega with a 16MHz clock)