Arduino Control Pure sine wave inverter [LEP]

ในตอนสุดท้าย เป็นการควบคุมแรงดันเอาต์พุตคงที่ด้วยการใช้หม้อแปลงขนาดแรงดัน 220Vac : 6Vac (หม้อแปลงขนาดเล็ก) เป็นตัวป้อนกลับสัญญาณเข้าที่ขา A1 ของตัวบอร์ด Arduino UNO เพื่อประมวล ผลและได้ค่าแรงดันกระแสสลับที่เอาต์พุตของอินเวอร์เตอร์ตามที่ตั้งค่าไว้ และสำหรับการเขียนโปรแกรมไมโครคอนโทรลเลอร์ควบคุมในตัว Arduino UNO จะเพิ่มคำสั่งเล็กน้อยและเข้าใจง่าย โดยการทดลองครั้งนี้จะมีด้วยกัน 2 แบบคือ ทดลองการควบคุมแบบเปิด (Open loop control) และการควบคุมแบบปิด (Close loop control) ทั้งนี้เพื่อให้เห็นความแตกต่างของผลที่เกิดขึ้นจากการทดลองครั้งนี้

Arduino Control Pure sine wave inverter
รูปที่ 1 การต่ออุปกรณ์ต่างๆ ของวงจรอินเวอร์เตอร์ที่สำคัญ

ในรูปที่ 1 เป็นลักษระของการต่ออุปกรณ์ต่างๆ ที่ใช้ในการทดลองทั่วไป ซึ่งเป็นวงจรต้นแบบโดยในส่วนต่างๆ จะเชื่อมต่อด้วยกันผ่านสายแพรและสายไฟปกติ ทั้งนี้เพื่อให้ง่ายสำหรับการปรับแต่งหรือแก้ไขในระหว่างการทดลอง

Arduino Control Pure sine wave inverter
รูปที่ 2 ลักษณะของหม้อแปลงสำหรับใช้ในการส่งสัญญาณป้อนกลับ

รูปที่ 2 เป็นหม้อแปลงความถี่ต่ำ 220Vac : 6Vac สำหรับส่งสัญญาณป้อนกลับให้กับบอร์ดประมวลผล Arduino UNO โดยในด้านเอาต์พุต (6V) จะใช้วงจรเร็กติไฟร์และฟิลเตอร์ (Rectifier and filter circuit) เพื่อเปลี่ยนไฟฟ้ากระแสสลับให้เป็นกระแสตรง โดยแรงดันส่วนนี้จะเป็นสัดส่วนกับแรงดันทางด้านอินพุต (220V) และเราสามารถปรับค่าแรงดันที่ต้องการตั้งค่าได้อีกส่วนหนึ่งด้วยตัวต้านทานปรับค่า

Arduino Control Pure sine wave inverter
รูปที่ 3 แสดงตัวต้านทานปรับค่าสำหรับกำหนดและปรับค่าแรงดันเอาต์พุตที่ต้องการ

รูปที่ 3 แสดงตัวต้านทานปรับค่าทั้ง 2 ตัว ซึ่งในแต่ละตัวจะทำหน้าที่ปรับค่าความถี่ทางด้านเอาต์พุตได้ (Adjsible frequency) และอีกตัวหนึ่งจะให้เราปรับค่าแรงดันที่เอาต์พุตได้เช่นกัน (Adjsible VAC output) ทั้งนี้เราจะต้องเขียนโปรแกรมให้กับตัวควบคุมสามารถรับค่าเหล่านี้ได้เช่นกัน

