วันจันทร์ที่ 10 กรกฎาคม พ.ศ. 2560

Arduino Motor Controller

เผยแพร่เมื่อ 2 ต.ค. 2016
http://www.avrfreaks.net/forum/3-phas...
Arduino uno 3phase frequency driver controller for 3 phase induction motor CODE BY Tomasz Drazek Poland THANK YOU VERY MUCH SIR https://onedrive.live.com/?authkey=%2...

แนวทางการสร้าง อินเวอร์เตอร์ คอนเวอร์เตอร์
สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์
สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์
ติดตามแล้ว910
 เพิ่มลงใน   แชร์  เพิ่มเติม
ดู 284 ครั้ง
 3  0
เผยแพร่เมื่อ 30 ต.ค. 2016
Arduino 3 Phase Sine Wave GeneratorA variable-frequency drive (VFD) is a type of adjustable-speed drive used in electro-mechanical ... The AC electric motor used in a VFD system is usually three-phase induction motor. ..... lead lengths include minimizing cable distance, lowering carrier frequency, installing dV/dt filters, using inverter-duty-rated motors
หมวดหมู่
วิทยาศาสตร์และเทคโนโลยี
สัญญาอนุญาต
สัญญาอนุญาตมาตรฐานของ YouTube

arduino 3 phase inverter สร้างอินเวอร์เตอร์จากบอร์ด Arduino
สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์
สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์
การตั้งค่าช่อง
เพิ่มลงใน   แชร์  เพิ่มเติม
ดู 81 ครั้ง
 1  0
เผยแพร่เมื่อ 4 เม.ย. 2017

โปรแกรม และ Code ดูจากคลิปก่อนหน้านี้นะครับ บอร์ด รุ่น ARDUINO UNO 328 ที่ต่อวงจรและโปรแกรมแล้ว ราคา 700 บาท
บอร์ด รุ่น ARDUINO MEGA 2560 ที่ต่อวงจรและโปรแกรมแล้ว ราคา 1000 บาท ขอบพระคุณทุกท่าน ที่อุดหนุน สินค้า และติดตามผลงาน ติดต่อได้ที่ Email mrsompongt@hotmail.com



0:40 / 8:38
การใช้ Arduino 2560 แทน MC3PHAC
Sompong Tungmepol
Sompong Tungmepol
ติดตามแล้ว37K
 เพิ่มลงใน   แชร์  เพิ่มเติม
ดู 575 ครั้ง
 11  0
เผยแพร่เมื่อ 7 ก.ย. 2016
https://onedrive.live.com/?authkey=%2...
การใช้ Arduino 2560 และ ARDUINO 328 แทน MC3PHAC เนื่องจาก MC3PHAC เลิกผลิต จึงทำตัวใหม่ มาจำหน่าย แทนครับ ราคาลง โปรแกรมและทดสอบแล้ว มีวงจรและค่าของอุปกรณ์ประกอบ จะมีราคา ไม่เกิน 800 บาท ครับ ส่วนการจำหน่าย ทรานซิสเตอร์ ไอจีบีที สำหรับ สร้าง ซ่อม เครื่องปรับรอบมอเตอร์ไฟฟ้ากระแสสลับสามเฟส ขนาด 200 วัตต์ ถึง1 แรงม้า ยังมีสินค้าอีก หลายพันชิ้นครับ เช่น PS21963 PS219A2 6DI15S-050 MP6501A ราคา 300 บาท เท่ากัน ทุกเบอร์ครับ หากต้องการขับมอเตอร์ เกินหนึ่งแรงม้า ใช้ วิธี ขนาน กันได้ครับ ขอบคุณทุกท่านมากครับที่กรุณาอุดหนุน สินค้า และติดตามผลงาน ช่วงนี้ ขอเวลา ออกแบบ และทดลอง ต้นแบบ คำนวนราคา งบ ประมาณ ค่าใช้จ่าย จะให้ การใช้งาน และราคา ใกล้เคียง MC3PHAC ครับ คิดว่า อาจจะถูกกว่า MC3PHAC ครับ...
02-951-1356 Line pornpimon 1411
Email sompongindustrial@gmail.comรายละเอียด ราคา ตามที่แจ้งในคลิป
หมวดหมู่
การศึกษา
สัญญาอนุญาต
สัญญาอนุญาตมาตรฐานของ YouTube
แสดงน้อยลง
ความคิดเห็น • 5
สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์
เพิ่มความคิดเห็นสาธารณะ...
ความคิดเห็นยอดนิยม
 สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์
สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์3 เดือนที่ผ่านมา
ให้ดูจากคลิป อื่นก่อนหน้านี้ ประกอบสำหรับท่าน ที่ เข้ามาชม ใหม่ สำหรับท่านที่ซื้ออุปกรณ์ไปแล้ว ให้ดูจากคลิป ใหม่ ของ ปีนี้ นะครับ ขอบคุณมากครับ
ตอบกลับ    
 สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์
สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์7 เดือนที่ผ่านมา
PWM output and input
Detailed Description

Usage

PWM output:

(Optionally) call pinRemap() to change the timer connected to a pin
(Optionally) call analogWriteFrequency() to change output PWM frequency
Call pinMode() with PWM
Call analogWrite()
PWM input can be accomplished using two underlying methods: using a timer input channel (pin needs to be connected to a general purpose timer channel), or using an external interrupt (can only have one per PinSource—this is the last digit in 0–15 of the pin name).

(Optionally) if using PWM_IN, call pinRemap() to change the timer connected to a pin
Call pinMode() with PWM_IN or PWM_IN_EXTI
Call pwmIn()
Example: PWM output

#include <Arduino.h>
void setup() {
  // (Optional) non Arduino-like function to assign a different timer to PB6
  pinRemap(PB6, 11, TIMER19, 1);
  // Arduino-like configuration for PWM
  analogWriteFrequency(PB6, 25000);
  // Unlike in Arduino, this MUST be called before analogWrite()
  pinMode(PB6, PWM);
}
void loop() {
  // 75% duty cycle PWM at 25 KHz
  analogWrite(PB6, 0.75);
}
Example: PWM input (loopback) test

#include <Arduino.h>
// Connect PA0 and PA6 for this test
void setup() {
  Serial1.begin(115200);
  pinMode(PA0, PWM);
  pinMode(PA6, PWM_IN);
}
void loop() {
  analogWrite(PA0, 0.3);
  Serial1 << "Read " << pwmIn(PA6) << "\n";
  delay(10);
}
Functions

void  analogWriteResolution (uint8_t nbits)
  Set the resolution for the analogWrite() function. More...

void  analogWriteFrequency (uint8_t pin, int freqHz)
  Assign a PWM frequency to the specified pin (default = 1000 Hz) More...

void  analogWriteFloat (uint8_t pin, float duty)
  Change the PWM duty cycle on a pin. More...

void  analogWrite (uint8_t pin, uint32_t duty)
  Change the PWM duty cycle on a pin. More...

float  pwmIn (uint8_t pin)
  Read a PWM signal (non-blocking) More...

void  pwmInExpectedPeriod (int expectedUs)
  Set the expected period for PWM_IN or PWM_IN_EXTI. More...

Function Documentation

void analogWrite ( uint8_t  pin,
uint32_t  duty
)
Change the PWM duty cycle on a pin.

This should have the same effect as the Arduino function, but it is not efficient on systems without a floating point (as implemented), since it calls analogWriteFloat() under the hood.

Parameters
pin
duty The new duty cycle in [0,2^n] where n is the bit resolution set by analogWriteResolution() (default 8)
void analogWriteFloat ( uint8_t  pin,
float  duty
)
Change the PWM duty cycle on a pin.

Unlike Arduino, pinMode() must have been called on the pin beforehand with PWM. Also, the duty cycle is specified in floating point, and the resolution is only limited by the timer (see analogWriteFrequency()).

Parameters
pin
duty The new duty cycle in normalized floating point from 0.0 (0%) to 1.0 (100%).
void analogWriteFrequency ( uint8_t  pin,
int  freqHz
)
Assign a PWM frequency to the specified pin (default = 1000 Hz)

Please see the pin remapping documentation for more details about connected timers to pins, including defaults. This function will change the PWM frequency for all pins connected to the same timer.

Gory details:

There is a 36MHz base clock.
Resolution: When PWM freq = 20KHz, resolution = 36000/20 = 1800 ~= 11 bits, and better for lower frequencies
Minimum freuency is 36000000/65535 = 549Hz
Parameters
pin Pin to change frequency on
freqHz New frequency in Hz (default is 1000)
void analogWriteResolution ( uint8_t  nbits )
Set the resolution for the analogWrite() function.

