• Skip to main content
  • Skip to primary sidebar

Homemade Circuit Projects

Need circuit help? Post them in the comments! I've answered over 50,000!

Blog | Categories | About | Contact | Calculators-online
You are here: Home / Sine Table Calculator for SPWM Arduino Code

Sine Table Calculator for SPWM Arduino Code

This sine table calculator lets you choose how many SPWM steps (pillars) you want, and then gives you the correct sineTable[] values (0 to 255 range) to paste directly into Arduino code.

The above image shows one half cycle example of an SPWM waveform, which is a PWM equivalent of a pure sine waveform.

In the above image we see 7 pillars or varying PWM pulses being generated per half wave SPWM cycle. 7 pulses may look good if an iron core transformer is used but the resultant sine waveform might not be pure enough.

Ideally, you must use at least 20 to 30 PWM pulses or pillars on each of these half cycle waveforms, meaning, the higher the number of these pulses, the purer the sine wave will be, and closer it will be to an actual sine waveform.

Features of the Calculator:

  • Simple dropdown to select number of SPWM steps
  • Calculates values using formula:
    PWM = 127.5 + 127.5 × sin(angle)
  • Displays the array in Arduino-friendly format
Calculator by homemade-circuits.com

What It Does:

When a user selects a value like 11, 21, or 31, it will instantly give you the corresponding duty cycle outputs:

int sineTable[21] = {128, 159, 185, 208, …, 128};

You can copy-paste it directly into your Arduino sketch.

Example:

Consider the following Arduino Code of an SPWM generator:

int freq = 50;  // Can change to 60
int steps = 21;

int sineTable[21] = {
128, 147, 167, 185, 202, 218, 231, 241, 249, 253, 255, 253, 249, 241, 231, 218, 202, 185, 167, 147, 128};
};

int pwmPinA = 8;
int pwmPinB = 9;

void setup() {
  pinMode(pwmPinA, OUTPUT);
  pinMode(pwmPinB, OUTPUT);
}

void loop() {
  int microDelay = (1000000 / freq) / (2 * steps); // delay per step

  for (int i = 0; i < steps; i++) {
    analogWrite(pwmPinA, sineTable[i]);
    analogWrite(pwmPinB, 0);
    delayMicroseconds(50);     // Dead time
    delayMicroseconds(microDelay);
  }

  for (int i = 0; i < steps; i++) {
    analogWrite(pwmPinA, 0);
    analogWrite(pwmPinB, sineTable[i]);
    delayMicroseconds(50);     // Dead time
    delayMicroseconds(microDelay);
  }
}
Arduino SPWM code for sine wave invertersDownload

The code is designed to generate 21 pillars or 21 steps, or 21 pulses on each SPWM half cycles. You can easily change the following two values in code in order to change the number of these pulses or pillars, simply by tweaking the following two lines in the code:

