วันอังคารที่ 27 กันยายน พ.ศ. 2559

arduino 3 phase induction motor speed control

#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.000355) //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.03)     //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 led สีแดงขา 12
        }
      }
      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
}

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

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