Note that this has no effect on the actual PWM resolution, which is determined by the period of the PWM (see analogWriteFrequency()). This also has no effect on analogWriteFloat()

Parameters
nbits Number of bits used in analogWrite() (default is 8, as in Arduino)
float pwmIn ( uint8_t  pin )
Read a PWM signal (non-blocking)

pinMode() with PWM_IN must have been called on the pin before-hand. Unlike Arduino, this function does not block and wait. It uses high-speed timer interrupts to catch rising and falling edges, and keeps track of the time when these happen to estimate the PWM duty cycle.

Advanced:

Period: The period of the PWM is also available in low-level form. The command
    1 TIMER_MAP[ PIN_MAP[ pin ].timer ].channelData[ PIN_MAP[ pin ].channel-1].period
will return the PWM period in units such that 36000 -> 1ms, 3600 -> 0.1ms etc.
Parameters
pin Pin to read
Returns
A float from 0.0 to 1.0 corresponding to PWM duty cycle
void pwmInExpectedPeriod ( int  expectedUs )
Set the expected period for PWM_IN or PWM_IN_EXTI.

Parameters
expectedUs Expected period in microseconds (default 1000)
แสดงน้อยลง
แปลภาษา
ตอบกลับ    
 Sompong Tungmepol
Sompong Tungmepol9 เดือนที่ผ่านมา (แก้ไขแล้ว)
แปลเป็น ภาษา อังกฤษ

#define UN        (400.0)    //Rate motor voltage
#define FN        (50.0)     //Rate motor frequency
#define P         (UN/FN)    // et.al specifies the proportion of voltage to the rated frequency
#define T_PWM     (0.000255) //period of PWM signal - set by prescaler counters
#define T_MAX     (4.0)      //Determination of the maximum period of the output voltage
#define T_MIN     (0.02)     //the minimum period of the output voltage
#define K_MAX     floor(T_MAX/T_PWM)  //the number of values for the period of  T_MAX
#define K_MIN     ceil(T_MIN/T_PWM)   //the number of values for the  period of  T_MIN

volatile static unsigned int dlugosc_tab_sin;   //variable containing the number of values in full
                                                //the period of the output voltage
static unsigned int i = 0;                      //variable auxiliary
volatile static unsigned int licznik_glowny = 0;//Variables in periodically interrupted
                                                //^ wath time T_PWM increasing its value by 1
static unsigned int next_value_sin = 0; //variable whose value should calculate sin
static double t_param=100;              //parameter specifies the period of the output voltage
static float t = T_PWM;                 //T_PWM
static float omega_t;                   //pulsation of the output voltage multiplied by T_PWM
static float t_out;                     //Output voltage period
static float U_o_param;                 //size parameter specified output voltage
                                        //^ calculated on the basis t_out and U_in
