Skalar chastotnik untuk motor asinkron fase tunggal

Untuk memulainya, setiap programmer harus memiliki mesin bubut. Ya ... Atau, setidaknya, saya harus memilikinya. Dan bahkan tanpa CNC. Ini adalah mimpiku.

Dan mimpi itu menjadi kenyataan. Mesin itu dibeli, dibawa, dimasukkan ke tempat parkir dan ... Itu perlu untuk menyalakannya. Dan menyalakannya tidak begitu sederhana. Dan jika Anda tidak mencari cara sederhana, maka Anda memerlukan "chastotnik", tetapi secara ilmiah: konverter frekuensi. Dan biarkan saya menjadi orang awam dalam hal ini, tetapi saya berhasil.



Dan dengan koneksi mesin, kesenangan dimulai. Saya sendiri dalam kebodohan seperti itu, ada beberapa pengetahuan umum, tetapi bagaimana cara kerjanya sebenarnya saya tidak tahu. Dan ketika, bukannya 3 kesimpulan yang diharapkan dari 3 phasers, saya melihat 4, dan bahkan 3 belitan dengan titik yang sama, tetapi memisahkan 2, dan bahkan dengan resistensi yang berbeda ... Nah, saya, ahem, katakanlah ini - "terkejut."

Jadi, mesinnya. Mereka adalah tiga fase, tiga fase, dihubungkan oleh segitiga melalui kapasitor dan ... kapasitor fase tunggal.

Tiga fase - "penuh" tidak sinkron. 3 gulungan, dengan cara yang baik dimasukkan oleh bintang dan digantung dalam 3 fase penuh. Nah, atau chastotnik 3-fase, yang poros pada Ali.

Tiga fase + segitiga + kapasitor. Di sini kita sudah kehilangan efisiensi, tenaga, dan torsi, yah, jika tidak ada 3 fase, maka kita punya solusi untuk diri kita sendiri. Murah, sederhana, dapat diandalkan, ceria.

Kapasitor satu fase

Di sini kita akan membicarakannya. Secara umum, mesin seperti itu sangat umum. Ini adalah penggemar motor proyektor dan drive dari beberapa jam tangan, dan motor untuk aplikasi kecil dan aplikasi lain di mana daya tinggi tidak diperlukan, tetapi plus asinkronisasi diperlukan: keandalan besar + kecepatan, tergantung hanya pada frekuensi tegangan suplai.

Skema dasar inklusi (gambar itu bukan milik saya, jujur โ€‹โ€‹ditemukan di Internet):



Secara umum, kira-kira, prinsipnya adalah ini: Ada belitan starter, itu menginduksi EMF dalam rotor sangkar-tupai. Dengan pergeseran fasa, belitan yang bekerja dihidupkan. Dia "mendorong" jangkar magnet, rotasi dimulai. Ketika Anda beralih ke sudut tertentu, semuanya terulang. Motor mulai berputar.

Total - Anda perlu 2 fase, bergeser ke sudut tertentu. Biasanya 90 derajat. Ini disediakan oleh kapasitor awal. Nah, setelah serangkaian revolusi - jangkar mulai bekerja dari belitan yang sangat bekerja dan belitan starter bahkan dapat dimatikan sama sekali. Nah, atau ditenagai oleh kapasitor yang bekerja, kapasitas yang jauh lebih kecil.

Tapi ini semua hanya teori. Tetapi dalam praktiknya, apa yang Anda inginkan? Saya ingin chastotnik. Apa yang dipercepatnya, melambat, berputar di kedua arah, tentu saja, dengan kecepatan yang berbeda, tentu saja! Dan ini sedikit lebih rumit. Faktanya adalah bahwa ada banyak kali lebih sedikit chastotnik yang dijual. Dan harganya jauh lebih mahal. Secara umum - eksotis.

Tetapi jika Anda memikirkannya dengan cara ini, maka perbedaan dari 3 fase tidak begitu besar. Dan Anda bahkan dapat menggunakan sirkuit yang sama. Pada saat yang sama, ada 3 ketukan yang sama: umum, belitan starter, belitan kerja. Dan itu semua tentang firmware. Jadi - ini bisa dilakukan. Dan biarlah itu bukan kontrol vektor dengan banyak matematika, tetapi skalar sederhana, tapi ... yang saya bisa.

