单相异步电动机的标量chastotnik

首先,每个程序员都必须拥有一台车床。好吧……或者至少,我必须拥有它。甚至没有CNC。这是我的梦想。

梦想成真。购买了机器,将其带入停车场,然后放...开启它。而且打开它并不是那么简单。而且,如果您不寻找简单的方法,那么您需要一个“ chastotnik”,而是一种科学的方法:变频器。让我成为一个外行,但我做到了。



通过引擎的连接,乐趣就开始了。我本人是一个无知的人,有一些常识,但是它如何真正起作用我不知道。当我没有看到3个移相器的预期3个结论时,看到了4个,甚至没有3个具有相同点的绕组,而是看到了2个绕组,甚至具有不同的电阻……我,嗯,让我们这样说-“感到惊讶”。

因此,引擎。它们是三相,三相,通过电容器和…单相电容器通过三角形连接。

三相 -“完全”异步。 3个绕组,以星的形式很好地包含在整个3相中。好吧,或者说是三相Chastotnik,其中一个轴放在Ali身上。

三相+三角形+电容器。在这里,我们已经失去了效率,功率和扭矩,如果没有三相,那么我们将为自己找到解决方案。便宜,简单,可靠,开朗。

单相电容器

这里我们将讨论它们。通常,这样的引擎非常普遍。这些是投影仪的电动机和某些手表的驱动器的风扇,以及小型金刚砂和其他不需要高功率但需要异步器的电动机:巨大的可靠性+速度,仅取决于电源电压的频率。

包含的基本方案(图片并非我的,在互联网上可以找到):



一般而言,原理是这样的:有一个起动绕组,它在鼠笼形转子中感应出一个电动势。通过相移,工作绕组接通。她“按下”磁化的锚,旋转开始。当您转向某个角度时,一切都会重复。电机开始旋转。

总计-您需要2个阶段,并移至某个角度。通常是90度。这由启动电容器提供。好了,经过一系列旋转-锚从非常有效的绕组开始工作,而起动机绕组甚至可以完全关闭。好了,或者由工作电容器供电,容量要小得多。

但这全都是理论。但是实际上,您想要什么?我想要一个chastotnik。它会自动加速,减速,向两个方向旋转,当然,它们的速度会有所不同!在这里,它变得更加复杂。事实是,这样的chastotniks出售的数量要少很多倍。而且它们的成本要高出许多倍。一般来说-异国情调。

但是,如果您以这种方式考虑,那么与三相的区别就不会太大。您甚至可以使用相同的电路。同时,共有3个抽头:通用,起动绕组,工作绕组。一切都与固件有关。所以-这可以做到。并使其不是具有大量数学的矢量控件,而是一个简单的标量,但是...尽我所能。

所以-需要什么。首先,让我们看一下正弦和余弦的图形(我们有90度的偏移量)。惯例它看起来像这样:



即这项任务很基本:我们将大将军“拉”到地面,将一包正脉冲馈入起动机绕组,将一包脉冲馈入工人。然后,我们将通用拉到正,并将一包负脉冲馈入起动器,然后馈入工作绕组。 T.O.大致上,我们得到了极性变化和相移的模仿。从我们执行此操作的频率来看,“频率”将取决于。

通常,该理论很简单。作为带有引导加载程序的ATMega 328控制器,arduins(是的,arduina本身,只是没有太多的捆扎),IR2132驱动程序(旧的,但不能与IR2136配合使用)和IRG4BC30输出键。对于我的1.1 kW电机,这已经绰绰有余。

(如果重复该方案,则只需完成电路板,将草图倒入Arduino Duemilanove,然后将Mega328拔出并焊接到电路板中。)

在此之后……此外,我陷入了电感和电力电子的奇妙世界。事实证明,一切都不像开始时想象的那么简单:

1 .打开和关闭琴键的速度很重要。停滞时间非常重要。
2.打开镇流器-必须使用一个二极管,面对电源滤波电容器的正极。否则,电感卸载期间的放电有时会禁用功率IGBT。
3.冷却。板上的小散热器不好。要么过热,要么需要吹。但是,如果吹动它,则机器上的整个金属悬架迟早会短路某些东西,并且会发出爆炸声。
3+。云母,或者说非常薄的云母是不好的。它按照自己的方式行事,结果在文章标题中有所说明。同时,硅树脂导热垫的导热性较差。但是陶瓷...我没有。
4.通过在一个绕组上长脉冲串极性相同的脉冲来制动,晶体管迅速过热并烧毁。而且,电动机跳起来很有趣,旋转最多3千转,并在0.3秒内停止为0。5
当一切正常且放松时,不加镇流器就打开电路,然后按开始-会有砰的一声。这也导致更换驱动程序。

草图:现在实现了以0.25步进平滑调谐25-75 Hz频率的双向旋转。有一个想法,刹车。现在已被注释掉,有必要更改该方案。即,想法是这样的:我正确地施加了相同极性的脉冲,但。必须通过镇流器用单独的钥匙完成此操作。

动力部分:电路仍将最终确定,但此刻机器处于未加热的房间内,由于油冻结,使用它非常困难。

草绘
#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;
}


方案:
图片
通常,这几乎是经典方案,但由5种不同方案组成。通常,在使用IGBT晶体管时,“高”肩上的二极管不是必需的,但是我首先这样做,然后才想到

它可以工作。仍然需要完成很多工作,例如,外部“遥控器”,制动器。可能需要对脉冲持续时间进行实验,或者使用完整的PWM模拟正弦,而不是恒定的占空比。但是现在是这样。也许有人会派上用场。

最后,我想问:我用二极管“钳”住了一个扼流圈,而不是镇流器。这样的决定我有多错误? oke,我什至不知道电感是多少。取自位于无功补偿单元中的ATX PSU。

好吧,体验...体验非常有趣。我永远都不会想到这可能会如此困难。而且30V和300V是巨大的差异。我真的很尊重设计这类东西的人。
这就是我犯错的代价:您



可以在这里观看整个过程的视频:1 2 3

对于知识渊博的问题,我希望看到以下评论:

1.位于+310电路上的油门。我应该摆脱他吗?我设置它的目的是希望在直通电流的情况下,电流的增加会更慢,并且驱动器将有时间进入电流保护。

2.我得到相同占空比的脉冲。这很关键吗?离开,还是在占空比上做一些“与窦有关的事情”?

Source: https://habr.com/ru/post/zh-CN399357/


All Articles