Jump to content
ELFORUM - Forumul Electronistilor
Sign in to follow this  
Vlad Mihai

Pornirea unui motor de HDD de tip BLDC

Recommended Posts

Buna ziua, ieri am avut ceva timp sa finalizez un proiect mai mic ce consta in pornirea unui motor de HDD. Motorul este in conexiune stea cu nulul accesibil(4 fire). Initial am gasit secventele de pornire pe site-ul asta http://theamateurprogrammer.blogspot.hk/2014/02/revitalizing-old-hard-drive-motors.html dar partea de forta nu ma incanta de loc, asa ca am proiect o noua schema cu mosfet.

Schema:

Posted Image

PCB:

Posted Image

3D

Posted Image3/

Realizare practica:

 

Posted Image

 

Posted Image

Cod sursa:

const int phase1pin = 2;const int phase2pin = 3;const int phase3pin = 4;float holdTime = 90000; // microsecsconst unsigned long minHoldTime = 3400; unsigned long p1start,              p1end,              p2start,              p2end,              p3start,              p3end; void setup(){  Serial.begin(9600);  pinMode(phase1pin, OUTPUT);  pinMode(phase2pin, OUTPUT);  pinMode(phase3pin, OUTPUT);  p1start = micros();  digitalWrite(phase1pin, HIGH);}  void chkP1(){  unsigned long currentTime = micros();  unsigned long td = currentTime - p1start;  unsigned long refractory = 2.25*holdTime;  if(digitalRead(phase1pin)){    if(td > holdTime){      digitalWrite(phase1pin, LOW);      p1end = currentTime;    }  }else if(td > refractory){    digitalWrite(phase1pin, HIGH);    p1start = currentTime;  }} void chkP2(){  unsigned long currentTime = micros();  unsigned long td = currentTime - p1start;  if(digitalRead(phase2pin)){    if(td > 1.75*holdTime || td < 0.75*holdTime){      digitalWrite(phase2pin, LOW);      p2end = currentTime;    }  }else if(td > 0.75*holdTime && td < 1.75*holdTime){    digitalWrite(phase2pin, HIGH);    p2start = currentTime;  }} void chkP3(){  unsigned long currentTime = micros();  unsigned long td = currentTime - p1start;  if(digitalRead(phase3pin)){    if(td > 0.25*holdTime && p3start < p1start){      digitalWrite(phase3pin, LOW);      p3end = currentTime;    }  }else if(td > 1.5*holdTime){    digitalWrite(phase3pin, HIGH);    p3start = currentTime;  }} void loop(){  chkP1();  chkP2();  chkP3();  delayMicroseconds(100);  if(holdTime >= minHoldTime){    holdTime -= 0.5;  }}
Nu prea sunt incantat de ceea ce ar putea face acest motor, cuplul e mic, si consuma mult o sursa de 12V 2A nominal in 10-15 minute e calda, suge vreo 3A si are rezistenta infasurarilor de circa 3 ohmi.

La secventa de pornire iar e nasol ca nu am reusit sa il stabilizez, atasez si un video.

 

E dedicatie pentru Thunderer acest topic, e acelasi motor care am incercat noi sa il pornim acum mult timp si am renuntat(daca iti mai amintesti), acum l-am biruit. :sparge:

Share this post


Link to post
Share on other sites

Frumos!Daca consuma mult, atunci trebuie sa aiba si cuplu pe masura! Daca se incalzeste motorul, fara sa aiba cuplu, atunci comanda nu e 100% ok.

Share this post


Link to post
Share on other sites

Da am presupus si eu ca ar fi comanda. O sa mai incerc si alta varianta de soft. Eu am vrut doar sa il pornesc pentru moment .

Share this post


Link to post
Share on other sites

Hahaha, am banuit eu ceva... Bravo, inca o data, pentru perseverenta!

Share this post


Link to post
Share on other sites

Cum mai sus am facut pornirea lui cu un cod de pe net in mediul arduino, acum vin cu varianta mea de pornire in mikroC, e bruta dar porneste motorul.