Jadi - apa yang dibutuhkan. Pertama, mari kita lihat grafik sinus dan cosinus (kita memiliki offset 90 derajat). KONVENSI akan terlihat seperti ini:



Yaitu tugasnya sederhana: kita "menarik" jendral ke tanah, memberi makan satu paket pulsa positif ke belitan pemula, memberi makan satu paket pulsa ke pekerja. Kemudian kami menarik jendral ke plus dan memberi makan paket impuls negatif ke starter, dan kemudian bekerja berliku. T.O. kira-kira kita mendapatkan tiruan dari perubahan polaritas dan pergeseran fase. Dari seberapa sering kita akan melakukan ini, "frekuensi" akan tergantung.

Secara umum, teorinya sederhana. Sebagai pengontrol ATMega 328 dengan bootloader, arduins (ya, sebenarnya arduina itu sendiri, hanya tanpa terlalu banyak pengikat), driver IR2132 (lawas, tetapi tidak berhasil dengan IR2136) dan kunci output IRG4BC30. Untuk motor 1.1 kW saya ini lebih dari cukup.

(Jika Anda mengulangi skema, maka hanya papan selesai, sketsa dituangkan ke dalam Arduino Duemilanove, maka Mega328 ditarik keluar dan disolder ke papan. Selesai.)

Dan selanjutnya ... Selanjutnya, saya terjun ke dunia induktansi dan elektronika daya yang indah. Dan semuanya ternyata tidak sesederhana yang diperkirakan di awal:

1. Kecepatan membuka dan menutup kunci adalah penting. Waktu mati SANGAT penting.
2. Menghidupkan balast - wajib menggunakan dioda, menghadap ke plus pada kapasitor filter daya. Jika tidak, pelepasan selama pembongkaran induktansi kadang-kadang menonaktifkan IGBT daya.
3. Pendinginan. Radiator kecil di papan tidak baik. Entah itu terlalu panas, atau Anda perlu meledakkannya. Tetapi jika Anda meledakkannya, maka seluruh suspensi logam dari mesin, cepat atau lambat, akan menyebabkan hubungan pendek sesuatu dan akan ada ledakan.
3+.Mika, atau lebih tepatnya SANGAT TIPIS, adalah buruk. Itu membuat jalannya dan ternyata itu dalam judul artikel. Pada saat yang sama, bantalan termal silikon lebih buruk dalam konduktivitas termal. Tapi keramik ... aku tidak memilikinya.
4. Pengereman dengan metode semburan pulsa panjang dengan polaritas yang sama pada satu belitan, transistor dengan cepat menjadi terlalu panas dan terbakar. Dan juga, motor melompat dalam banyak kesenangan, berputar hingga 3 ribu putaran dan berhenti selama 0,3 detik menjadi 0.
5. Ketika semuanya bekerja dan Anda santai, nyalakan sirkuit tanpa pemberat dan tekan start - akan ada ledakan. Ini juga mengarah pada penggantian pengemudi.

Sketsa:Sekarang rotasi di kedua arah dengan penyempurnaan frekuensi 25-75 Hz dengan langkah 0,25 diterapkan. Ada ide dengan rem. Sekarang sudah dikomentari dan akan perlu untuk mengubah skema. Yaitu, idenya adalah ini: Saya menerapkan impuls dengan polaritas yang sama, TETAPI. Ini harus dilakukan melalui pemberat dengan kunci terpisah.

Bagian daya: sirkuit masih akan diselesaikan, tetapi saat ini mesin berada di ruang yang tidak dipanaskan dan sangat sulit untuk bekerja dengannya karena pembekuan minyak.

Sketsa
#define Hi_ST 10    //
#define Hi_WK 11    //
#define Hi_M 12    //
#define Lo_ST 7
#define Lo_WK 8
#define Lo_M 9
#define SoftStart 6 //   
#define RelBrake 1

