Chastotnik escalar para um motor assíncrono monofásico

Para começar, todo programador deve ter um torno. Bem ... Ou, pelo menos, eu tenho que ter. E mesmo sem CNC. Este é o meu sonho.

E o sonho se tornou realidade. A máquina foi comprada, trazida, colocada no estacionamento e ... Seria necessário ligá-la. E ativá-lo não é tão simples. E se você não procurar maneiras simples, precisará de um "chastotnik", mas de maneira científica: um conversor de frequência. E deixe-me ser leigo nisso, mas consegui.



E com a conexão do motor, a diversão começa. Eu mesmo estou em tal ignorância, existe algum conhecimento geral, mas como realmente funciona eu não fazia ideia. E quando, em vez das 3 conclusões esperadas dos 3 phasers, vi 4, e nem mesmo 3 enrolamentos com um ponto comum, mas separamos 2 e até com diferentes resistências ... Bem, eu, ahem, digamos isso - "surpresos".

Então, os motores. Eles são trifásicos, trifásicos, conectados por um triângulo através de capacitores e ... capacitor monofásico.

Trifásico - assíncrono "completo". 3 enrolamentos, em boa forma incluídos por uma estrela e pendurados em 3 fases completas. Bem, ou um chastotnik trifásico, dos quais um eixo em Ali.

Trifásico + triângulo + capacitores. Aqui já estamos perdendo eficiência, potência e torque, bem, se não houver três fases, teremos uma solução para nós mesmos. Barato, simples, confiável, alegre.

Capacitor monofásico

Aqui vamos falar sobre eles. Em geral, esses mecanismos são muito comuns. São ventiladores dos motores e acionamentos de projetores de alguns relógios e motores para pequenas esmeril e outras aplicações em que não é necessária alta potência, mas são necessárias vantagens assíncronas: grande confiabilidade + velocidade, dependendo apenas da frequência da tensão de alimentação.

O esquema básico de inclusão (a imagem não é minha, encontrada honestamente na Internet):



Em geral, grosso modo, o princípio é o seguinte: existe um enrolamento inicial, induz EMF em um rotor de gaiola de esquilo. Com uma mudança de fase, o enrolamento de trabalho é ligado. Ela "empurra" a âncora magnetizada, a rotação começa. Quando você gira para um determinado ângulo, tudo se repete. O motor começa a girar.

Total - você precisa de 2 fases, deslocadas para um determinado ângulo. Geralmente é de 90 graus. Isso é fornecido pelo capacitor de partida. Bem, depois de um conjunto de rotações - a âncora começa a funcionar a partir do enrolamento muito funcional e o enrolamento inicial pode até ser desligado completamente. Bem, ou alimentado por um capacitor de trabalho, uma capacidade muito menor.

Mas isso tudo é uma teoria. Mas, na prática, o que você quer? Eu quero um chastotnik. O que ele iria acelerar, desacelerar, girar em ambas as direções, bem, com velocidades diferentes, é claro! E aqui fica um pouco mais complicado. O fato é que há muitas vezes menos chastotniks à venda. E eles custam muitas vezes mais. Em geral - exótico.

Mas se você pensar dessa maneira, a diferença da fase trifásica não é tão grande. E você pode até usar o mesmo circuito. Ao mesmo tempo, existem as mesmas três torneiras: comum, enrolamento inicial, enrolamento de trabalho. E é tudo sobre o firmware. Então - isso pode ser feito. E que não seja um controle vetorial com um monte de matemática, mas um escalar simples, mas ... como eu puder.

Então - o que é necessário. Primeiro, vejamos os gráficos do seno e do cosseno (temos um deslocamento de 90 graus). CONVENÇÃO Ela ficará assim:



I.e. a tarefa é elementar: “puxamos” o general para o chão, alimentamos um pacote de pulsos positivos no enrolamento inicial, alimentamos um pacote de pulsos no trabalhador. Depois, puxamos o general para o positivo e alimentamos um pacote de impulsos negativos para o iniciador e depois o enrolamento de trabalho. T.O. mais ou menos, temos uma imitação de uma mudança de polaridade e uma mudança de fase. De quantas vezes faremos isso, a "frequência" dependerá.