static unsigned int ocr0a, ocr0b, ocr1a;//auxiliary variables for storing calculated filling material
static unsigned int ocr1b, ocr2a, ocr2b;//^
static double sin_in;         //variable containing the parameter of the function sin
static double blad = 1;       // variable deck used to stop generating voltage of overloading
static unsigned int analog=0; //variable containing the measured value
static double U_in = 0;       //variable stores the measurement voltage cardiovascular middleware
static double U_rms_max;      //the maximum currently possible after generation of the effective voltage
static bool a=0;              //Boolean to perform two alternate measurements
int main()
{
  io_init();     //initialization inputs and outputs
  timers_init(); //initializing the counter PWM
  adc_init();    //initialization transducer ADC
  while(1)                                //infinite loop of the main program
  {
    if(i==185)                            //the condition concerning the entry to change function
    {                                     //parameters of the output voltage , the call approximately every 100 ms
      zmien_predkosc();                   //change function parameters of the output voltage
      i=0;
    }
    next_value_sin = licznik_glowny%dlugosc_tab_sin;  //kolejna wartoœๆ sinusa do obliczenia
    sin_in=omega_t*next_value_sin;

/obliczenie wartosci do rejestrow okreslajacych wypelnienie sygnalu wyjscioweg/
    ocr0a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6
    ocr0b = ocr0a - 1;
    ocr1a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 9
    ocr1b = ocr1a - 1;
    ocr2a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11
    ocr2b = ocr2a - 1;
     
/uaktualnienie wartosci w rejestrach/
    cli();                              //prohibit to handle interrupts in case
                                        //when you upgrade an interrupt
    OCR0A = ocr0a;    //pin 6
    OCR0B = ocr0b;    //pin 5
    OCR1AL = ocr1a;   //pin 9
    OCR1BL = ocr1b;   //pin 10
    OCR2A = ocr2a;    //pin 11
    OCR2B = ocr2b;    //pin 3
    sei();                              //Permission to interrupt service
    i++;
    }
}
void adc_init()
{
ADCSRA |= _BV(ADEN);//launching transducer
ADCSRA |= _BV(ADPS2);//setting prescaler
ADCSRA |= _BV(ADPS1);//^
ADCSRA |= _BV(ADPS0);//^
ADMUX |= _BV(REFS0);// voltage reference set as a voltage supply
ADMUX |= ADMUX &= 0b11110000; //selecting ADC0 input 0 to measure
}
void timers_init()
{
cli();  // service interrupts prohibited
//timer0 init
TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00);              
TCCR0B |= _BV(CS01);              //preskaler 8
TIMSK0 |= _BV(TOIE0);             //flag of value 0 switched on
//timer1 init
TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1)  | _BV(WGM10);    
TCCR1B |= _BV(CS11);              //preskaler 8
//timer2 init
TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1)  | _BV(WGM20);    
TCCR2B |= _BV(CS21);              //preskaler 8
//reset value of the counter
TCNT0 = 0;
TCNT1L = 0;
TCNT2 = 0;
/* licznik zlicza w g๓re do 255, nastepnie w d๓ณ: /\/\/\
przy wartosci 255 jest przerwanie przy ktorym dokonuje sie
pomiarow napiec i pradow
*/
sei();  //permission to interrupt service
}
void io_init()
{
  pinMode(6, OUTPUT); //OC0A
  pinMode(5, OUTPUT); //OC0B
  pinMode(9, OUTPUT); //OC1A
  pinMode(10, OUTPUT);//OC1B
  pinMode(11, OUTPUT);//OC2A
  pinMode(3, OUTPUT); //OC2B
  pinMode(2, INPUT);
  pinMode(4, INPUT);
  pinMode(12, OUTPUT);
}
ISR(TIMER0_OVF_vect)  //interruption of the value of the counter 00
{
    analog = ADC;
      if(a)
      {
        U_in = 0.0709*analog;
        ADMUX |= _BV(MUX0);           //select input  ADC1 to measure the current                                    
      }
      else
      {
        ADMUX |= ADMUX &= 0b11110000; //select input  ADC0 to measure voltage
        if(analog>579)          
        {
          blad = 0;               // If the overload voltage generation Exclusion
          digitalWrite(12, HIGH); //diode
        }
      }
      ADCSRA |= _BV(ADSC);//  start reading measurement
      a=a^1;              //bramka XOR neguje wartosc logiczna a              
 licznik_glowny++;
 if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0;
}
void zmien_predkosc()
{
  U_rms_max = U_in*0.62;  //0.62 value determined experimentally
  bool up;          //boolean informs about holding down the button increases the frequency
  bool down;        //boolean inform the button is pressed , reduce frequency
  up =  digitalRead(4);     //read:if pressed increases the frequency
  down = digitalRead(2);    //read:if you pressed the button reduce the frequency
  if(up==1) t_param--;      //If you press the button increases the frequency decrease the period
  if(down==1) t_param++;    //If you press the button to decrease the frequency increases the service life
  if(t_param<0) t_param=0;    //protection exceeding the extreme values
  if(t_param>100) t_param=100;//^
  dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/50+K_MIN);//number of padded values in one period
  t_out = T_PWM*dlugosc_tab_sin;                          //calculation of  period of the output voltage
  omega_t = t*2*PI/t_out;                                 //calculate the output ripple voltage
  U_o_param = (P/t_out)/U_rms_max;  //calculation of the parameter defining an output voltage
  if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //the voltage at the output at low frequency 10V
  if(U_o_param>1) U_o_param=1;                  //protection exceeding the extreme values
}
อ่านเพิ่มเติม
แปลภาษา
ตอบกลับ    
 Sompong Tungmepol
Sompong Tungmepol9 เดือนที่ผ่านมา (แก้ไขแล้ว)
Code จาก ท่าน      SIR...  Tomasz Drazek     ประเทศ Poland  โปแลนด์ ครับ