#define LedFwd 4  // ""
#define LedRew 5  // ""
#define LedStp 13 // 
#define CmdFwd 2 // ""
#define CmdRew 3 // ""   - .

#define ValFwd 4 // "" 720
#define ValRew 5 // "" 450

#define RemoteVal 0 //720 + 450 .   . 1.2         750,  1.5

int nn = 0;  //  (    " ")
byte WkState = 0;
byte OldRemVal = 0; //   

int SoftStartMotor = 0; //     .

void setup() 
{   

  pinMode(CmdFwd, INPUT);
  pinMode(CmdRew, INPUT);
  
  pinMode(Hi_ST, OUTPUT);
  pinMode(Hi_WK, OUTPUT);
  pinMode(Hi_M, OUTPUT);
  pinMode(Lo_ST, OUTPUT);
  pinMode(Lo_WK, OUTPUT);
  pinMode(Lo_M, OUTPUT);
  pinMode(SoftStart, OUTPUT);
  pinMode(RelBrake, OUTPUT);
  
  pinMode(LedFwd, OUTPUT);
  pinMode(LedRew, OUTPUT);
  pinMode(LedStp, OUTPUT);

  digitalWrite(RelBrake, LOW);
  AllOff();

  delay(1500);
  digitalWrite(SoftStart, HIGH);
  Indicate();
}


void loop() 
{

  byte CurRemVal = 0;
  int RemVal = analogRead(RemoteVal);
  if (RemVal > 380 && RemVal < 520)
    { CurRemVal = 2; }

  if (RemVal > 600 && RemVal < 800)
    { CurRemVal = 1; }

  //
  bool cmdF = digitalRead(CmdFwd);
  bool cmdR = digitalRead(CmdRew);

  
  if (CurRemVal != OldRemVal)
  {
    OldRemVal = CurRemVal;
    if (CurRemVal == 0) {cmdF = true; cmdR = true;}
    if (CurRemVal == 1) {cmdF = true; cmdR = false;}
    if (CurRemVal == 2) {cmdF = false; cmdR = true;}
  }

  if (cmdF && !cmdR) 
  {
    if(WkState != 1 && nn > 0)
    {
      WkState = 1; //  .     ,     .
      Indicate();
      Brake(); //
    }
    WkState = 1; //       .   .
    Indicate();
  }
  if (!cmdF && cmdR)
  {
    if(WkState != 2 && nn > 0)
    {
      WkState = 2;
      Indicate();
      Brake(); //
    }
    WkState = 2;
    Indicate();
    
  }
  if (cmdF && cmdR)
  {
    if(WkState != 0)
    {
      WkState = 0;
      Indicate();
      Brake(); //
    }
    Indicate();
    WkState = 0;
  }
  
  //
  if (WkState == 0) //
  {
    SoftStartMotor = 0;
    nn = 0;
    delay(50);
    return;
  }

  nn ++; //  (    " ")
  SoftStartMotor += 15; //  ,   .
  
  if (nn > 30000) nn = 30000; 
  if (SoftStartMotor > 1200) SoftStartMotor = 1200;

  if (WkState == 1) //
  {
    int delays = GetDelayByVal(min(1024-analogRead(ValFwd),SoftStartMotor)); //   . , ... 
    RotateFwd(delays-400);
  }
  else //
  {
    int delays = GetDelayByVal(min(analogRead(ValRew),SoftStartMotor));
    RotateRew(delays-400 );
  }
}

// .  
void RotateFwd(int delays)
{
  digitalWrite(Lo_M, !HIGH); //  
  SendPosST(delays);
  delayMicroseconds(100);
  SendPosWK(delays);
  digitalWrite(Lo_M, !LOW); //  . 
  
  delayMicroseconds(100); // 
  
  digitalWrite(Hi_M, !HIGH);
  SendNegST(delays);
  delayMicroseconds(100);
  SendNegWK(delays);
  digitalWrite(Hi_M, !LOW);

  delayMicroseconds(60);
}

