Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

VFD to control 3 phase AC induction motor 400V 6000 rpm

Status
Not open for further replies.
Hi,

I think it's far more beneficial if I solve this problem here - I think many of our children will have a lot to learn. So the benefit would be millions of times bigger than if I bought a VFD...

Learning.. means to start at the basics. This is what I´m missing here.

The problem is not that the lack of knowledge about
* what´s the use of the filter
* why a comparator is used and not a simple logic gate
* PCB layout
* and so on..

The biggest problem is that I don´t think the OP knows about the safety...
And teaching children how to build a VFD but at the sime time risking the life of the children is not what I want to support.

Klaus
 

Hi,



Learning.. means to start at the basics. This is what I´m missing here.

The problem is not that the lack of knowledge about
* what´s the use of the filter
* why a comparator is used and not a simple logic gate
* PCB layout
* and so on..

The biggest problem is that I don´t think the OP knows about the safety...
And teaching children how to build a VFD but at the sime time risking the life of the children is not what I want to support.

Klaus

I think this story has begun to take another direction here - from proposing a functional VFD scheme to the way we educate our children.
I do not think it's dangerous for a 15-year-old child to play with such a circuit at 30V 5A for example.
I think it's more dangerous if a 15-year-old would drink 5 beers in 30 minutes.
Let's be serious, everything is about education.

For me, electronics is just a hobby and I just asked you to participate in the practical realization of a very useful device with a wide range of applications.
I am very convinced that there are users here who have done so successfully and all I have asked is to share knowledge.
You can see very simply how interesting this topic is - it was viewed 4400 times in a very short time.
So let's build a sinusoidal open source VFD - it looks like we need it.
 
Last edited:

Hi,

The direction is given by the member who brought those keywords into the discussion: "400V", "education", "children", "beer", ..

There are many reliable sources to learn "how to design a VFD" in the internet.
They have a step by step teaching method: they start with basics, theory of operation, mathematics, raw - then detailed design of schematics, hardware and PCB layout. Profound knowledge.
My personal opinion is, that this is a more effective way to teach knowledge.

I want to emphasize "reliable". This means proven circuits from universities or hardware manufacturers, not random circuits from hobbyists, with fragmentary description.

***
I don´t want to stop you from teaching (your) children. Please keep on doing this.

But my personal opinion still is: I don´t see this thread is a useful way to educate how to design a VFD - rather how not to do electronics design.

Klaus
 

I think this story has begun to take another direction here.

Not sure if you are still interested in the original topic. If we think about educational VFD design, we should also talk about the quality of learning material and design examples. The material you base your design ideas on is unsuitable in my opinion.
 

Not sure if you are still interested in the original topic. If we think about educational VFD design, we should also talk about the quality of learning material and design examples. The material you base your design ideas on is unsuitable in my opinion.

I'm waiting for you to come up with a functional circuit proposal.
Meanwhile, I've been thinking of using as a VESC command circuit that is open source and my power circuit based on the HCPL3120
https://github.com/vedderb/bldc-hardware
 

I already suggested a functional circuit in post #59. I believe you have still difficulties to see the problem with your original circuit and understand the requirements for a VFD inverter gate drive pattern. There's no simple solution, except for studying the topic thoroughly.
 

The circuit drives the inverter with square waves instead of sine pwm. You can have this much easier by sending square waves out of the micro controller, don't need the dds stuff.
post#57

I already suggested a functional circuit in post #59. I believe you have still difficulties to see the problem with your original circuit and understand the requirements for a VFD inverter gate drive pattern. There's no simple solution, except for studying the topic thoroughly.

In post#57 you said that the IGBT bridge would be commanded by a square signal that does not help me.
I want a sinusoidal signal inverter.
If I could manage myself, I would not ask for help

- - - Updated - - -

My suggestion so that your work enviroment is safer when you test your motor with higher voltages.

Simply send your motor to a motor rewinder. Let him rewind your motor from 3 phase 400Vac to 3 phase 24Vac. It will not cost too much. The rewinder can use the same enamelled wire. It costs you maybe 50-60 USD.

After that you can test all your system including the IGBTS with 24VDC Bus.

After you test all the fuctionality, you raise your DC bus to 560VDC and change your motor windings back to 400Vac and make further enchancement.

This is a more safer way.

I test with this code and my IR2113 IGBT driver and my 400V 900 rpm motor start to rotate at 30V but the signal is square and not so good for my motor