*** CodeProgram Arduino UNO [*Reference [1]]

 // 3 phase PWM sine INVERTER
 // (c) 2016 C. Masenas
 // Modified from original DDS from: 
 // KHM 2009 /  Martin Nawrath
 // https://3phaseinverter.blogspot.com/
 // https://github.com/cmasenas/3-Phase-Sine-Arduino/blob/Release/DDS_Generator.ino
 // table of 256 sine values / one sine period / stored in flash memory
 PROGMEM const unsigned char sine256[]  = {
   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,236,
   236,238,238,238,239,239,240,241,242,243,245,247,247,248,249,249,250,
 251,251,252,252,252,252,252,
 250,250,249,249,248,248,247,247,246,246,245,245,243,240,240,238,238,
   236,236,234,233,231,229,227,225,223,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,
   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,
   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
 };
 define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
 define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
 int testPin = 7;
 int enablePin = 8 ;
 int sensorPin = A0; 
 int sensorValue = 0;
 int ValueFB = 0;
 float k = 0;
 int Adj_Frq=25; 
 volatile  float freq=1;
 const float refclk=122.549  ;   // 16 MHz/510/256
 // variables used inside interrupt service declared as voilatile
 volatile unsigned long sigma;   // phase accumulator
 volatile unsigned long delta;   // phase increment
 byte phase0, phase1, phase2 ;

 void setup()
 {
Serial.begin(9600);        // Connect to the serial port
Serial.println("DDS Test"); 
 pinMode(enablePin,OUTPUT);    // sets the digital pin as output
 pinMode(testPin,OUTPUT);      // sets the digital pin as output
 pinMode(5,OUTPUT);
 pinMode(6,OUTPUT); 
 pinMode(9,OUTPUT);
 pinMode(10,OUTPUT);
 pinMode(11,OUTPUT);
 pinMode(3,OUTPUT); 
 Setup_timer2();
 Setup_timer1();
 Setup_timer0(); 
 digitalWrite(enablePin, HIGH);
 // the waveform index is the highest 8 bits of sigma
 // choose refclk as freq to increment the lsb of the 8 highest bits
 // for every call to the ISR of timer2 overflow
 // the lsb of the 8 highest bits is 1<<24 (1LL<<24 for long integer literal)
   delta = (1LL<<24)*freq/refclk ;  
 }

void loop(){
 
ValueFB = analogRead(A1);  // Voltage FB 
if(ValueFB>500 && k>0.1)  k-=0.01; 
if(ValueFB<500 && k<0.99) k+=0.01;  
    
delayMicroseconds(50); 

sensorValue = analogRead(A0);  // Adj_Frq   
Adj_Frq = (sensorValue/9); 
 if (Adj_Frq <25) {
        Adj_Frq = 25;
      }                
      changeFreq(Adj_Frq);   
 }
 void changeFreq(float _freq){
   cbi (TIMSK2,TOIE2);              // disable timer2 overflow detect  
   freq = _freq;
   delta=(1LL<<24)*freq/refclk;     // update phase increment    
   sbi (TIMSK2,TOIE2);              // enable timer2 overflow detect
 } 
 //**
 // timer2 setup
 // set prscaler to 1, fast PWM
 void Setup_timer2() {
 // Timer2 Clock Prescaler to : 1
   sbi (TCCR2B, CS20);  // set
   cbi (TCCR2B, CS21);  // clear
   cbi (TCCR2B, CS22);
 // Timer2 PWM Mode 
   cbi (TCCR2A, COM2A0);  // clear OC2A on Compare Match, PWM pin 11
   sbi (TCCR2A, COM2A1);
 //   set 2-8-60 ----------------------  
   sbi (TCCR2A, COM2B0);  // clear OC2A on Compare Match, PWM pin 3
   sbi (TCCR2A, COM2B1);
 //   set 2-8-60 ----------------------  
 // set to fast PWM
   sbi (TCCR2A, WGM20);   // Mode 1, phase correct PWM
   cbi (TCCR2A, WGM21);
   cbi (TCCR2B, WGM22);
   sbi (TIMSK2,TOIE2);    // enable overflow detect
 }
 // timer1 setup  (sets pins 9 and 10)
 // set prscaler to 1, PWM mode to phase correct PWM, 16000000/510 = 31372.55 Hz clock
 void Setup_timer1() {
 // Timer1 Clock Prescaler to : 1
 sbi (TCCR1B, CS10);
 cbi (TCCR1B, CS11);
 cbi (TCCR1B, CS12);
 // Timer1 PWM Mode set to Phase Correct PWM
 cbi (TCCR1A, COM1A0);  // clear OC1A on Compare Match, PWM pin 9
 sbi (TCCR1A, COM1A1);  
 sbi (TCCR1A, COM1B0);  // clear OC1B on Compare Match, PWM pin 10
 sbi (TCCR1A, COM1B1);
 sbi (TCCR1A, WGM10);   // Mode 1  / phase correct PWM
 cbi (TCCR1A, WGM11);
 cbi (TCCR1B, WGM12);
 cbi (TCCR1B, WGM13);
 }
 void Setup_timer0() {    
 sbi (TCCR0B, CS00);
 cbi (TCCR0B, CS01);
 cbi (TCCR0B, CS02);  
 // Timer0 PWM Mode set to Phase Correct PWM
 cbi (TCCR0A, COM0A0);  // clear OC0A on Compare Match, PWM pin 
 sbi (TCCR0A, COM0A1);     
 sbi (TCCR0A, COM0B0);  // clear OC0B on Compare Match, PWM pin 
 sbi (TCCR0A, COM0B1);
 sbi (TCCR0A, WGM00);   // Mode 1  / phase correct PWM
 cbi (TCCR0A, WGM01);
 cbi (TCCR0B, WGM02);  
 }
 //**
 // Timer2 Interrupt Service at 31372,550 KHz = 32uSec
 // this is the timebase REFCLOCK for the DDS generator
 // runtime : 8 microseconds ( inclusive push and pop)
 // OC2A - pin 11
 // OC1B - pin 10
 // OC1A - pin 9
 // https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM
 ISR(TIMER2_OVF_vect) {    
 sigma=sigma+delta;      // soft DDS, phase accu with 32 bits
 phase0=sigma >> 24;     // use upper 8 bits for phase accu as frequency information
                           // read value fron ROM sine table and send to PWM DAC
 phase1 = phase0 +55 ;   // 65
 phase2 = phase0 +180 ;  // 200   
 OCR1A = pgm_read_byte_near(sine256 + phase1)*k;  // pwm pin 9 (+B)
 OCR1B = OCR1A+3; // pwm pin 10   
 OCR0A = pgm_read_byte_near(sine256 + phase2)*k;  // pwm pin 6 (+B)
 OCR0B = OCR0A+3; // pwm pin 5             
 }