#define UN        (400.0)    //napiecie znamionowe silnika
#define FN        (50.0)     //czestotliwosc znamionowa silnika
#define P         (UN/FN)    //wsp. okreslajacy proporcje napiecia do czestotliwoci znamionowej
#define T_PWM     (0.000255) //okres sygnalu PWM - ustawiony przez preskaler w licznikach
#define T_MAX     (4.0)      //okreslenie maksymalnego okresu napiecia wyjsciowego
#define T_MIN     (0.02)     //minimalny okres napiecia wyjsciowego
#define K_MAX     floor(T_MAX/T_PWM)  //liczba wartosci okresu dla T_MAX
#define K_MIN     ceil(T_MIN/T_PWM)   //liczba wartosci okresu dla T_MIN

volatile static unsigned int dlugosc_tab_sin;   //zmienna zawierajaca liczbe wartosci w pelnym
                                                //okresie napiecia wyjsciowego
static unsigned int i = 0;                      //zmienna pomocniacza
volatile static unsigned int licznik_glowny = 0;//zmienna wystepujaca w przerwaniu czyklicznie
                                                //^ co okres T_PWM zwiekszajaca swoja wartosc o 1
static unsigned int next_value_sin = 0; //zmienna ktora wartosc sin nalezy obliczyc
static double t_param=100;              //parametr okreslajacy okres napiecia wyjsciowego
static float t = T_PWM;                 //T_PWM
static float omega_t;                   //pulsacja napiecia wyjsciowego pomnozona przez T_PWM
static float t_out;                     //okres wyjsciowy napiecia
static float U_o_param;                 //parametr okreslajacy wielkosc napiecie wyjsciowego
                                        //^ obliczony na podstawie t_out i U_in
static unsigned int ocr0a, ocr0b, ocr1a;//zmienne pomocnicze do przechowywania obl. wypelnien
static unsigned int ocr1b, ocr2a, ocr2b;//^
static double sin_in;         //zmienna zawierajaca parametr funkcji sin
static double blad = 1;       //zmienna uzyta do zatrzymania generowania napiecia przy przeciazeniu
static unsigned int analog=0; //zmienna zawierajaca zmierzona wartosc
static double U_in = 0;       //zmienna przechowujนca pomiar napiecia ukladu posredniczacego
static double U_rms_max;      //maksymalna aktualnie mozliwa do generacji wartosc skuteczna napiecia
static bool a=0;              //zmienna logiczna do realizacji dwoch naprzemiennych pomiarow
int main()
{
  io_init();     //inicjalizacja wejsc i wyjsc
  timers_init(); //inicjalizacja licznikow PWM
  adc_init();    //inicjalizacja przetwornika ADC
  while(1)                                //nieskonczona petla z programem glownym
  {
    if(i==185)                            //warunek okreslajacy wejscie do funkcji zmiany
    {                                     //parametrow napiecia wysjciowego, wywolanie co okolo 100ms
      zmien_predkosc();                   //funkcja zmiany parametrow napiecia wyjsciowego
      i=0;
    }
    next_value_sin = licznik_glowny%dlugosc_tab_sin;  //kolejna wartoœๆ sinusa do obliczenia
    sin_in=omega_t*next_value_sin;

/obliczenie wartosci do rejestrow okreslajacych wypelnienie sygnalu wyjscioweg/
    ocr0a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6
    ocr0b = ocr0a - 1;
    ocr1a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 9
    ocr1b = ocr1a - 1;
    ocr2a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11
    ocr2b = ocr2a - 1;
     
/uaktualnienie wartosci w rejestrach/
    cli();                              //zabronienie na obsloge przerwan na wypadek gdyby
                                        //podczas uaktualniania wystapilo przerwanie
    OCR0A = ocr0a;    //pin 6
    OCR0B = ocr0b;    //pin 5
    OCR1AL = ocr1a;   //pin 9
    OCR1BL = ocr1b;   //pin 10
    OCR2A = ocr2a;    //pin 11
    OCR2B = ocr2b;    //pin 3
    sei();                              //zezwolenie na obsloge przerwan
    i++;
    }
}
void adc_init()
{
ADCSRA |= _BV(ADEN);//uruchomienie przetwornika
ADCSRA |= _BV(ADPS2);//ustawienie preskalera
ADCSRA |= _BV(ADPS1);//^
ADCSRA |= _BV(ADPS0);//^
ADMUX |= _BV(REFS0);// napiecie odniesienia ustawione jako napiecie zasilania
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru
}
void timers_init()
{
cli();  // obsloga przerwan zabroniona
//timer0 init
TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00);              
TCCR0B |= _BV(CS01);              //preskaler 8
TIMSK0 |= _BV(TOIE0);             //flaga od wartosci 0 wlaczona
//timer1 init
TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1)  | _BV(WGM10);    
TCCR1B |= _BV(CS11);              //preskaler 8
//timer2 init
TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1)  | _BV(WGM20);    
TCCR2B |= _BV(CS21);              //preskaler 8
//zerowanie wartosci licznik๓w
TCNT0 = 0;
TCNT1L = 0;
TCNT2 = 0;
/* licznik zlicza w g๓re do 255, nastepnie w d๓ณ: /\/\/\
przy wartosci 255 jest przerwanie przy ktorym dokonuje sie
pomiarow napiec i pradow
*/
sei();  //zezwolenie na obsloge przerwan
}
void io_init()
{
  pinMode(6, OUTPUT); //OC0A
  pinMode(5, OUTPUT); //OC0B
  pinMode(9, OUTPUT); //OC1A
  pinMode(10, OUTPUT);//OC1B
  pinMode(11, OUTPUT);//OC2A
  pinMode(3, OUTPUT); //OC2B
  pinMode(2, INPUT);
  pinMode(4, INPUT);
  pinMode(12, OUTPUT);
}
ISR(TIMER0_OVF_vect)  //przerwanie przy wartosci 0 licznika0
{
    analog = ADC;
      if(a)
      {
        U_in = 0.0709*analog;
        ADMUX |= _BV(MUX0);           //wybranie wejscia ADC1 do pomiaru pradu                                          
      }
      else
      {
        ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru napiecia
        if(analog>579)          
        {
          blad = 0;               //jezeli przeciazenie wylaczenie generacji napiecia
          digitalWrite(12, HIGH); //zapalenie diody
        }
      }
      ADCSRA |= _BV(ADSC);//start odczytywania pomiaru
      a=a^1;              //bramka XOR neguje wartosc logiczna a              
 licznik_glowny++;
 if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0;
}
void zmien_predkosc()
{
  U_rms_max = U_in*0.62;  //wartosc 0.62 wyzanczona eksperymentalnie
  bool up;          //zmienna logiczna, informuje o nacisnietym przycisku zwieksz czestotliwosc
  bool down;        //zmienna logiczna, informuje o nacisnietym przycisku zmiejsz czestotliwosc
  up =  digitalRead(4);     //odczyt: czy nacisniety przycisk zwieksz czestotliwosc
  down = digitalRead(2);    //odczyt: czy nacisniety przycisk zmiejsz czestotliwosc
  if(up==1) t_param--;      //jezeli nacisniety przycisk zwieksz czestotliwosc to zmiejsz okres
  if(down==1) t_param++;    //jezeli nacisniety przycisk zmniejsz czestotliwosc to zwieksz okres
  if(t_param<0) t_param=0;    //zabezpieczenie przekroczenia wartosci skrajnych
  if(t_param>100) t_param=100;//^
  dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/100+K_MIN);//ilosc wartosci wypelnien w jednym okresie
  t_out = T_PWM*dlugosc_tab_sin;                          //obliczenie okresu napiecia wyjsciowego
  omega_t = t*2*PI/t_out;                                 //obliczenie pulsacji napiecia wyjsciowego
  U_o_param = (P/t_out)/U_rms_max;  //obliczenie parametru okreslajacego wielkosc napiecia wyjsciowego
  if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //napi๊cie na wyjsciu przy niskiej czestotliwosci 10V
  if(U_o_param>1) U_o_param=1;                  //zabezpieczenie przekroczenia wartosci skrajnych
}
อ่านเพิ่มเติม
แปลภาษา
ตอบกลับ    
 Sompong Tungmepol
