arduino control 3 phase inverter

Discussion in 'The Projects Forum' started by HaMZaBeST, Apr 26, 2014.

  1. HaMZaBeST

    Thread Starter New Member

    Dec 13, 2013
    3
    1
    i want to generate 3 PWM 120 degrees out of phase with arduino mega2560 because i want to control six pluse igbt to control 3 phase motor ( 220v/380v // f=50hz // rpm = 1430 ) and display the frequence in LCD .0

    [​IMG]

    i know i want using timer1/timer2

    i found this code but i have some problems with output frequence

    can you help me to fix the code for my arduino mega 2560 and thx.

    Code ( (Unknown Language)):
    1.  
    2. #include "avr/pgmspace.h"
    3. #include "avr/io.h"
    4.  
    5. // Look Up table of a single sine period divied up into 256 values. Refer to PWM to sine.xls on how the values was calculated
    6. PROGMEM  prog_uchar sine256[]  = {
    7.   127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
    8.   242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
    9.   221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,
    10.   76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,
    11.   33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124};
    12.  
    13.  
    14. #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
    15. #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
    16. int PWM_OUT_1 =11; // PWM output on pin 11
    17. int PWM_OUT_2 =10; // PWM output on pin 10
    18. int PWM_OUT_3 =12; // PWM output on pin 9
    19. int LED_PIN =13; // LED status on pin 13
    20. int TEST_PIN =7; // Scope trigger on pin 7
    21. int POTEN_IN =A0; // Potentiometer on pin 0
    22. int OFFSET_1 =85; // Offset for second-phase
    23. int OFFSET_2 =170; // Offset for third-phase
    24. double dfreq;
    25. const double refclk = 31376.6; // measured
    26. const uint64_t twoTo32 = pow(2, 32); // compute value at startup and use as constant
    27. // variables used inside interrupt service declared as voilatile
    28. volatile uint8_t icnt; // var inside interrupt
    29. volatile uint8_t icnt1; // var inside interrupt
    30. volatile uint8_t c4ms; // counter incremented every 4ms
    31. volatile uint32_t phase_accum; // pahse accumulator
    32. volatile uint32_t tword_m; // dds tuning word m
    33. //******************************************************************
    34. void setup()
    35. {
    36. pinMode(LED_PIN, OUTPUT); // sets the digital pin as output
    37. Serial.begin(115200); // connect to the serial port
    38. Serial.println("DDS Test");
    39.  
    40. pinMode(TEST_PIN, OUTPUT); // sets the digital pin as output
    41. pinMode(PWM_OUT_1, OUTPUT); // PWM output / frequency output
    42. pinMode(PWM_OUT_2, OUTPUT); // PWM output / frequency output
    43. pinMode(PWM_OUT_3, OUTPUT); // PWM output / frequency output
    44. // Setup the timers
    45. setup_timer1();
    46. setup_timer2();
    47. // disable interrupts to avoid timing distortion
    48. cbi (TIMSK0, TOIE0); // disable Timer0 !!! delay() is now not available
    49. sbi (TIMSK2, TOIE2); // enable Timer2 Interrupt
    50. dfreq = 1000.0; // initial output frequency = 1000.0 Hz
    51. tword_m = twoTo32 * dfreq / refclk; // calulate DDS new tuning word
    52. }
    53. //******************************************************************
    54. void loop()
    55. {
    56. if (c4ms > 250) // timer / wait for a full second
    57. {
    58. c4ms = 0;
    59. dfreq = analogRead(POTEN_IN); // read Poti on analog pin 0 to adjust output frequency from 0..1023 Hz
    60. cbi (TIMSK2, TOIE2); // disble Timer2 Interrupt
    61. tword_m = twoTo32 * dfreq / refclk; // calulate DDS new tuning word
    62. sbi (TIMSK2, TOIE2); // enable Timer2 Interrupt
    63. Serial.print(dfreq);
    64. Serial.print(" ");
    65. Serial.println(tword_m);
    66. }
    67. }
    68. //******************************************************************
    69. // timer1 setup
    70. // set prscaler to 1, PWM mode to phase correct PWM, 16000000/512 = 31.25kHz clock
    71. void setup_timer1(void)
    72. {
    73. // Timer1 Clock Prescaler to : 1
    74. sbi (TCCR1B, CS10);
    75. cbi (TCCR1B, CS11);
    76. cbi (TCCR1B, CS12);
    77. // Timer0 PWM Mode set to Phase Correct PWM
    78. cbi (TCCR1A, COM1A0); // clear Compare Match
    79. sbi (TCCR1A, COM1A1);
    80. cbi (TCCR1A, COM1B0); // clear Compare Match
    81. sbi (TCCR1A, COM1B1);
    82. sbi (TCCR1A, WGM10); // Mode 1 / Phase Correct PWM
    83. cbi (TCCR1A, WGM11);
    84. cbi (TCCR1B, WGM12);
    85. cbi (TCCR1B, WGM13);
    86. }
    87.  
    88. //******************************************************************
    89. // timer2 setup
    90. // set prscaler to 1, PWM mode to phase correct PWM, 16000000/512 = 31.25kHz clock
    91. void setup_timer2()
    92. {
    93. // Timer2 Clock Prescaler to : 1
    94. sbi (TCCR2B, CS20);
    95. cbi (TCCR2B, CS21);
    96. cbi (TCCR2B, CS22);
    97. // Timer2 PWM Mode set to Phase Correct PWM
    98. cbi (TCCR2A, COM2A0); // clear Compare Match
    99. sbi (TCCR2A, COM2A1);
    100. sbi (TCCR2A, WGM20); // Mode 1 / Phase Correct PWM
    101. cbi (TCCR2A, WGM21);
    102. cbi (TCCR2B, WGM22);
    103. }
    104. //******************************************************************
    105. // Timer2 Interrupt Service at 31.25kHz = 32us
    106. // this is the timebase REFCLOCK for the DDS generator
    107. // FOUT = (M (REFCLK)) / (2 exp 32)
    108. // runtime : 8 microseconds ( inclusive push and pop)
    109. ISR(TIMER2_OVF_vect)
    110. {
    111. sbi(PORTD, TEST_PIN); // Test / set PORTD,TEST_PIN high to observe timing with a oscope
    112. phase_accum += tword_m; // soft DDS, phase accu with 32 bits
    113. icnt = phase_accum >> 24; // use upper 8 bits for phase accu as frequency information
    114. OCR2A = pgm_read_byte_near(sine256 + icnt); // read value fron ROM sine table and send to PWM DAC
    115. OCR1A = pgm_read_byte_near(sine256 + (uint8_t)(icnt + OFFSET_1));
    116. OCR1B = pgm_read_byte_near(sine256 + (uint8_t)(icnt + OFFSET_2));
    117. if (icnt1++ == 125) // increment variable c4ms every 4 milliseconds
    118. {
    119. c4ms++;
    120. icnt1 = 0;
    121. }
    122. cbi(PORTD, TEST_PIN); // reset PORTD,TEST_PIN
    123. }
     
    jaydip likes this.
  2. GetDeviceInfo

    Senior Member

    Jun 7, 2009
    1,571
    230
    check the atmel site, they have code snippets for this very thing.
     
  3. HaMZaBeST

    Thread Starter New Member

    Dec 13, 2013
    3
    1
    i download the doc of atmega2560 i read but how can i fixe the value of frenquence in 0 to 50HZ ?
     
  4. HaMZaBeST

    Thread Starter New Member

    Dec 13, 2013
    3
    1
    can you give some help
     
  5. sirch2

    Well-Known Member

    Jan 21, 2013
    1,008
    351
    May be better to ask this on the Arduino Forum
     
Loading...