My test: https://www.dropbox.com/s/456wewors6dmfc6/WhatsApp%20Video%202019-03-25%20at%2018.07.41.mp4?dl=0
https://www.dropbox.com/s/261kgkul3ci35ln/WhatsApp%20Video%202019-03-25%20at%2018.09.33.mp4?dl=0
 
Last edited:

I really think you should buy a cheap drive rather than try and do this yourself. Also is the Motor rated to operate at 6000rpm? They sometimes do not like to run at above their base speed and can explode.
 

Forget post #57. I just wanted to explain why the post #56 circuit is useless.

The Arduino OCRx pins are already outputting a pulse pattern modulated with a sine waveform (except for some missing details like speed proportional magnitude and superimposed zero sequence to fully utilize the available DC bus voltage). You only need to send each of the three pwm signals to a half bridge to get a sine shaped motor current.

Also is the Motor rated to operate at 6000rpm? They sometimes do not like to run at above their base speed and can explode.

Industry standard motors of the said size (6 kW) can run up to 6000 rpm. Review a motor catalog. But according to V/f characteristic, the voltage must be doubled to keep the torque. A 230/400 V 6kW motor wired for 230V can run with 400V 100Hz input at 3/4 of its nominal torque, respectively 9 kW power.

- - - Updated - - -

Meanwhile, I've been thinking of using as a VESC command circuit that is open source and my power circuit based on the HCPL3120.
No bad idea. STM32F4 is one of the previously mentioned powerful processors that can generate all 6 gate drive signals directly. The considerations about sine pwm pattern are still valid. In other words, it's possible to achieve the basic function with the circuit suggested in post #59.
 
You may also consider driving the driver transistors (gate drivers) with pulse transformers that can help many of the common problems. But I really do not know why transformer drivers are not popular.
 
Forget post #57. I just wanted to explain why the post #56 circuit is useless.

The Arduino OCRx pins are already outputting a pulse pattern modulated with a sine waveform (except for some missing details like speed proportional magnitude and superimposed zero sequence to fully utilize the available DC bus voltage). You only need to send each of the three pwm signals to a half bridge to get a sine shaped motor current.



Industry standard motors of the said size (6 kW) can run up to 6000 rpm. Review a motor catalog. But according to V/f characteristic, the voltage must be doubled to keep the torque. A 230/400 V 6kW motor wired for 230V can run with 400V 100Hz input at 3/4 of its nominal torque, respectively 9 kW power.

- - - Updated - - -


No bad idea. STM32F4 is one of the previously mentioned powerful processors that can generate all 6 gate drive signals directly. The considerations about sine pwm pattern are still valid. In other words, it's possible to achieve the basic function with the circuit suggested in post #59.

Do you say it will work with the scheme from post # 59?
The three phases that will power the motor will have a sinusoidal signal in this case?
Thank you

- - - Updated - - -

You may also consider driving the driver transistors (gate drivers) with pulse transformers that can help many of the common problems. But I really do not know why transformer drivers are not popular.

I would like to use DC DC isolated converters for each mosfet driver.
But this is a fairly costly method - if you know an equally good and less expensive method I would love to apply it in this circuit.
Thank you
 

Square waves can be shaped to become sine-like, via the same type of LC 2nd order filter which is generally used to smooth SPWM. The L & C values need to be tailored to suit load and frequency. And they are larger than those needed to smooth SPWM.

Here are 3 simulations applying 560VAC square waves at 25, 50 & 75Hz. The middle circuit resembles one winding of your motor, normally drawing 2kW at 400 VAC.

I 'guesstimate' the load value to have reduced impedance at a slow frequency (thus it tries to draw higher Amperes), and greater impedance at the fast frequency. The aim is to avoid overload.

This method with low-freq square waves is not so prone to create hi-voltage spikes. The inductor always sees low-impedance. Therefore current is not abruptly shut off.

560v sq wave LC2nd order filter loads get sines 25 50 75Hz.png

The problem is that a different coil and capacitor are needed each time you change frequency. Perhaps you might choose to have several switches, each providing a different different gate frequency, inductor & capacitor.
 

Here are 3 simulations applying 560VAC square waves at 25, 50 & 75Hz.

For a realistic simulation, you should use the values for 75Hz and see the effect at 50Hz and 100Hz.

We should also replace the load as an inductor (rather than a resistor). Because the frequency range is rather limited, the effects will be rather small.

