Pages: [1]   Go Down
Author Topic: PWM for 3-phase Inverter  (Read 2210 times)
0 Members and 1 Guest are viewing this topic.
India
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Apologies in advance if this is answered elsewhere or posted in the wrong forum.
I would like to drive a 3-phase Inverter with a PWM in a variable duty cycle or fixed duty cycle also. I am using this Inverter for STATCOM (Static Synchronous Compensator) in my project.

I need the PWM output at a frequency of around 1.5 kHz.I would like to be able to change the duty cycle of the PWM across the entire range, from 0% to 100%.

I am using Arduino MEGA 256 for generating PWM. I am new in Programming field and using it.

If you could possibly help me with the code in Arduino MEGA 256, it will be a great help for me.

If I was unclear about something, please let me know and I will clarify.

Thanks..!!
Logged

South Texas
Offline Offline
Edison Member
*
Karma: 8
Posts: 1023
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Standard Arduino has a PWM fequency of ~500Hz. If you want another PWM frequency you will need to look at assembly language.

You would be doing yourself a favor if you took some time to learn more about Arduino by spending some time with the sample programs before going into a more involved project.
Logged

India
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@kf2q : Thank you for your kind reply...

I know i should take some time to learn more about Arduino by spending some more time but my project is somewhat tougher so did not have much time to get through the programming part. I have only 1 month left for the project so i was asking for help. I have also tried to write a code for PWM myself but i am getting error.

Thank you again smiley
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

You should be able to set up PWM at whatever frequency you like quite easily using the ATmega's 8-bit TIMER2. The code I'm posting has been used to generate a 38KHz carrier for IR remote control but I have adapted it for use generating much lower frequencies, e.g. your 1.5KHz. This code has been used on the ATmega328P (Arduino Duemilanove) but shouldn't require any modification - it should just work but I can't guarantee anything. I've had a quick look at the ATmega1280 datasheet and everything seems to be the same with regard to this, so hopefully it will work fine on your board - http://www.atmel.com/devices/ATMEGA1280.aspx?tab=documents

The key with using custom PWM frequencies is to work out the correct value for the TOP limit register and the prescaler. Basically, the clock frequency (16MHz) is divided by (TOP limit * prescaler) to give the frequency of the timer. So if you want a frequency of 1500 Hz you'll need

Code:
(limit * prescaler) = (16000000 / 1500)

Since the limit has a maximum value of 255 for TIMER2, you'll need a prescaler value that gives you a value for limit less than 256 and ideally as large as possible within that range to allow maximum precision of control. The possible values for the prescaler are given in the datasheet I linked to and the most appropriate for your case appears to be 64. If you use phase correct PWM, which you may need for your application, then the frequency is divided by 2 again (since fast PWM counts up only and phase correct PWM counts both up and down) - there's a good explanation of all this here: http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html

Any, top stop with the rambling, I think you should be using some code very much like the following:

Code:
int pwm_pin = 3;

void setup_pwm()
{
  // Set the pin mode to output and make it low when we're not sending PWM
  pinMode( pwm_pin, OUTPUT );
  digitalWrite( pwm_pin, LOW );

  // Disable all timer 2 interrupts
  TIMSK2 &= ~((1<<OCIE2A) | (1<<OCIE2B) | (1<<TOIE2));
  // Set prescale to 32
  TCCR2B &= ~(1<<CS22);
  TCCR2B |= ((1<<CS20) | (1<<CS21));
  // Set frequency
  OCR2A = 166; // = 16000000 / 1500 / 32 / 2
  // Set duty-cycle to zero initially
  OCR2B = 0;
  // Enable phase correct PWM, TOP at OCR2A (OCR2A determines frequency)
  TCCR2A &= ~(1<<WGM21);
  TCCR2A |= (1<<WGM20);
  TCCR2B |= (1<<WGM22);
  // Disable OC2A output (pin 11)
  TCCR2A &= ~((1<<COM2A0) | (1<<COM2A1));
  // Enable OC2B output (pin 3)
  TCCR2A &= ~(1<<COM2B0);
  TCCR2A |= (1<<COM2B1);
}

After you've done this, writing a value between 0 and 166 to OCR2B should give you between 0% and 100% duty-cycle respectively.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16548
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No one has addressed that he requires 3 phase PWM output. That is three separate PWM outputs all using the same duty cycle value but required to be phase shifted precisely by a specific amount of degrees. This in not an easy task and may not even be possible just using arduino software functions without external hardware assistance?

Lefty
« Last Edit: March 22, 2012, 11:13:57 am by retrolefty » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm, I completely missed the point that the OP was trying to do this for a 3-phase inverter.

I've been digging about myself with regard to solving that problem and I think there's an old post on the forums that addresses it: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1270367757/all. There's a pretty good discussion on there of doing it and a suggestion that I'm going to chase up on tomorrow to have a timer running at 3x the required frequency, catch the interrupt generated by the timer and use that ISR to set the output pins to the desired values for that phase. (This is all in a post by gbulmer about 1/3 of the way down)
Logged

Pages: [1]   Go Up
Jump to: