Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

SPWM using Arduino Mega2560

imranahmed

Advanced Member level 3
Joined
Dec 4, 2011
Messages
817
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,298
Location
Karachi,Pakistan
Activity points
6,492
Hi,
I wrote a code for SPWM with the help of internet and others projects. It is successfully output SPWM signals and Mosfets Inverter circuit also have output but I learn only thing is output filter LC type. How to design LC filter?
I am using Arduino Mega2560 and IR2112 driver.

Carrier Frequency 26kHz.
Output Frequency 50Hz.
Output Current 5A.

Any other stuff if you want I will provide about inverter.

I want to study LC Filter Design.

Code is attached below.
Code:
#define MAX_COUNT 308    // (16 MHz / SW_FREQ) / 2 = 16000000 / 26000 = 615 / 2 = 308
#define NO_OF_PULSES 260 // 26 kHz / 50 Hz = 520; 520 / 2 = 260 pulses in one half-cycle

const int lookUp[NO_OF_PULSES] = {
  0, 4, 7, 11, 15, 19, 22, 26, 30, 33, 37, 41, 45, 48,
  52, 56, 59, 63, 66, 70, 74, 77, 81, 84, 88, 92, 95,
  99, 102, 106, 109, 113, 116, 120, 123, 126, 130, 133,
  137, 140, 143, 146, 150, 153, 156, 159, 163, 166, 169,
  172, 175, 178, 181, 184, 187, 190, 193, 196, 199, 201,
  204, 207, 210, 212, 215, 218, 220, 223, 226, 228, 231,
  233, 235, 238, 240, 242, 245, 247, 249, 251, 253, 256,
  258, 260, 262, 264, 265, 267, 269, 271, 273, 274, 276,
  278, 279, 281, 282, 284, 285, 287, 288, 289, 291, 292,
  293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 302,
  303, 304, 304, 305, 305, 306, 306, 307, 307, 307, 307,
  308, 308, 308, 308, 308, 308, 308, 308, 308, 307, 307,
  307, 307, 306, 306, 305, 305, 304, 304, 303, 302, 302,
  301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 291,
  289, 288, 287, 285, 284, 282, 281, 279, 278, 276, 274,
  273, 271, 269, 267, 265, 264, 262, 260, 258, 256, 253,
  251, 249, 247, 245, 242, 240, 238, 235, 233, 231, 228,
  226, 223, 220, 218, 215, 212, 210, 207, 204, 201, 199,
  196, 193, 190, 187, 184, 181, 178, 175, 172, 169, 166,
  163, 159, 156, 153, 150, 146, 143, 140, 137, 133, 130,
  126, 123, 120, 116, 113, 109, 106, 102, 99, 95, 92, 88,
  84, 81, 77, 74, 70, 66, 63, 59, 56, 52, 48, 45, 41, 37,
  33, 30, 26, 22, 19, 15, 11, 7, 4
};

const int lookUp2[NO_OF_PULSES] = {
  1, 5, 8, 12, 16, 20, 23, 27, 31, 34, 38, 42, 46, 49, 53,
  57, 60, 64, 67, 71, 75, 78, 82, 85, 89, 93, 96, 100, 103,
  107, 110, 114, 117, 121, 124, 127, 131, 134, 138, 141, 144,
  147, 151, 154, 157, 160, 164, 167, 170, 173, 176, 179, 182,
  185, 188, 191, 194, 197, 200, 202, 205, 208, 211, 213, 216,
  219, 221, 224, 227, 229, 232, 234, 236, 239, 241, 243, 246,
  248, 250, 252, 254, 257, 259, 261, 263, 265, 266, 268, 270,
  272, 274, 275, 277, 279, 280, 282, 283, 285, 286, 288, 289,
  290, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302,
  303, 303, 304, 305, 305, 306, 306, 307, 307, 308, 308, 308,
  308, 309, 309, 309, 309, 309, 309, 309, 309, 309, 308, 308,
  308, 308, 307, 307, 306, 306, 305, 305, 304, 303, 303, 302,
  301, 300, 299, 298, 297, 296, 295, 294, 293, 292, 290, 289,
  288, 286, 285, 283, 282, 280, 279, 277, 275, 274, 272, 270,
  268, 266, 265, 263, 261, 259, 257, 254, 252, 250, 248, 246,
  243, 241, 239, 236, 234, 232, 229, 227, 224, 221, 219, 216,
  213, 211, 208, 205, 202, 200, 197, 194, 191, 188, 185, 182,
  179, 176, 173, 170, 167, 164, 160, 157, 154, 151, 147, 144,
  141, 138, 134, 131, 127, 124, 121, 117, 114, 110, 107, 103,
  100, 96, 93, 89, 85, 82, 78, 75, 71, 67, 64, 60, 57, 53, 49,
  46, 42, 38, 34, 31, 27, 23, 20, 16, 12, 8, 5
};