But even a 5 step PWM can have a very effective role (in terms of large capacitors and inductors that can become very expensive).
 
For a realistic simulation, you should use the values for 75Hz and see the effect at 50Hz and 100Hz.

We should also replace the load as an inductor (rather than a resistor). Because the frequency range is rather limited, the effects will be rather small.

But even a 5 step PWM can have a very effective role (in terms of large capacitors and inductors that can become very expensive).
Hi, you introduced me into a study that I only dream of VFD all night.
I found this code on the internet that promises to generate all 6 spwm signals.
Can you help me measure dead time and if it works to adjust it?
Thank you


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
// 3 phase PWM sine
// (c) 2016 C. Masenas
// Additional modifications from KHM 2009 DDS generator /  Martin Nawrath
// Modified Y2018 By Seree2004
 
#include <LiquidCrystal.h>    //Call the LCD display command program to join.
 
// Saow Wave data set, 256 characters per set //Amplitude_248 
PROGMEM const unsigned char Sine_Table[256]  = {124,127,130,133,136,139,142,145,148,151,154,157,160,163,166,169,172,174,177,180,
183,185,188,191,193,196,198,201,203,205,208,210,212,214,216,218,220,222,224,226,227,229,231,232,234,235,236,238,239,240,241,242,
243,244,244,245,246,246,247,247,247,248,248,248,248,248,248,248,247,247,247,246,245,245,244,243,242,241,240,239,238,237,236,234,
233,231,230,228,227,225,223,221,219,217,215,213,211,209,206,204,202,199,197,194,192,189,187,184,181,179,176,173,170,167,164,162,
159,156,153,150,147,144,141,138,135,132,129,126,122,119,116,113,110,107,104,101,98,95,92,89,86,84,81,78,75,72,69,67,64,61,59,56,
54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,17,15,14,12,11,10,9,8,7,6,5,4,3,3,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,4,5,
6,7,8,9,10,12,13,14,16,17,19,21,22,24,26,28,30,32,34,36,38,40,43,45,47,50,52,55,57,60,63,65,68,71,74,76,79,82,85,88,91,94,97,
100,103,106,109,112,115,118,121,124};
 
// Change the method of setting the value of the new internal register of Arduino to make it easier to use.
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
// Change the name of the new Arduino pin to make it easy to connect the circuit.
#define PWM_OUT_UL  6   // PWM1 UL output
#define PWM_OUT_UH  5   // PWM1 UH output
#define PWM_OUT_VL  9   // PWM2 VL output
#define PWM_OUT_VH  10  // PWM2 VH output
#define PWM_OUT_WL  11  // PWM3 WL output
#define PWM_OUT_WH  3   // PWM3 WH output
#define testPin   13  // Test OutPut To flash the lamp LED
#define enablePin 8   // To turn off / turn on the Power Driver sector
#define single_3ph      12      //For the jumper to be single phase or 3 phase
#define FAULT_DETECT     2     //In order to detect various errors, will turn off the Power Driver sector before causing the device to be damaged
#define FREQ_POT     0        //In order to reduce the frequency of the volume analog input A0 
//#define CURRENT_POT  1        // Reserve analog input A1 
#define WATER  1    // Float switch
#define USER1  6    // Reserve analog input A6
#define USER2  7    // Reserve  analog input A7
 
// Name the configuration  DeadTime
#define DT_LOW          2   // DeadTime Low Side
#define DT_HIGH  DT_LOW*2   // DeadTime High Side
// Name the configuration of Volume adjusts the speed (Hz) minimum and maximum
#define FREQ_MIN     7        // default: 15
#define FREQ_MAX     60    // default: 90
#define MAX_AMP_AT   50      // Giving the highest Amplitude strength at 50 Hz
// Change the name of the fixed value of the Arduino volume controller, which is the ability of each MCU in different numbers.
#define POT_MIN 0    // default: 0
#define POT_MAX 1023 // default: 1023
#define MAX_Amplitude 64
#define TABLE_DIV 64
 
//Naming variables used in the program
volatile  float freq = 15;
const float refclk = 3921  ;     // Fixed values derived from calculations Crystal used 16 MHz / 8/510/256 = 15.318
 
// Name the variables that are used to calculate the cycles of the signal waveforms and continuously interrupt service declared as voilatile
volatile unsigned long sigma;   // phase accumulator
volatile unsigned long delta;  // phase increment
 