void main() {TRISB.F5 = 0;TRISB.F4 = 0;TRISB.F3 = 0;PORTB.F5 = 0;PORTB.F4 = 0;PORTB.F3 = 0;while(1){PORTB.F5=1;Delay_ms(30);PORTB.F5=0;Delay_us(8);  //dead timePORTB.F4=1;Delay_ms(30);PORTB.F4=0;Delay_us(8);   //dead timePORTB.F3=1;Delay_ms(30);PORTB.F3=0;Delay_us(8);  //dead time}}

Share this post


Link to post
Share on other sites

Asta se numeste ambitie veritabila, si merita toate cuvintele de lauda, bravo @Vlad. :101

Share this post


Link to post
Share on other sites

E bine că te-ai apucat, felicitări. :da Acum, e momentul să-l perfecţionezi. Adică să afli ce nu e bine :nebunrau: şi să-l faci să meargă ca un adevărat motor de HDD.Arată-ne ce poţi!

Share this post


Link to post
Share on other sites

Buna seara, am mai studiat problema si incerc o alta partea de comanda. Voi construi in invertor trifazic cu 3 semipunti(H bridge) cu mosfeti canal N(Vds=80V, id=100-150A, Rdson-3,4mohmi, Ciss ok) alaturi de niste drivere de 2A. Momentan merge greu ca de la servici nu ma slabesc deloc, si mai am si masterul, dar inaintez ca mi-a mancat zilele acest motor, ori va merge ori il ard si gata.

 

Ca driver HB voi folosi MAX5063D (cu intrare TTL), pentru a putea fi comandat de un microcontroler.

 

Fiind 3 semipunti am nevoie de 6 semnale pwm sa comand motorul, dar daca cititi catalogul la MAX5063D veti vedea ca pot folosi doar 3 semnale pwm, cate unul pentru fiecare faza. :freaza:

 

Momentan sunt in stadiu de proiectare pcb si calcul pe foaie componente.

Posted Image

 

Sper sa revin curand cu detalii. O zi buna!

Share this post


Link to post
Share on other sites

Buna dimineata, de mult am zis ca  ma  apuc sa fac un invertor   in 3 faze pentru un acest de motor de HDD dar nu am avut timp, insa ieri nu am mai rezistat si am realizat practic. Am  pornit de la o schema cu  perechi de mosfeti complementari (irf3205+ irf4905) si cu cate un driver  max628.De asemenea am  pus  si un "high side current sense"  realizat cu max4377 pentru a citi curentul. Momentan testez  functionarea unui soft  de  baza realizat dupa  diagrama de  comenzi preluata din documentatii, dar  mai am  de lucru, insa in seara asta am dat de un cod   pe net cu care am putut sa testez  invertorul, si  am ramas  impresionat cum lucreaza.

Atasez cateva imagini:

Schema   electrica a invertorului:

Posted Image

PCB invertor:

Posted Image

3d invertor:

Posted Image

 
Posted Image

PCB fizic invertor:

Posted Image

invertor:

Posted Image

 
Posted Image
 
Posted Image
Video:
Se misca mult mai bine fata de  cel precedent,  dar  trebuie sa il realizez cu  mosfeti cu canal n ca  cei de sus au rds on 20mohm si cam disipa  caldura, si in plus trebuie sa ii fac limitare  de curent. Dar  am prins curaj, se invarte cam cu aproximativ 4000 de rot/min acum. Poate il duc mai sus. Bineinteles va urma si o interfata in LabVIEW de control si monitorizare dar dupa ce termin. Folosesc  o placuta  Arduino sa il controlez, si  folosesc   3 fire  pentru a controla motorul, nu mai folosesc nulul de data asta.
Ps: la inceputul  clipului led-ul  clipeste pentru ca sursa  intra in limitare, o  stoarce de  curent, dar  cu cresterea  vitezei  nu mai   apare problema asta. Am facut o greseala ca am ales   driverele  smd, se cam incalzesc si nu au pad-uri  de racire ca alte  drivere dedicate smd.
Edited by Vlad Mihai

Share this post


Link to post
Share on other sites

Pune niste radiatoare sub Mosfeturi. Daca stai sub 5-6A nu vad de ce ai trece pe punte N. Fa-ti calculul de putere disipata (vezi aici http://ww1.microchip.com/downloads/en/AppNotes/00799b.pdf) si vezi daca asta e problema driverului. Poti sa te folosesti de pinii driverului (facand trasee PCB mai groase in viitor - vezi care sunt pinii mai potriviti sa disipe caldura) sa disipi caldura. 

 

Bafta la proiecte!

Share this post


Link to post
Share on other sites

Cel mai probabil incalzirea MOSFET-urilor este cauzata de conductia simultana a highside+lowside. Din cate stiu MAX628 nu ofera deadtime intern, de aceea el trebuie realizat de circuitul de comanda PWM. Poti sa verifici/reglezi acest deadtime din placa PWM (este Arduino?) ?

Daniel

Share this post


Link to post
Share on other sites

Salut,  da  am implementat   dead-time  de 10uS din  soft, placa arduino, o sa il mai reglez. Thunderer multumesc  pentru documentatie, o sa o citesc, desi  calculasem in mintea mea  valorile componentelor ca sa nu depasesc  limitele admise de driver.

Share this post


Link to post
Share on other sites

Salutare, de data  asta l-am biruit, se invarte  ca un  un motor de hard disk cu turatie maxima. Am  rezolvat cu incalzirea   invertorului  prin  adaugare de  limitare de curent de circa  0.8 A, motorul are  3 ohmi rezistenta infasurarilor. Am schimbat   toate  driverele, max628 cu altele noi si nu se mai incalzesc (cele  anterioare erau recuperate  de pe un alt montaj de-al meu, probabil erau defecte). Am realizat un soft care  porneste lent si accelereaza pe parcurs pana la viteaza maxima. Acest motor e un motor BLDC outrunner adica  rotorul  e in exterior. Timpul  mort la   fiecare  tranzistor este de   10uS, e arhisuficient, dupa 10 minute de functionare,  invertorul sta rece. Mi-a mancat zilele motorul asta.

Video:

https://www.youtube.com/watch?v=clD7sbHwC8c&feature=youtu.be

Share this post


Link to post
Share on other sites

Felicitari Mihai!

Eu sunt impresionat de ambitia ta, ai invatat foarte multe intr-un timp scurt, ai realizat foarte multe lucruri demne de toata lauda. Chiar daca ai testat cu un motor de mica putere, invertorul, prin redimensionarea partii de forta, cred ca ar putea alimenta motoare brushless, de putere mult mai mare. Eu sunt interesat de asa ceva, vreau sa fac ceva teste cu un alternator auto, convertit in motor. Daca ai putea da ceva detalii despre realizarea partii de comanda, ti-as fi recunoscator. Cu partea de forta, cred ca ma descurc. Apropo de asta, poti folosi doar mosfeti N, folosind drivere flotante, de ex IR2110. In felul asta, tensiunea de alimentare a puntii H, poate fi pana la vreo 400V. Trebuie insa citit curentul spre masa, dar e simplu de facut, cu un senzor de curent, care poate fi o simpla rezistenta.

Edited by giongiu

Share this post


Link to post
Share on other sites

Multumesc giongiu! O sa facem  in functie de ce timp am si  regulatorul dvs, v-am explicat pe mesaj privat. Postez codul sursa pe care l-am scris pentru a testa acest motor, se mai poate optimiza dar eu sunt multumit deocamdata  ca l-am dus la viteza maxima. Limbajul este  in Arduino,  procesor  ATmega328 smd.  Stiu ca e dezordonat  codul, dar important  e ca imi merge.

int T1 = 5;int T2 = 6;         // phase 1int T3 = 7;int T4 = 8;        //phase 2int T5 = 9;int T6 = 10;      //phase 3unsigned long stepLength = 40000;int minStepLength = 780;int steps = 10;void setup() { pinMode(T1, OUTPUT);  pinMode(T2, OUTPUT);  pinMode(T3, OUTPUT);    pinMode(T4, OUTPUT);    pinMode(T5, OUTPUT);    pinMode(T6, OUTPUT); }void loop(){    switchStep(1);  switchStep(2);   switchStep(3);  switchStep(4);  switchStep(5);  switchStep(6);    if(stepLength > minStepLength)  {    stepLength = stepLength - steps;  } else {        stepLength=minStepLength;  }    if (stepLength < 39950) {        steps = 300;  }     if (stepLength < 20000) {        steps = 50;  }  if (stepLength < 3000) {        steps = 2;  }}void switchStep(int stage){  switch(stage)  {  case 1:    digitalWrite(T1,  LOW);   digitalWrite(T2, LOW);     digitalWrite(T3, HIGH);     digitalWrite(T4, LOW);    digitalWrite(T5, LOW);     digitalWrite(T6, HIGH);  delayMicroseconds(10);   //dead time    myDelay(stepLength);    break;      case 2:   digitalWrite(T1, HIGH);    digitalWrite(T2, LOW);     digitalWrite(T3, LOW);     digitalWrite(T4, LOW);     digitalWrite(T5, LOW);     digitalWrite(T6, HIGH);delayMicroseconds(10);    //dead time    myDelay(stepLength);    break;    case 3:     digitalWrite(T1, HIGH);    digitalWrite(T2, LOW);     digitalWrite(T3, LOW);     digitalWrite(T4,HIGH);    digitalWrite(T5, LOW);    digitalWrite(T6, LOW);delayMicroseconds(10);   //dead time    myDelay(stepLength);    break;    case 4:  digitalWrite(T1, LOW);    digitalWrite(T2,LOW);     digitalWrite(T3, LOW);     digitalWrite(T4, HIGH);    digitalWrite(T5, HIGH);     digitalWrite(T6, LOW);   delayMicroseconds(10);    //dead time    myDelay(stepLength);    break;    case 5:    digitalWrite(T1, LOW);    digitalWrite(T2, HIGH);     digitalWrite(T3, LOW);     digitalWrite(T4, LOW);     digitalWrite(T5, HIGH);     digitalWrite(T6, LOW);delayMicroseconds(10);    //dead time    myDelay(stepLength);    break;      default:    digitalWrite(T1, LOW);   digitalWrite(T2, HIGH);    digitalWrite(T3, HIGH);     digitalWrite(T4, LOW);    digitalWrite(T5, LOW);     digitalWrite(T6, LOW);  delayMicroseconds(10);   //dead time    myDelay(stepLength);    break;  }  } void myDelay(unsigned long p) {if (p > 16380) {  delay (p/1000);  } else {  delayMicroseconds(p);  }}
Edited by Vlad Mihai

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.