Chastotnik scalaire pour un moteur asynchrone monophasé

Pour commencer, chaque programmeur doit avoir un tour. Eh bien ... Ou, au moins, je dois l'avoir. Et mĂȘme sans CNC. Ceci est mon rĂȘve.

Et le rĂȘve est devenu rĂ©alitĂ©. La machine a Ă©tĂ© achetĂ©e, amenĂ©e, mise sur le parking et ... Il faudrait l'allumer. Et l'activer n'est pas si simple. Et si vous ne cherchez pas des moyens simples, alors vous avez besoin d'un "chastotnik", mais de maniĂšre scientifique: un convertisseur de frĂ©quence. Et laissez-moi ĂȘtre un profane dans ce domaine, mais je l'ai fait.



Et avec la connexion du moteur, le plaisir commence. Je suis moi-mĂȘme dans un tel ignorant, il y a des connaissances gĂ©nĂ©rales, mais comment cela fonctionne vraiment, je n'en avais aucune idĂ©e. Et quand, au lieu des 3 conclusions attendues des 3 phaseurs, j'ai vu 4, et mĂȘme pas 3 enroulements avec un point commun, mais 2 sĂ©parĂ©s, et mĂȘme avec une rĂ©sistance diffĂ©rente ... Eh bien, moi, ahem, disons ceci - "surpris".

Donc, les moteurs. Ils sont triphasés, triphasés, reliés par un triangle à travers des condensateurs et ... un condensateur monophasé.

Triphasé - "complet" asynchrone. 3 enroulements, dans le bon sens inclus par une étoile et suspendus en 3 phases complÚtes. Eh bien, ou un chastotnik en 3 phases, dont un arbre sur Ali.

TriphasĂ© + triangle + condensateurs. Ici, nous perdons dĂ©jĂ  en efficacitĂ©, en puissance et en couple, eh bien, s'il n'y a pas 3 phases, nous avons une solution pour nous-mĂȘmes. Bon marchĂ©, simple, fiable, gai.

Condensateur monophasé

Nous en parlerons ici. En gĂ©nĂ©ral, ces moteurs sont trĂšs courants. Ce sont des fans de moteurs de projecteurs et d'entraĂźnements de certaines montres, et des moteurs pour petites Ă©meri et autres applications oĂč une puissance Ă©levĂ©e n'est pas nĂ©cessaire, mais des avantages d'asynchroniseurs sont nĂ©cessaires: une fiabilitĂ© + vitesse Ă©norme, en fonction uniquement de la frĂ©quence de la tension d'alimentation.

Le schĂ©ma de base de l'inclusion (l'image n'est pas la mienne, honnĂȘtement trouvĂ©e sur Internet):



En général, grosso modo, le principe est le suivant: il y a un enroulement de démarrage, il induit un CEM dans un rotor à cage d'écureuil. Avec un déphasage, l'enroulement de travail est activé. Elle «pousse» l'ancre aimantée, la rotation commence. Lorsque vous vous tournez vers un certain angle, tout se répÚte. Le moteur commence à tourner.

Total - vous avez besoin de 2 phases, dĂ©calĂ©es selon un certain angle. Il fait gĂ©nĂ©ralement 90 degrĂ©s. Ceci est fourni par le condensateur de dĂ©marrage. Eh bien, aprĂšs un ensemble de rĂ©volutions - l'ancre commence Ă  fonctionner Ă  partir du bobinage trĂšs fonctionnel et le bobinage du dĂ©marreur peut mĂȘme ĂȘtre complĂštement dĂ©sactivĂ©. Eh bien, ou alimentĂ© par un condensateur de travail, une capacitĂ© beaucoup plus petite.

Mais tout cela n'est qu'une théorie. Mais en pratique, que voulez-vous? Je veux un chastotnik. Qu'est-ce qu'il accélérerait, ralentirait, tournerait dans les deux sens, enfin, à des vitesses différentes, bien sûr! Et ici, cela devient un peu plus compliqué. Le fait est qu'il y a beaucoup moins de chastotniks en vente. Et ils coûtent beaucoup plus cher. En général - exotique.

Mais si vous y rĂ©flĂ©chissez de cette façon, la diffĂ©rence par rapport Ă  la phase 3 n'est pas si grande. Et vous pouvez mĂȘme utiliser les mĂȘmes circuits. En mĂȘme temps, il y a les mĂȘmes 3 prises: commune, enroulement de dĂ©marrage, enroulement de travail. Et tout tourne autour du firmware. Donc - cela peut ĂȘtre fait. Et que ce ne soit pas un contrĂŽle vectoriel avec un tas de mathĂ©matiques, mais un simple scalaire, mais ... comme je peux.

Donc - ce qui est requis. Tout d'abord, regardons les graphiques du sinus et du cosinus (nous avons un décalage de 90 degrés) CONVENTION cela ressemblera à ceci:



C'est-à-dire la tùche est élémentaire: nous «tirons» le général au sol, introduisons un paquet d'impulsions positives dans le bobinage du démarreur, alimentons un paquet d'impulsions dans l'ouvrier. Ensuite, nous tirons le général au plus et envoyons un pack d'impulsions négatives au démarreur, puis à l'enroulement de travail. T.O. grossiÚrement, nous obtenons une imitation d'un changement de polarité et d'un déphasage. De la fréquence à laquelle nous le ferons, la «fréquence» dépendra.