// .  
void RotateRew(int delays)
{
  digitalWrite(Lo_M, !HIGH); //  
  SendPosST(delays);
  digitalWrite(Lo_M, !LOW); //  . 

  delayMicroseconds(100);
  digitalWrite(Hi_M, !HIGH);
  SendNegWK(delays);  
  delayMicroseconds(100);
  SendNegST(delays);
  digitalWrite(Hi_M, !LOW);

  delayMicroseconds(100);
  digitalWrite(Lo_M, !HIGH); //  
  SendPosWK(delays);
  digitalWrite(Lo_M, !LOW); //  .

  delayMicroseconds(60);
}

//  
void SendPulse(int pin, int delays) 
{

/*
digitalWrite(pin, !HIGH);
MyDelay(delays);
digitalWrite(pin, !LOW);
*/

byte pwrCycle = 0;
  while(delays > 0) //  ,      
  {
    pwrCycle ++;
    if (delays < 0)
      return;
    if (delays < 300) //   300,   .
    {
      delayMicroseconds(delays);
      return;
    }
    
    if (pwrCycle < 5){  digitalWrite(pin, !HIGH);}
    delayMicroseconds(min(1200,delays));  // . 1200
    digitalWrite(pin, !LOW);
    
    if (delays < 300)//   300,   .
    {
      delayMicroseconds(delays);
      return;
    }

    delayMicroseconds(200); 
    delays -= 1400; //  
  }
}

void SendPosWK(int delays)
{
  SendPulse(Hi_WK,delays);
}
void SendNegWK(int delays)
{
  SendPulse(Lo_WK,delays);
}
void SendPosST(int delays)
{
  if (nn < 100) // 
  { SendPulse(Hi_ST,delays); } 
  else
  { 
    if (delays > 2000) //   -    25% 
    {
      SendPulse(Hi_ST,2000);
      delayMicroseconds(delays - 2000);
    }
    else
    {
      SendPulse(Hi_ST,delays);
      //delayMicroseconds(delays); //  ,   100%   -     1-2  
    }
  }
}
void SendNegST(int delays)
{
  if (nn < 100) // 
  { SendPulse(Lo_ST,delays); } 
  else
  {
    if (delays > 2000)
    {
      SendPulse(Lo_ST,2000);
      delayMicroseconds(delays - 2000);
    }
    else
    {
      SendPulse(Hi_ST,delays);
    }
  }
}

//    .       ,      .
void Brake()
{
  digitalWrite(LedStp, 1);
  AllOff();
  digitalWrite(RelBrake, HIGH);
  delay(1600);
  digitalWrite(RelBrake, LOW);
  delay(300);
  return;

  //Serial.println("Brake");
}

void AllOff()
{
  digitalWrite(Hi_ST, !LOW);
  digitalWrite(Hi_WK, !LOW);
  digitalWrite(Hi_M, !LOW);
  digitalWrite(Lo_ST, !LOW);
  digitalWrite(Lo_WK, !LOW);
  digitalWrite(Lo_M, !LOW);
  delayMicroseconds(300);
}

void Indicate()
{
  digitalWrite(LedStp, (WkState == 0 ? 1:0));
  digitalWrite(LedFwd, (WkState == 1 ? 1:0));
  digitalWrite(LedRew, (WkState == 2 ? 1:0));
}