Arduino Control Pure sine wave inverter
รูปที่ 4 ลักษณะของการใช้เครื่องมือและอุปกรณ์ในการทดลอง

รูปที่ 4 เป็นลักษณะของการทดลอง ซึ่งในการทดลองนี้จะใช้มอเตอร์เป็นโหลดในการทดสอบวงจรอินเวอร์เตอร์ โดยตัวมอเตอร์จะมีขนาด 220V/0.53A เพื่อให้เห็นการตอบสนองการทำงานต่อโหลดที่นำมาต่อในเบื้องต้น

Arduino Control Pure sine wave inverter
รูปที่ 5 การทดลองปรับค่าต่างๆ ในการทดลอง

รูปที่ 5 เป็นลักษณะของการทดลองปรับค่าต่างๆ เพื่อสังเกตการทำงานของวงจรที่ออกแบบ และลักษณะของการประมวลผลของโปรแกรมที่สามารถทำงานได้ตามแนวความคิดที่กำหนด รวมทั้งผลที่เกิดขึ้นในด้านอื่นเพื่อเป็นประสบการณ์และหาทางแก้ไขอีกต่อไป

Arduino Control Pure sine wave inverter
รูปที่ 6 แสดงวงจรที่ใช้ในการทดลองอินเวอร์เตอร์

รูปที่ 6 เป็นวงจรที่ใช้ในการทดลองโครงงานนี้ โดยในส่วนด้านล่างของรูปกรอบสีน้ำเงิน จะเป็นวงจรป้อนกลับสัญญาณทางด้านเอาต์พุต (Feedback Signal) มายังตัวควบคุม โดยวิธีการนี้เป็นการใช้งวจรที่เข้าใจง่ายและไม่ยากมากนัก

Datasheet for IPM Power IGBT BM64364S-VA

สำหรับโครงงานการควบคุมอินเวอร์เตอร์ 1 เฟส ด้วยบอร์ด Arduino UNO นี้ ยังคงเป็นต้นแบบเล็กๆ ที่จะช่วยให้ท่านได้เห็นลักษณะการทำงานและการทดลองอีกแบบหนึ่ง ซึ่งท่านสามารถนำไปเป็นแนวทางสำหรับพัฒนาวงจรที่ต้องการและเหมาะสมต่อไปนะครับ.

Reference

  1. https://github.com/cmasenas/3-Phase-Sine-Arduino/blob/Release/DDS_Generator.ino
  2. 3-Phase-Sine-Arduino/DDS_Generator.ino at Release · cmasenas/3-Phase-Sine-Arduino · GitHub
  3. http://www.eprojectszone.com/how-to-generate-a-sine-wave-from-arduino-or-atmega-328/
  4. https://www.youtube.com/watch?v=mmwsh00No2c
  5. https://drive.google.com/file/d/1C91GSlEiPzmXDcwhuriaN-Rf8SkgqWoG/view?usp=sharing
  6. https://theorycircuit.com/arduino-inverter-circuit/
  7. https://www.electroschematics.com/sine-wave-generator-circuit/