En gĂ©nĂ©ral, la thĂ©orie est simple. En tant que contrĂŽleur ATMega 328 avec un chargeur de dĂ©marrage, les arduins (oui, en fait, l'arduina elle-mĂȘme, juste sans trop de cerclage), le pilote IR2132 (ancien, mais cela ne fonctionnait pas avec IR2136) et les clĂ©s de sortie IRG4BC30. Pour mon moteur de 1,1 kW, c'est plus que suffisant.

(Si vous répétez le diagramme, alors la carte est terminée, un croquis est versé dans l'Arduino Duemilanove, puis le Mega328 est retiré et soudé dans la carte. Terminé.)

Et par la suite ... De plus, j'ai plongé dans le monde merveilleux des inductances et de l'électronique de puissance. Et tout s'est avéré pas aussi simple qu'on le pensait au début:

1. La vitesse d'ouverture et de fermeture des clés est importante. Le temps mort est TRÈS important.
2. Mise sous tension du ballast - obligatoire à l'aide d'une diode, face au plus sur le condensateur de filtrage de puissance. Sinon, les décharges pendant le déchargement de l'inductance désactivent parfois les IGBT de puissance.
3. Refroidissement. Les petits radiateurs sur la carte sont mauvais. Soit il surchauffe, soit vous devez le souffler. Mais si vous le soufflez, alors toute la suspension métallique de la machine, tÎt ou tard, court-circuitera quelque chose et il y aura un coup.
3+.Le mica, ou plutĂŽt le mica TRÈS MINCE, est mauvais. Il fait son chemin et il s'avĂšre que dans le titre de l'article. Dans le mĂȘme temps, les coussinets thermiques en silicone ont une conductivitĂ© thermique pire. Mais la cĂ©ramique ... je ne l'ai pas.
4. Freinage par la mĂ©thode d'une longue rafale d'impulsions de mĂȘme polaritĂ© sur un enroulement, les transistors surchauffent rapidement et ils grillent. Et aussi, le moteur saute dans beaucoup de plaisir, tourne jusqu'Ă  3 000 tours et s'arrĂȘte pendant 0,3 seconde Ă  0.
5. Lorsque tout fonctionne et que vous vous détendez, allumez le circuit sans ballast et appuyez sur Start - il y aura un coup. Cela conduit également à un remplacement de pilote.

Esquisse:Maintenant, la rotation dans les deux sens avec un rĂ©glage en douceur de la frĂ©quence de 25 Ă  75 Hz avec un pas de 0,25 est mise en Ɠuvre. Il y avait une idĂ©e avec un frein. Maintenant, il est commentĂ© et il faudra changer le schĂ©ma. À savoir, l'idĂ©e est la suivante: j'ai correctement appliquĂ© des impulsions de mĂȘme polaritĂ©, MAIS. Cela doit ĂȘtre fait par ballast avec une clĂ© sĂ©parĂ©e.

Partie puissance: le circuit sera encore finalisĂ©, mais pour le moment la machine est dans une piĂšce non chauffĂ©e et il est extrĂȘmement difficile de travailler avec elle en raison du gel de l'huile.

Esquisse
#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;
}


Schéma:
image
En général, presque un classique, mais assemblé à partir de 5 schémas différents. Les diodes sur les épaules "hautes", en général, lors de l'utilisation de transistors IGBT, ne sont pas nécessaires, mais je l'ai fait en premier, puis je n'ai pensé qu'en

consĂ©quence: cela fonctionne. Il reste encore beaucoup Ă  faire, par exemple une «tĂ©lĂ©commande» externe, un frein. Il peut ĂȘtre utile d'expĂ©rimenter la durĂ©e de l'impulsion ou de crĂ©er un PWM Ă  part entiĂšre simulant un sinus plutĂŽt qu'un cycle de service constant. Mais pour l'instant c'est le cas. Peut-ĂȘtre que quelqu'un vous sera utile.

Et au final, j'aimerais demander: au lieu du ballast, je mets un starter, "serrĂ©" par des diodes. Ai-je tort dans une telle dĂ©cision? Choke, je ne sais mĂȘme pas quelle inductance. TirĂ© de l'alimentation ATX, oĂč il se trouvait dans l'unitĂ© de compensation de puissance rĂ©active.

Eh bien, l'expĂ©rience ... L'expĂ©rience est trĂšs intĂ©ressante. Je n'aurais jamais pensĂ© que cela aurait pu ĂȘtre aussi difficile. Et ce 30V et 300V est une Ă©norme diffĂ©rence. Je respecte vraiment les gens qui conçoivent de telles choses.
Et c'est le prix de mes erreurs: Vous



pouvez regarder la vidéo de l'ensemble du processus ici: 1 2 3

Questions pour les plus avertis, je voudrais voir les commentaires:

1. La manette des gaz qui se dresse sur le circuit +310. Dois-je me débarrasser de lui? Je le mets dans l'espoir que l'augmentation du courant, en cas de courant traversant, sera plus lente et que le conducteur aura le temps de passer en protection de courant.

2. J'obtiens des impulsions du mĂȘme rapport cyclique. Est-ce critique? Quitter, ou encore faire quelque chose de «dĂ©pendant des sinus» dans le cycle de service?

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


All Articles