// 25  75   0.25  511 ( ) = 50
int GetDelayByVal(int val)
{
  if (val < 5) return 10000;
  if (val < 10) return 9900;
  if (val < 15) return 9803;
  if (val < 20) return 9708;
  if (val < 25) return 9615;
  if (val < 30) return 9523;
  if (val < 35) return 9433;
  if (val < 40) return 9345;
  if (val < 45) return 9259;
  if (val < 50) return 9174;
  if (val < 55) return 9090;
  if (val < 60) return 9009;
  if (val < 65) return 8928;
  if (val < 70) return 8849;
  if (val < 76) return 8771;
  if (val < 81) return 8695;
  if (val < 86) return 8620;
  if (val < 91) return 8547;
  if (val < 96) return 8474;
  if (val < 101) return 8403;
  if (val < 106) return 8333;
  if (val < 111) return 8264;
  if (val < 116) return 8196;
  if (val < 121) return 8130;
  if (val < 126) return 8064;
  if (val < 131) return 8000;
  if (val < 136) return 7936;
  if (val < 141) return 7874;
  if (val < 147) return 7812;
  if (val < 152) return 7751;
  if (val < 157) return 7692;
  if (val < 162) return 7633;
  if (val < 167) return 7575;
  if (val < 172) return 7518;
  if (val < 177) return 7462;
  if (val < 182) return 7407;
  if (val < 187) return 7352;
  if (val < 192) return 7299;
  if (val < 197) return 7246;
  if (val < 202) return 7194;
  if (val < 207) return 7142;
  if (val < 212) return 7092;
  if (val < 217) return 7042;
  if (val < 223) return 6993;
  if (val < 228) return 6944;
  if (val < 233) return 6896;
  if (val < 238) return 6849;
  if (val < 243) return 6802;
  if (val < 248) return 6756;
  if (val < 253) return 6711;
  if (val < 258) return 6666;
  if (val < 263) return 6622;
  if (val < 268) return 6578;
  if (val < 273) return 6535;
  if (val < 278) return 6493;
  if (val < 283) return 6451;
  if (val < 288) return 6410;
  if (val < 294) return 6369;
  if (val < 299) return 6329;
  if (val < 304) return 6289;
  if (val < 309) return 6250;
  if (val < 314) return 6211;
  if (val < 319) return 6172;
  if (val < 324) return 6134;
  if (val < 329) return 6097;
  if (val < 334) return 6060;
  if (val < 339) return 6024;
  if (val < 344) return 5988;
  if (val < 349) return 5952;
  if (val < 354) return 5917;
  if (val < 359) return 5882;
  if (val < 364) return 5847;
  if (val < 370) return 5813;
  if (val < 375) return 5780;
  if (val < 380) return 5747;
  if (val < 385) return 5714;
  if (val < 390) return 5681;
  if (val < 395) return 5649;
  if (val < 400) return 5617;
  if (val < 405) return 5586;
  if (val < 410) return 5555;
  if (val < 415) return 5524;
  if (val < 420) return 5494;
  if (val < 425) return 5464;
  if (val < 430) return 5434;
  if (val < 435) return 5405;
  if (val < 441) return 5376;
  if (val < 446) return 5347;
  if (val < 451) return 5319;
  if (val < 456) return 5291;
  if (val < 461) return 5263;
  if (val < 466) return 5235;
  if (val < 471) return 5208;
  if (val < 476) return 5181;
  if (val < 481) return 5154;
  if (val < 486) return 5128;
  if (val < 491) return 5102;
  if (val < 496) return 5076;
  if (val < 501) return 5050;
  if (val < 506) return 5025;
  if (val < 512) return 5000;
  if (val < 517) return 4975;
  if (val < 522) return 4950;
  if (val < 527) return 4926;
  if (val < 532) return 4901;
  if (val < 537) return 4878;
  if (val < 542) return 4854;
  if (val < 547) return 4830;
  if (val < 552) return 4807;
  if (val < 558) return 4784;
  if (val < 563) return 4761;
  if (val < 568) return 4739;
  if (val < 573) return 4716;
  if (val < 578) return 4694;
  if (val < 583) return 4672;
  if (val < 588) return 4651;
  if (val < 593) return 4629;
  if (val < 599) return 4608;
  if (val < 604) return 4587;
  if (val < 609) return 4566;
  if (val < 614) return 4545;
  if (val < 619) return 4524;
  if (val < 624) return 4504;
  if (val < 629) return 4484;
  if (val < 634) return 4464;
  if (val < 640) return 4444;
  if (val < 645) return 4424;
  if (val < 650) return 4405;
  if (val < 655) return 4385;
  if (val < 660) return 4366;
  if (val < 665) return 4347;
  if (val < 670) return 4329;
  if (val < 675) return 4310;
  if (val < 680) return 4291;
  if (val < 686) return 4273;
  if (val < 691) return 4255;
  if (val < 696) return 4237;
  if (val < 701) return 4219;
  if (val < 706) return 4201;
  if (val < 711) return 4184;
  if (val < 716) return 4166;
  if (val < 721) return 4149;
  if (val < 727) return 4132;
  if (val < 732) return 4115;
  if (val < 737) return 4098;
  if (val < 742) return 4081;
  if (val < 747) return 4065;
  if (val < 752) return 4048;
  if (val < 757) return 4032;
  if (val < 762) return 4016;
  if (val < 768) return 4000;
  if (val < 773) return 3984;
  if (val < 778) return 3968;
  if (val < 783) return 3952;
  if (val < 788) return 3937;
  if (val < 793) return 3921;
  if (val < 798) return 3906;
  if (val < 803) return 3891;
  if (val < 808) return 3875;
  if (val < 814) return 3861;
  if (val < 819) return 3846;
  if (val < 824) return 3831;
  if (val < 829) return 3816;
  if (val < 834) return 3802;
  if (val < 839) return 3787;
  if (val < 844) return 3773;
  if (val < 849) return 3759;
  if (val < 855) return 3745;
  if (val < 860) return 3731;
  if (val < 865) return 3717;
  if (val < 870) return 3703;
  if (val < 875) return 3690;
  if (val < 880) return 3676;
  if (val < 885) return 3663;
  if (val < 890) return 3649;
  if (val < 896) return 3636;
  if (val < 901) return 3623;
  if (val < 906) return 3610;
  if (val < 911) return 3597;
  if (val < 916) return 3584;
  if (val < 921) return 3571;
  if (val < 926) return 3558;
  if (val < 931) return 3546;
  if (val < 936) return 3533;
  if (val < 942) return 3521;
  if (val < 947) return 3508;
  if (val < 952) return 3496;
  if (val < 957) return 3484;
  if (val < 962) return 3472;
  if (val < 967) return 3460;
  if (val < 972) return 3448;
  if (val < 977) return 3436;
  if (val < 983) return 3424;
  if (val < 988) return 3412;
  if (val < 993) return 3401;
  if (val < 998) return 3389;
  if (val < 1003) return 3378;
  if (val < 1008) return 3367;
  if (val < 1013) return 3355;
  if (val < 1018) return 3344;
  if (val < 1024) return 3333;
}