volatile bool positiveHalf = false;
volatile bool positiveHalf3 = false;

void setup()
{
  pinMode(2, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(50, OUTPUT);
  // Timer1 Registers initialisation, see datasheet for more detail.
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR3A = 0;
  TCCR3B = 0;
  TCCR1A = 0b10110000;       // Set OC1A (pin D9) on Compare Match; Disconnect OC1B (pin D10); PWM, Phase and Frequency Correct (Mode 8);
  TCCR1B = 0b00010001;       // PWM, Phase and Frequency Correct (Mode 8); Clock Select = System clock (No Prescaling) [Ref. Data Sheet, p. 132]
  ICR1 = MAX_COUNT;          // Period for 16MHz crystal, for a switching frequency of 16 kHz for 320 subdevisions per 50 Hz sin wave cycle.
  TCCR3A = 0b10110000;       // Set OC1A (pin D9) on Compare Match; Disconnect OC1B (pin D10); PWM, Phase and Frequency Correct (Mode 8);
  TCCR3B = 0b00010001;       // PWM, Phase and Frequency Correct (Mode 8); Clock Select = System clock (No Prescaling) [Ref. Data Sheet, p. 132]
  ICR3 = MAX_COUNT;          // Period for 16MHz crystal, for a switching frequency of 16 kHz for 320 subdevisions per 50 Hz sin wave cycle.
  OCR1A = lookUp[0];
  OCR1B = lookUp2[0];
  OCR3A = lookUp[0];
  OCR3B = lookUp2[0];
  TIMSK1 = 0b00000001;       // TOIE1 = 1: Overflow Interrupt Enable
  TIMSK3 = 0b00000001;    // TOIE3 = 1: Overflow Interrupt Enable
  sei();                     // Enable global interrupts.
}

void loop()
{
  // place any code you want
}

ISR(TIMER1_OVF_vect)
{
  static int i = 1;       // Static means it will NOT be reinitialized
  if (i >= NO_OF_PULSES) {
    i = 0;
  }

  if (positiveHalf == true) {
    OCR1A = lookUp[i];
    OCR1B = lookUp2[i];
  } else {
    OCR1A = 0;
    OCR1B = 0;
  }

  if (i == 1) {
    positiveHalf = !positiveHalf;
    OCR1A = 0;
    OCR1B = 0;
  }
  i++;

}

ISR(TIMER3_OVF_vect)
{
  static int j = 1;       // Static means it will NOT be reinitialized
  if (j >= NO_OF_PULSES) {
    j = 0;
  }
  if (positiveHalf3 == false) {
    OCR3A = lookUp[j];
    OCR3B = lookUp2[j];
  } else {
    OCR3A = 0;
    OCR3B = 0;
  }
  if (j == 1) {
    positiveHalf3 = !positiveHalf3;
    OCR3A = 0;
    OCR3B = 0;
  }
  j++;
}


1690686091346.png
 
Hi,

Filter in general:
* A filter hass a pass band: in your case the important frequency is 50Hz with and an unavoidable signal attenuation.
* and a filter has a stop band: in your case the 26kHz with a finite attenuation at this frequency.

Now you may go a mathematical way and choose the filter frequency to be in the "middle" of both frequencies:
fc = sqrt(50Hz x 26kHz).
But you may optimize your filter on
* low cost
* better 26 Hz attenuation
* size
* filter current
.. or whatever you want.

There are rules of thumb using 3x the one frequency or 1/3 of the other... In the end you have to decide what to chose.

Besides the frequency dependent characteristic of a filter you also should take care about ohmic loss (generated heat).
It is dominated by the ohmic resitance of the coil.

Klaus
 
output filter LC type. How to design LC filter?

I guess you mean LC in a 2nd-order low-pass arrangement?

Both components contribute to filtering action and power factor correction.
The inductor value should be selected so it provides approximately the waveform you desire while leaving a few jaggies. Small Henry value has little effect.
Too large Henry value reduces amplitude unnecessarily.

The capacitor also does the task of removing jaggies. It should carry about the same Ampere level as the load.

L & C should be carefully adjusted so that the Ampere waveform is in sync with the Voltage waveform (through the switching component). The goal is so that both waveforms turn off at the same time.
This is usually related to L:C ratio.
 

LaTeX Commands Quick-Menu:

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top