volatile unsigned long  c4ms;  // counter incremented every 4ms
volatile unsigned long  c4x10ms;
 
//ตั้งชื่อตัวแปรต่าง ๆ
byte character1[8] = {0,18,18,18,18,18,27,0};
byte character2[8] = {0,14,17,29,21,21,25,0};
byte character3[8] = {0,4,4,4,4,4,6,0};
byte character4[8] = {0,2,31,1,29,19,25,0};
byte character5[8] = {1,15,6,9,14,1,6,0};
byte phase0, phase1, phase2, freq_old, freq_new,temp,temp2,Amplitude; 
unsigned int temp_ocr0a, temp_ocr0b, temp_ocr1a, temp_ocr1b, temp_ocr2a, temp_ocr2b;
unsigned int SW_WATER = 0;
 
bool single = false;
bool testPin_status = false;
 
// Name the fixed values that we define in connecting the Arduino pins to the LCD for easy recognition.
  const int RS = 7, EN = 4, D4 = A2, D5 = A3, D6 = A4, D7 = A5;
// And then order to define this
  LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
  
//*********** Change Version here **************************** 
char My_Version[] = "-Ver.10-10-2018-";
//*********************************************************
 
// Start the program by setting various commands first.
void setup(){
  //------------------------------------
   pinMode(FAULT_DETECT,OUTPUT);
   digitalWrite(FAULT_DETECT, LOW);
  //------------------------------------ 
   pinMode(enablePin, OUTPUT);     // Order the set to be an output signal
   digitalWrite(enablePin, LOW);   // Order this leg to be closed (in 0) to make the region  Power Drive Don't just work now
   pinMode(testPin, OUTPUT);       // Order the set to be an output signal
 
   pinMode(single_3ph, INPUT_PULLUP); // Order the set to be the input signal and the pool up
 
   pinMode(PWM_OUT_UL, OUTPUT); // Order the set to be an output signal
   pinMode(PWM_OUT_UH, OUTPUT); // Order the set to be an output signal
   pinMode(PWM_OUT_VL, OUTPUT); // Order the set to be an output signal
   pinMode(PWM_OUT_VH, OUTPUT); // Order the set to be an output signal
   pinMode(PWM_OUT_WL, OUTPUT); // Order the set to be an output signal
   pinMode(PWM_OUT_WH, OUTPUT); // Order the set to be an output signal
   
   if (digitalRead(single_3ph) == LOW){single = true;} // Check if the jumper pin is single phase or not. If the jumper says true, if he does not say that he is false
   
   lcd.begin(16,2); // Start the LCD display.
   lcd.createChar(0,character1);
   lcd.createChar(1,character2);
   lcd.createChar(2,character3);
   lcd.createChar(3,character4);
   lcd.createChar(4,character5);
   
   lcd.setCursor(5, 0); // Order to display column number 5 on the first line (0)
   lcd.write(byte(0));
   lcd.write(byte(1));
   lcd.write(byte(1));
   lcd.write(byte(2));
   lcd.write(byte(3));
   lcd.write(byte(4));
     
   lcd.setCursor(0, 1);
    for (temp=0; temp <= 16; temp++){
      lcd.print(My_Version[temp]);
      delay(200);
   } 
   delay(1000);       // Delay this time for 3 seconds.
//----------------------------------------------------------------------------- 
   if (single == true){     // If the jumper is true, then display the column 13, first line 1PH.
     lcd.setCursor(11, 0);
     lcd.print("~J1PH");
   } 
   else{
     lcd.setCursor(11, 0);    // Or if the jumper is false To show results at column 13, first line 3PH
     lcd.print("~J3PH");     
   }
 //----------------------------------------------------------------------------  
   lcd.setCursor(0, 0);     // Display the result at column 1, first line. The word Amplitude is waiting for it to come true.
   lcd.print("Amplitude:");
   lcd.setCursor(0, 1);    // Display results at column 1, line 2, word frequency. Wait for the actual value to continue.
   lcd.print("Frequency:");
//-----------------------------------------------------------------------------
 // Go to the program to set up the timer to set up the 3 PWM signal generation using the three Arduino timers. Setup the timers
   setup_timer0();
   setup_timer1();
   setup_timer2(); 
// This part is calculated according to the formula for To complete the waveform signal. Continuous cycle requires a resolution of up to 32 bits and will get the maximum 8-bit secret, but the time must be shifted back to 8 bits.   
  delta = pow(2,32)*freq/refclk ; 
  freq_new = 10;
  freq_old = 5;
  changeFreq_ramp(freq_new);
  freq_new = 11;
  freq_old = 10;
//-----------------------------------------------------------------------------
  digitalWrite(FAULT_DETECT, HIGH);
  pinMode(FAULT_DETECT, INPUT_PULLUP); // Order the set to be the input signal and the pool up
  attachInterrupt(0, fault, LOW);
  digitalWrite(enablePin, HIGH); //Open the Power Drive sector to start working.
  freq_new = map(analogRead(FREQ_POT), POT_MIN, POT_MAX, FREQ_MIN, FREQ_MAX);
  changeFreq_ramp(freq_new);
  freq_old = freq_new;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void loop(){
  if (c4ms == 0){
    digitalWrite(testPin, testPin_status);
    testPin_status = !testPin_status;
    freq_new = map(analogRead(FREQ_POT), POT_MIN, POT_MAX, FREQ_MIN, FREQ_MAX);
    SW_WATER = map(analogRead(WATER), POT_MIN, POT_MAX, 0, 100);
    if (freq_new != freq_old){
        changeFreq(freq_new);
        freq_old = freq_new;
    }
    
    if (SW_WATER >= 25){
      digitalWrite(enablePin, LOW); // Turn off the Power Drive sector to stop working.
        //-------------------Stop waiting until the float switch is open.------------------
        do{
         SW_WATER = map(analogRead(WATER), POT_MIN, POT_MAX, 0, 100);
          lcd.setCursor(10, 1);
          lcd.print("!WAIT ");
          while(c4x10ms){delay(100);}
          lcd.setCursor(10, 1);
          lcd.print("WATER ");
          while(c4x10ms){delay(100);}
        }while (SW_WATER >=25);
        //------------------------------------------------------------
       freq_new = 10;
       freq_old = 5;
       changeFreq_ramp(freq_new);
       freq_new = 11;
       freq_old = 10;  
       digitalWrite(enablePin, HIGH); //Open the Power Drive sector to start working
       freq_new = map(analogRead(FREQ_POT), POT_MIN, POT_MAX, FREQ_MIN, FREQ_MAX);
       changeFreq_ramp(freq_new);
       freq_old = freq_new;   
    }
  }
  delay(100); 
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// Set of instructions to change the frequency
void changeFreq(float _freq){
      temp2 = _freq;
      Amplitude = temp2 + 20;
      if (Amplitude >= MAX_Amplitude){Amplitude = MAX_Amplitude;}  // ล๊อค Amplitude
      lcd.setCursor(10, 0);
      lcd.print(Amplitude);
      lcd.setCursor(10, 1);
      lcd.print(temp2);
      lcd.print(" Hz ");
      cbi (TIMSK2,TOIE2);              // Stop the timer 2 disable timer2 overflow detect
      freq = _freq;
      delta=pow(2,32)*freq/refclk;  // Update the new frequency update phase increment
      sbi (TIMSK2,TOIE2);              //Enable the timer 2 to work enable timer2 overflow detect
      while(c4ms);              
} 
//----------------------------------------------------------------------------
// Command set to change the frequency _RAMP
void changeFreq_ramp(float _freq){
    if (_freq > freq_old){     
        for (temp2 = freq_old; temp2 <= _freq; temp2++){
          Amplitude = temp2 +20;
          if (Amplitude >= MAX_Amplitude){Amplitude = MAX_Amplitude;}  // Lock Amplitude
          lcd.setCursor(10, 0);
          lcd.print(Amplitude);
          lcd.setCursor(10, 1);
          lcd.print(temp2);
          lcd.print(" Hz ");
          cbi (TIMSK2,TOIE2);              // Stop the timer 2  disable timer2 overflow detect
          freq = temp2;
          delta=pow(2,32)*freq/refclk;  // Update the new frequency  update phase increment
          sbi (TIMSK2,TOIE2);              //Enable the timer 2 to work enable timer2 overflow detect
          while(c4ms);          
       }          
    }
    
    if (_freq < freq_old){    
      for (temp2 = freq_old; temp2 >= _freq; temp2--){
         Amplitude = temp2 +20;
         if (Amplitude >= MAX_Amplitude){Amplitude = MAX_Amplitude;}  // Lock Amplitude
         lcd.setCursor(10, 0);
         lcd.print(Amplitude);
         lcd.setCursor(10, 1);
         lcd.print(temp2);
         lcd.print(" Hz ");
         cbi (TIMSK2,TOIE2);              // Stop the timer 2 disable timer2 overflow detect
         freq = temp2;
         delta=pow(2,32)*freq/refclk;  // Update the new frequency update phase increment
         sbi (TIMSK2,TOIE2);              //Enable the timer 2 to work enable timer2 overflow detect
         while(c4ms);              
      }           
   }
} 
//------------------------------------------------------------------------------
// Command set in setting the first timer (0)
// timer0 setup
// set prescaler to 8, PWM mode to phase correct PWM, 16000000/512/8 = 3.9kHz clock
void setup_timer0(void){
// Timer0 Clock Prescaler to :Set the timer to divide another 8 to get the 3.9 Khz PWM frequency to fit the old IPM numbers.
   cbi (TCCR0B, CS00);
   sbi (TCCR0B, CS01);
   cbi (TCCR0B, CS02);   
 
// Timer0 PWM Mode set to Phase Correct PWM
   cbi (TCCR0A, COM0A0); //Set the first transmitter set (OCR0A) to send the signal to normal Sine PWM +
   sbi (TCCR0A, COM0A1);
   sbi (TCCR0A, COM0B0); // Set the first transmitter set (OCR0B) to output the signal as Sine PWM. Return the Invert phase to
   sbi (TCCR0A, COM0B1);
   sbi (TCCR0A, WGM00); //Set all pulse signals to be in the same line in every phase. (Mode 1 / Phase Correct PWM)
   cbi (TCCR0A, WGM01);
   cbi (TCCR0B, WGM02);
}
 
//------------------------------------------------------------------------------
// timer1 setup
// set prescaler to 8, PWM mode to phase correct PWM, 16000000/512/8 = 3.9kHz clock To fit IPM, old numbers
void setup_timer1(void){
// Timer1 Clock Prescaler to :Set the timer to divide another 8 to get the PWM frequency of 3.9 Khz. 
   cbi (TCCR1B, CS10);
   sbi (TCCR1B, CS11);
   cbi (TCCR1B, CS12);
 
// Timer1 PWM Mode set to Phase Correct PWM
   cbi (TCCR1A, COM1A0); // Set to channel 2 (OCR1A) to send signals to normal Sine PWM +
   sbi (TCCR1A, COM1A1);
   sbi (TCCR1A, COM1B0); // Set the channel 2 (OCR1B) to send the signal to Sine PWM. Return the Invert phase to -
   sbi (TCCR1A, COM1B1);
   sbi (TCCR1A, WGM10); //Set all pulse signals to be in the same position in every phase (Mode 1 / Phase Correct PWM)
   cbi (TCCR1A, WGM11);
   cbi (TCCR1B, WGM12);
   cbi (TCCR1B, WGM13);
}
 
//------------------------------------------------------------------------------
// timer2 setup
// set prescaler to 8, PWM mode to phase correct PWM, 16000000/512/8 = 3.9kHz clock To fit IPM, old numbers
void setup_timer2(void){
// Timer1 Clock Prescaler to :Set the timer to divide another 8 to get the PWM frequency of 3.9 Khz.  
   // Timer2 Clock Prescaler to : /8
   cbi (TCCR2B, CS20);
   sbi (TCCR2B, CS21);
   cbi (TCCR2B, CS22);
 
// Timer2 PWM Mode set to Phase Correct PWM
   cbi (TCCR2A, COM2A0); // Set to channel 3 (OCR2A) to send signal to normal Sine PWM +
   sbi (TCCR2A, COM2A1);
   sbi (TCCR2A, COM2B0); //Set the channel 3 (OCR2B) signal to be output to Sine PWM. Return the Invert phase to -
   sbi (TCCR2A, COM2B1);
   sbi (TCCR2A, WGM20); //Set all pulse signals to be in the same position in every phase (Mode 1 / Phase Correct PWM)
   cbi (TCCR2A, WGM21);
   cbi (TCCR2B, WGM22);
}
 
//------------------------------------------------------------------------------
// ส่งInterrupt Service Routine attached to INT0 vector
void fault(){
  digitalWrite(enablePin, LOW); // Order this leg to close (in 0) to make the Power Drive sector not work now
  digitalWrite(testPin, HIGH);
  cbi (TIMSK2,TOIE2);              // Stop the timer operation 2 disable timer2 overflow detect
  OCR0A=0;
  OCR0B=0;
  OCR1A=0;
  OCR1B=0;  
  OCR2A=0;
  OCR2B=0; 
  lcd.clear();
  lcd.setCursor(0, 0); // Order to display column 1 in the first line (0) 
  lcd.print("!!Detect Error!!"); // Display Error
  lcd.setCursor(0, 1); // Order to display the column number 1 on line 2 (1)
  lcd.print(" Pls Switch OFF ");
  while(1){}; // Stop working forever until resetting or turning off the power to enter the new machine.
}
//------------------------------------------------------------------------------
//In order to obtain a wave signal that has a precise frequency as we set it, it takes time to count the time of the timer 2 and when the count is set as we have to follow this set.
// Timer2 Interrupt Service at 31372,550 KHz = 32uSec
// this is the timebase REFCLOCK for the DDS generator
// runtime : 8 microseconds ( inclusive push and pop)
 
ISR(TIMER2_OVF_vect) {
   // The frequency calculation formula returns and moves from 32 bits back to using only 8 bits below. 
  sigma=sigma+delta; // soft DDS, phase accu with 32 bits
  phase0=sigma >> 24;     // use upper 8 bits for phase accu as frequency information
  
   //This instruction set is divided into 2 parts. The first set is to send the signal of the three wave pairs to have different phases, 0-90-180 for use with single-phase motors and subsequent sets for 3-phase 0-120. -120
                         
    if (single == true){      // If the jumper is true To work this part Is single phase                
      phase1 = phase0 +127 ;  // Phase 1 value
      phase2 = phase0 +63 ;  // Phase 2 value
  //For single-phase, dual-phase, phase 0 and phase 1, the pair will reverse for the motor. Rotate the same direction in both singles and 3 phases
  // Bring the value read from the wave grid + signal strength (Amplitude) + Phase + DeadTime value out to all 3 pairs of signal
// OCR0A=(uint8_t)pgm_read_byte_near((Sine_Table + ADD_AMPD) + phase1)+DT_LOW;
      temp_ocr0a = pgm_read_byte_near(Sine_Table + phase1) * (Amplitude) / (TABLE_DIV) + DT_LOW;
      temp_ocr0b = pgm_read_byte_near(Sine_Table + phase1) * (Amplitude) / (TABLE_DIV) + DT_HIGH;
      temp_ocr1a = pgm_read_byte_near(Sine_Table + phase0) * (Amplitude) / (TABLE_DIV) + DT_LOW;
      temp_ocr1b = pgm_read_byte_near(Sine_Table + phase0) * (Amplitude) / (TABLE_DIV) + DT_HIGH;
      temp_ocr2a = pgm_read_byte_near(Sine_Table + phase2) * (Amplitude) / (TABLE_DIV) + DT_LOW;
      temp_ocr2b = pgm_read_byte_near(Sine_Table + phase2) * (Amplitude) / (TABLE_DIV) + DT_HIGH;
      
      OCR0A=(uint8_t) temp_ocr0a;  // pin D6
      OCR0B=(uint8_t) temp_ocr0b;  // pin D5
 
      OCR1A=(uint8_t) temp_ocr1a;  // pin D9
      OCR1B=(uint8_t) temp_ocr1b;  // pin D10
    
      OCR2A=(uint8_t) temp_ocr2a;  // pin D11
      OCR2B=(uint8_t) temp_ocr2b;  // pin D3 
    }
  //---------------------- If the jumper is false To work this part is a 3 phase with 120 different phases------------------------------------------------------------------
    else{
      phase1 = phase0 +85 ;  //  Phase 1 value
      phase2 = phase0 +170 ;   // Phase 2 value
   // Bring the value that can be read from the wave grid + Amplitude + Phase + DeadTime to all 3 pairs of signal
      temp_ocr0a = pgm_read_byte_near(Sine_Table + phase0) * (Amplitude) / (TABLE_DIV) + DT_LOW;
      temp_ocr0b = pgm_read_byte_near(Sine_Table + phase0) * (Amplitude) / (TABLE_DIV) + DT_HIGH;
      temp_ocr1a = pgm_read_byte_near(Sine_Table + phase1) * (Amplitude) / (TABLE_DIV) + DT_LOW;
      temp_ocr1b = pgm_read_byte_near(Sine_Table + phase1) * (Amplitude) / (TABLE_DIV) + DT_HIGH;
      temp_ocr2a = pgm_read_byte_near(Sine_Table + phase2) * (Amplitude) / (TABLE_DIV) + DT_LOW;
      temp_ocr2b = pgm_read_byte_near(Sine_Table + phase2) * (Amplitude) / (TABLE_DIV) + DT_HIGH;
      
      OCR0A=(uint8_t) temp_ocr0a;  // pin D6
      OCR0B=(uint8_t) temp_ocr0b;  // pin D5
 
      OCR1A=(uint8_t) temp_ocr1a;  // pin D9
      OCR1B=(uint8_t) temp_ocr1b;  // pin D10
    
      OCR2A=(uint8_t) temp_ocr2a;  // pin D11
      OCR2B=(uint8_t) temp_ocr2b;  // pin D3       
    }     
   if (c4ms++ == 1000){
     c4ms = 0;
     if (c4x10ms++ == 10){c4x10ms = 0;}
   }
}

 

Can you help me measure dead time and if it works to adjust it?

I cannot go through the program in detail but it appears to be neatly written by people who know...

I cannot make out anything about the comment line # 62...

There are two dead times defined in the program: lines 39 and 40. To change the dead time, you need to change line 39 (you can make 2 into 3 or 4 but not much ...)

You also need to adj the other defined variables (say for example line 42 and 43) etc etc.

Compile and pay attention to all warning too.

Try out with a dummy load and with a small fuse.

(The program was apparently written for a water pump and with a LCD display: you can safely remove these part to make a lean (and mean) program...

Or, instead of the LCD, you can add lots of LEDs...
 

For a realistic simulation, you should use the values for 75Hz and see the effect at 50Hz and 100Hz.

We should also replace the load as an inductor (rather than a resistor). Because the frequency range is rather limited, the effects will be rather small.

Following your recommendations here is the simulated results. The frequency sweeps from 25 to 75 Hz, providing square waves +-560VAC. The result suggests it's feasible to find suitable LC values that deliver sensible power levels to the motor at various rpm's.

I don't know what proportion of the load is inductive, so I guessed at half inductive, half resistive. (Values are selected so the overall draw is 2kW at 50Hz 400VAC sine.)
It was necessary to revise values in the LC shaping filter.

560v sq wave sweep 25-75Hz LC2nd order filter sines to load LR.png

As rpm gets faster, voltage needs to be greater amplitude (as stated in the discussion above). However it seems risky to push too many Amperes through the load. I chose LC values so that less power reaches the load at low rpm and high rpm.
 
However it seems risky to push too many Amperes through the load.

I completely agree with your analysis; motors are basically current dependent devices and at higher effective frequency, the motor can get very hot (both iron and copper losses).

It is better to accept some loss of output brake horse power at double the speed. Particularly if you are planning to run it continuously at full load.

It appears (from visual analysis) that the waveforms seen in the simulation may be acceptable in real life. One filter can work over the range of 50-100 Hz for all practical purposes.
 
w=angular speed is directly related to frequency since rpm=120*f/PolePair (lets not consider slipping)
w=2*pi*rpm/60
w=2*pi*120*(f/PolePair) /60=4*pi*f/Pp

Power=sqrt(3)*V*I=Torque*w
sqrt(3)*V*I=Torque*w
Torque=sqrt(3)*V.I/(4*pi*f/Pp)

At a point you can increase the frequency but can't increase the voltage and that's why you will loose torque.
Check page 2 figure 2.
https://ww1.microchip.com/downloads/cn/AppNotes/cn012129.pdf

If you run a motor (any motor) beyond it's rated speed these are the risks:
1-Bearings can be broken
2-With the reason I explained at start your motor will drawn more current than the winding can sustain.
3-Heat problems
4-Vibrations.

In the end you will loose the motor.

I highly recommend space vector modulation instead carrier based for AC motor applications.

If you really want more speed consider gearboxes.
 

Attachments

  • vfcontrol.JPG
    vfcontrol.JPG
    77.9 KB · Views: 121
Last edited:

2-With the reason I explained at start your motor will drawn more current than the winding can sustain...

Your analysis is broadly accurate but the above statement is misleading.

At higher frequency (w or f, in your formula) the motor will draw lower current (at const voltage)- see the graph in the same reference you gave (page 2, graph 1).

The excessive heating will result from the losses (that are unaccounted in your formula).
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top