Skema:
gambar
Secara umum, hampir klasik, tetapi disusun dari 5 skema berbeda. Dioda pada bahu "tinggi", secara umum, ketika menggunakan transistor IGBT, tidak perlu, tetapi saya melakukannya terlebih dahulu, dan kemudian hanya berpikir

Sebagai hasilnya: ia bekerja. Masih banyak yang harus diselesaikan, misalnya, "remote control" eksternal, rem. Mungkin patut bereksperimen dengan durasi pulsa atau membuat PWM lengkap mensimulasikan sinus, daripada siklus tugas yang konstan. Tapi untuk saat ini begitu. Mungkin seseorang akan berguna.

Dan pada akhirnya, saya ingin bertanya: alih-alih pemberat, saya meletakkan choke, "dijepit" oleh dioda. Betapa salahnya saya dalam keputusan seperti itu? Choke, aku bahkan tidak tahu induktansi apa. Diambil dari PSU ATX, di mana ia berdiri di unit kompensasi daya reaktif.

Nah, pengalamannya ... Pengalamannya sangat menarik. Saya tidak akan pernah berpikir bahwa itu bisa sangat sulit. Dan bahwa 30V dan 300V adalah perbedaan besar. Saya sangat menghargai orang yang mendesain hal-hal seperti itu.
Dan ini adalah harga kesalahan saya: Anda



dapat menonton video seluruh proses di sini: 1 2 3

Pertanyaan untuk yang lebih berpengetahuan, saya ingin melihat komentar:

1. Throttle yang berdiri di sirkuit +310. Haruskah aku menyingkirkannya? Saya mengaturnya dengan harapan bahwa peningkatan arus, dalam hal arus-lewat, akan lebih lambat dan pengemudi akan memiliki waktu untuk masuk ke perlindungan saat ini.

2. Saya mendapatkan pulsa dari siklus tugas yang sama. Apakah ini penting? Tinggalkan, atau masih melakukan sesuatu "tergantung sinus" dalam siklus tugas?

Source: https://habr.com/ru/post/id399357/


All Articles