Sompong Tungmepol9 เดือนที่ผ่านมา (แก้ไขแล้ว)
ราคาเหมาะสมกับภาวะเศรษฐกิจ หรือ ลงโปรแกรมเองก็ได้ ครับ Code inverter 3 phase for induction motor speed control Atmega 328 P Arduino uno By ท่าน  Tomasz Drazek จากประเทศ โปแลนด์ อยู่ด้านล่าง ครับ Copy ไป ลง Arduino แล้วแปลงไฟล์ อัพโหลด ก็ใช้ได้ ดู จาก คลิป ตัวอย่าง ที่ผมลง ไปแล้ว การทำงานและ ต่อสาย ตามนี้ครับ

#define UN        (400.0)    //napiecie znamionowe silnika
#define FN        (50.0)     //czestotliwosc znamionowa silnika
#define P         (UN/FN)    //wsp. okreslajacy proporcje napiecia do czestotliwoci znamionowej
#define T_PWM     (0.000255) //okres sygnalu PWM - ustawiony przez preskaler w licznikach
#define T_MAX     (4.0)      //okreslenie maksymalnego okresu napiecia wyjsciowego
#define T_MIN     (0.02)     //minimalny okres napiecia wyjsciowego
#define K_MAX     floor(T_MAX/T_PWM)  //liczba wartosci okresu dla T_MAX
#define K_MIN     ceil(T_MIN/T_PWM)   //liczba wartosci okresu dla T_MIN

volatile static unsigned int dlugosc_tab_sin;   //zmienna zawierajaca liczbe wartosci w pelnym
                                                //okresie napiecia wyjsciowego
static unsigned int i = 0;                      //zmienna pomocniacza
volatile static unsigned int licznik_glowny = 0;//zmienna wystepujaca w przerwaniu czyklicznie
                                                //^ co okres T_PWM zwiekszajaca swoja wartosc o 1
static unsigned int next_value_sin = 0; //zmienna ktora wartosc sin nalezy obliczyc
static double t_param=100;              //parametr okreslajacy okres napiecia wyjsciowego
static float t = T_PWM;                 //T_PWM
static float omega_t;                   //pulsacja napiecia wyjsciowego pomnozona przez T_PWM
static float t_out;                     //okres wyjsciowy napiecia
static float U_o_param;                 //parametr okreslajacy wielkosc napiecie wyjsciowego
                                        //^ obliczony na podstawie t_out i U_in