int steps = 21;
int sineTable[21] = {

But that does not complete the procedures because then you will also need to change the following corresponding values which represent the PWM duty cycle levels that shape the sine wave.

128, 159, 185, 208, 230, 243, 250, 255, 250, 243,
230, 208, 185, 159, 128

If you don't do this, then your code will not work and not compile.

So that is when you can use the above Sine Table Calculator to calculate these corresponding PWM duty cycle levels, so that your Arduino is able to generate the required SPWM code correctly and validly.

Improving the Code Even Further with Timer1 and Interrupt for SPWM

improved Arduino SPWM codeDownload
// ==== CONFIGURATION ====

// Frequency of sine wave output (can change to 60)
const int freq = 50;

// Number of steps in half sine wave
const int steps = 21;

// Dead time in microseconds
const int deadTime = 50;

// Output pins for SPWM (must be PWM capable)
const int pwmPinA = 9;   // OC1A on Arduino Uno
const int pwmPinB = 10;  // OC1B

// Lookup table for one half sine wave (0 to 255)
const byte sineTable[steps] = {
  128, 147, 167, 185, 202, 218, 231, 241, 249, 253,
  255, 253, 249, 241, 231, 218, 202, 185, 167, 147, 128
};

// Variables for ISR control
volatile int index = 0;
volatile bool halfCycle = false; // false = A active, true = B active

void setup() {
  pinMode(pwmPinA, OUTPUT);
  pinMode(pwmPinB, OUTPUT);

  // Disable PWM on Timer1 temporarily
  TCCR1A = 0;
  TCCR1B = 0;

  // Set Timer1 compare interrupt for step timing
  // Total microseconds per step = 1 / (2 * freq * steps)
  unsigned long stepTimeMicros = 1000000UL / (2UL * freq * steps);

  // Convert to timer ticks (16 MHz / 8 prescaler = 2 MHz = 0.5 us per tick)
  unsigned int ocr1a = stepTimeMicros * 2;

  // Set Timer1 compare match value
  OCR1A = ocr1a;

  // Set Timer1 mode to CTC (Clear Timer on Compare Match)
  TCCR1B |= (1 << WGM12);

  // Set prescaler to 8
  TCCR1B |= (1 << CS11);

  // Enable compare match interrupt
  TIMSK1 |= (1 << OCIE1A);
}

void loop() {
  // Main loop does nothing, all work is done by ISR
}

// ==== INTERRUPT SERVICE ROUTINE ====
// Runs every stepTimeMicros microseconds

ISR(TIMER1_COMPA_vect) {
  // First add dead time
  analogWrite(pwmPinA, 0);
  analogWrite(pwmPinB, 0);
  delayMicroseconds(deadTime);  // may cause slight jitter but works

  // Now output PWM value based on current half-cycle
  if (!halfCycle) {
    // A active
    analogWrite(pwmPinA, sineTable[index]);
    analogWrite(pwmPinB, 0);
  } else {
    // B active
    analogWrite(pwmPinA, 0);
    analogWrite(pwmPinB, sineTable[index]);
  }

  index++;

  // If we finish one half-cycle
  if (index >= steps) {
    index = 0;
    halfCycle = !halfCycle; // switch side
  }
}
improved Arduino SPWM codeDownload

How the Code Works

So first, in the configuration part:

We fix the sine wave frequency we want like 50 Hz, then how many steps we want to divide each half cycle into, like 21, so full cycle will have 42 steps. Then we put a small dead time like 50 microseconds to stop shoot-through.

We define the output pins A and B. We use PWM pins 9 and 10 on Uno which are OC1A and OC1B so compatible with Timer1. Then we define a lookup table for sine wave values scaled between 128 to 255 in 21 steps. This gives us a clean half sine shape.

In setup():

We first set the PWM pins as OUTPUT. Then we turn off Timer1’s PWM functions for now. Then we calculate how many microseconds each step should last.

For example for 50 Hz and 21 steps, each half cycle must be done in 10,000 microseconds (20 ms / 2), so 10,000 / 21 = around 476 microseconds per step.

Then we convert that into Timer1 tick counts. Since we will use prescaler 8 that gives us 2 million ticks per second or 0.5 µs per tick. So we multiply our microseconds by 2 to get ticks.

Then we load that value into OCR1A register of Timer1 and set it to CTC mode (Clear on Compare Match) so that interrupt will happen every step.

Finally we enable interrupt on compare match A.

In loop():

We do nothing here all work is done by the interrupt.

In ISR:

So when interrupt triggers, first we add the dead time by setting both PWM pins LOW and delay for dead time (just small 50 µs).

Then we check which half cycle we are in, if halfCycle is false then we are on A side, so we give PWM to pin A, pin B remains OFF. If halfCycle is true then we reverse, pin B gets PWM, pin A is OFF.

After writing the PWM, we increase the index for the sine step. Once we reach end of steps then we reset index to 0 and toggle halfCycle.

This keeps repeating forever, generating perfect alternate sine PWM on both pins.

Final Thoughts

So now this version is much better than previous code because:

  • No blocking delays so other code can run parallel.
  • Very precise sine wave step timing using Timer1.
  • Dead time added manually.
  • Easily expandable for more steps or frequency.
  • Good for SPWM in inverters, UPS, motor control.

Reader Interactions

Need Help? Please Leave a Comment! We value your input—Kindly keep it relevant to the above topic! Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

circuit simulator image



Subscribe to get New Circuits in your Email



Categories

  • Arduino Projects (93)
  • Audio and Amplifier Projects (133)
  • Automation Projects (17)
  • Automobile Electronics (101)
  • Battery Charger Circuits (85)
  • Datasheets and Components (109)
  • Electronics Theory (149)
  • Energy from Magnets (27)
  • Games and Sports Projects (11)
  • Grid and 3-Phase (20)
  • Health related Projects (27)
  • Home Electrical Circuits (13)
  • Indicator Circuits (16)
  • Inverter Circuits (95)
  • Lamps and Lights (159)
  • Meters and Testers (71)
  • Mini Projects (28)
  • Motor Controller (68)
  • Oscillator Circuits (28)
  • Pets and Pests (15)
  • Power Supply Circuits (91)
  • Remote Control Circuits (50)
  • Renewable Energy (12)
  • Security and Alarm (64)
  • Sensors and Detectors (106)
  • SMPS and Converters (34)
  • Solar Controller Circuits (60)
  • Temperature Controllers (43)
  • Timer and Delay Relay (49)
  • Voltage Control and Protection (42)
  • Water Controller (36)
  • Wireless Circuits (30)





Other Links

  • Privacy Policy
  • Cookie Policy
  • Disclaimer
  • Copyright
  • Videos
  • Sitemap



People also Search

555 Circuits | 741 Circuits | LM324 Circuits | LM338 Circuits | 4017 Circuits | Ultrasonic Projects | SMPS Projects | Christmas Projects | MOSFETs | Radio Circuits | Laser Circuits | PIR Projects |

Social Profiles

  • Twitter
  • YouTube
  • Instagram
  • Pinterest
  • My Facebook-Page
  • Stack Exchange
  • Linkedin



Recent Comments

  • Swagatam on Arduino 2-Step Programmable Timer Circuit
  • Swagatam on Simple Buck-Boost Converter Circuits Explained
  • Swagatam on IC IR2111 H-Bridge MOSFET, IGBT Driver IC: Full Datasheet, Circuit Diagram
  • Swagatam on Electronic Circuit Projects, Tutorials, and Practical Engineering Solutions
  • Kadir on Simple 3 Phase Inverter Circuit

© 2026 · Swagatam Innovations