Em geral, a teoria é simples. Como um controlador ATMega 328 com um gerenciador de inicialização, arduins (sim, de fato, o próprio arduina, apenas sem correias desnecessárias), como um driver IR2132 (antigo, mas não funcionou com o IR2136) e as chaves de saída IRG4BC30. Para o meu motor de 1,1 kW, isso é mais do que suficiente.

(Se você repetir o diagrama, apenas a placa está pronta, um esboço é derramado no Arduino Duemilanove, o Mega328 é retirado e soldado na placa. Feito.)

E daqui em diante ... Além disso, mergulhei no maravilhoso mundo das indutâncias e da eletrônica de potência. E tudo acabou não sendo tão simples como se pensava no começo:

1. A velocidade de abertura e fechamento das teclas é importante. Deadtime é MUITO importante.
2. Ligar o reator - obrigatório usando um diodo, voltado para o sinal de mais no capacitor de filtragem de energia. Caso contrário, as descargas durante o descarregamento da indutância às vezes desativam os IGBTs de energia.
3. Resfriamento. Pequenos radiadores no painel estão ruins. Ou superaquece, ou você precisa explodi-lo. Mas se você explodir, toda a suspensão de metal da máquina, mais cedo ou mais tarde, entrará em curto-circuito com alguma coisa e haverá um estrondo.
3+.Mica, ou melhor, MUITO FINAL, é ruim. Faz o seu caminho e acontece que no título do artigo. Ao mesmo tempo, as almofadas térmicas de silicone são piores em condutividade térmica. Mas cerâmica ... eu não tenho.
4. Ao travar pelo método de uma longa explosão de pulsos da mesma polaridade em um enrolamento, os transistores superaquecem rapidamente e queimam. E também, o motor salta muito divertido, girando até 3 mil rotações e parou por 0,3 segundos a 0.
5. Quando tudo funcionar e você relaxar, ligue o circuito sem reator e pressione start - haverá um estrondo. Isso também leva à substituição do driver.

Esboço:Agora, a rotação nas duas direções com uma sintonia suave da frequência de 25-75 Hz com um passo de 0,25 é implementada. Havia uma ideia com um freio. Agora está comentado e será necessário alterar o esquema. Ou seja, a idéia é a seguinte: apliquei corretamente impulsos da mesma polaridade, MAS. Isso deve ser feito através do reator com uma chave separada.

Parte de energia: o circuito ainda estará finalizado, mas no momento a máquina está em uma sala sem aquecimento e é extremamente difícil trabalhar com ela devido ao congelamento de óleo.

Esboço
#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;
}


Esquema:
imagem
Em geral, quase um clássico, mas montado a partir de 5 esquemas diferentes. Diodos nos ombros "altos", em geral, ao usar transistores IGBT, não são necessários, mas eu o fiz primeiro e depois pensei apenas

como resultado: funciona. Muito ainda precisa ser concluído, por exemplo, um "controle remoto" externo, um freio. Pode valer a pena experimentar a duração do pulso ou fazer um PWM completo simulando um seno, em vez de um ciclo de trabalho constante. Mas por enquanto é assim. Talvez alguém venha a calhar.

E, no final, gostaria de perguntar: em vez de lastro, dou um estrangulamento, "preso" por diodos. Quão errado estou nessa decisão? Choke, eu nem sei que indutância. Retirado do ATX PSU, onde ficava na unidade de compensação de potência reativa.

Bem, a experiência ... A experiência é muito interessante. Eu nunca teria pensado que poderia ser tão difícil. E esses 30V e 300V são uma enorme diferença. Eu realmente respeito as pessoas que projetam essas coisas.
E esse é o preço dos meus erros: você



pode assistir ao vídeo de todo o processo aqui: 1 2 3

Perguntas para os que têm mais conhecimento, gostaria de ver os comentários:

1. O acelerador que fica no circuito +310. Devo me livrar dele? Defino isso na esperança de que o aumento de corrente, no caso de corrente contínua, seja mais lento e o motorista tenha tempo para entrar na proteção de corrente.

2. Recebo pulsos do mesmo ciclo de trabalho. Isso é crítico? Sair ou ainda fazer algo "dependente de seio" no ciclo de trabalho?

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


All Articles