static unsigned int ocr0a, ocr0b, ocr1a;//zmienne pomocnicze do przechowywania obl. wypelnien
static unsigned int ocr1b, ocr2a, ocr2b;//^
static double sin_in;         //zmienna zawierajaca parametr funkcji sin
static double blad = 1;       //zmienna uzyta do zatrzymania generowania napiecia przy przeciazeniu
static unsigned int analog=0; //zmienna zawierajaca zmierzona wartosc
static double U_in = 0;       //zmienna przechowujนca pomiar napiecia ukladu posredniczacego
static double U_rms_max;      //maksymalna aktualnie mozliwa do generacji wartosc skuteczna napiecia
static bool a=0;              //zmienna logiczna do realizacji dwoch naprzemiennych pomiarow
int main()
{
  io_init();     //inicjalizacja wejsc i wyjsc
  timers_init(); //inicjalizacja licznikow PWM
  adc_init();    //inicjalizacja przetwornika ADC
  while(1)                                //nieskonczona petla z programem glownym
  {
    if(i==185)                            //warunek okreslajacy wejscie do funkcji zmiany
    {                                     //parametrow napiecia wysjciowego, wywolanie co okolo 100ms
      zmien_predkosc();                   //funkcja zmiany parametrow napiecia wyjsciowego
      i=0;
    }
    next_value_sin = licznik_glowny%dlugosc_tab_sin;  //kolejna wartoœๆ sinusa do obliczenia
    sin_in=omega_t*next_value_sin;

/obliczenie wartosci do rejestrow okreslajacych wypelnienie sygnalu wyjscioweg/
    ocr0a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6
    ocr0b = ocr0a - 1;
    ocr1a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 9
    ocr1b = ocr1a - 1;
    ocr2a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11
    ocr2b = ocr2a - 1;
     
/uaktualnienie wartosci w rejestrach/
    cli();                              //zabronienie na obsloge przerwan na wypadek gdyby
                                        //podczas uaktualniania wystapilo przerwanie
    OCR0A = ocr0a;    //pin 6
    OCR0B = ocr0b;    //pin 5
    OCR1AL = ocr1a;   //pin 9
    OCR1BL = ocr1b;   //pin 10
    OCR2A = ocr2a;    //pin 11
    OCR2B = ocr2b;    //pin 3
    sei();                              //zezwolenie na obsloge przerwan
    i++;
    }
}
void adc_init()
{
ADCSRA |= _BV(ADEN);//uruchomienie przetwornika
ADCSRA |= _BV(ADPS2);//ustawienie preskalera
ADCSRA |= _BV(ADPS1);//^
ADCSRA |= _BV(ADPS0);//^
ADMUX |= _BV(REFS0);// napiecie odniesienia ustawione jako napiecie zasilania
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru
}
void timers_init()
{
cli();  // obsloga przerwan zabroniona
//timer0 init
TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00);              
TCCR0B |= _BV(CS01);              //preskaler 8
TIMSK0 |= _BV(TOIE0);             //flaga od wartosci 0 wlaczona
//timer1 init
TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1)  | _BV(WGM10);    
TCCR1B |= _BV(CS11);              //preskaler 8
//timer2 init
TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1)  | _BV(WGM20);    
TCCR2B |= _BV(CS21);              //preskaler 8
//zerowanie wartosci licznik๓w
TCNT0 = 0;
TCNT1L = 0;
TCNT2 = 0;
/* licznik zlicza w g๓re do 255, nastepnie w d๓ณ: /\/\/\
przy wartosci 255 jest przerwanie przy ktorym dokonuje sie
pomiarow napiec i pradow
*/
sei();  //zezwolenie na obsloge przerwan
}
void io_init()
{
  pinMode(6, OUTPUT); //OC0A
  pinMode(5, OUTPUT); //OC0B
  pinMode(9, OUTPUT); //OC1A
  pinMode(10, OUTPUT);//OC1B
  pinMode(11, OUTPUT);//OC2A
  pinMode(3, OUTPUT); //OC2B
  pinMode(2, INPUT);
  pinMode(4, INPUT);
  pinMode(12, OUTPUT);
}
ISR(TIMER0_OVF_vect)  //przerwanie przy wartosci 0 licznika0
{
    analog = ADC;
      if(a)
      {
        U_in = 0.0709*analog;
        ADMUX |= _BV(MUX0);           //wybranie wejscia ADC1 do pomiaru pradu                                          
      }
      else
      {
        ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru napiecia
        if(analog>579)          
        {
          blad = 0;               //jezeli przeciazenie wylaczenie generacji napiecia
          digitalWrite(12, HIGH); //zapalenie diody
        }
      }
      ADCSRA |= _BV(ADSC);//start odczytywania pomiaru
      a=a^1;              //bramka XOR neguje wartosc logiczna a              
 licznik_glowny++;
 if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0;
}
void zmien_predkosc()
{
  U_rms_max = U_in*0.62;  //wartosc 0.62 wyzanczona eksperymentalnie
  bool up;          //zmienna logiczna, informuje o nacisnietym przycisku zwieksz czestotliwosc
  bool down;        //zmienna logiczna, informuje o nacisnietym przycisku zmiejsz czestotliwosc
  up =  digitalRead(4);     //odczyt: czy nacisniety przycisk zwieksz czestotliwosc
  down = digitalRead(2);    //odczyt: czy nacisniety przycisk zmiejsz czestotliwosc
  if(up==1) t_param--;      //jezeli nacisniety przycisk zwieksz czestotliwosc to zmiejsz okres
  if(down==1) t_param++;    //jezeli nacisniety przycisk zmniejsz czestotliwosc to zwieksz okres
  if(t_param<0) t_param=0;    //zabezpieczenie przekroczenia wartosci skrajnych
  if(t_param>100) t_param=100;//^
  dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/100+K_MIN);//ilosc wartosci wypelnien w jednym okresie
  t_out = T_PWM*dlugosc_tab_sin;                          //obliczenie okresu napiecia wyjsciowego
  omega_t = t*2*PI/t_out;                                 //obliczenie pulsacji napiecia wyjsciowego
  U_o_param = (P/t_out)/U_rms_max;  //obliczenie parametru okreslajacego wielkosc napiecia wyjsciowego
  if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //napi๊cie na wyjsciu przy niskiej czestotliwosci 10V
  if(U_o_param>1) U_o_param=1;                  //zabezpieczenie przekroczenia wartosci skrajnych
}
แสดงน้อยลง
แปลภาษา
ตอบกลับ  

ไม่มีความคิดเห็น:

แสดงความคิดเห็น