This is an old revision of the document!
Vajalikud teadmised: [HW] Mootorite moodul, [AVR] Digitaalsed sisendid-väljundid, [LIB] Mootorid, [LIB] Viide
Püsimagnetiga DC mootorid on väga laialt levinud robootikas ja mehatroonikas. DC mootorite kiirust ja pöörlemissuunda on suhteliselt lihtne juhtida. Mootori pöörlemissuunda muudetakse mootorile antava pinge polaarsusega. Mikrokontrolleriga juhtimisel kasutatakse H-silda.
Kuigi DC mootori kiirust on lihtne juhtida, siis puudub garantii, et soovitud kiirus siiski saavutatakse. Tegelik kiirus sõltub paljudest factoritest, põhiliselt jõumomendist mootori väljundvõllil, töövoolust ja muudest mootori karakteristikutest. Mootori ja kiiruse ning väljundmomendi suhe on ideaalsel mootoril lineaarses suhtes, st mida suurem on väljundmoment, seda madalam on kiirus ning seda rohkem tarbib mootor voolu, kuid reaalsete mootorite puhul sõltub see täpse mootori tüübist.
Alalisvoolu mootorit saab juhtida nii analoog kui digitaal signaalidega.
Tavaliselt on mootori kiirus sõltuvuses mootor klemmidele antavast pingest. Kui mootorile anda nominaalpinge, siis mootor pöörleb nominaalkiirusega kui mootorit pole koormatud. Kui vähendada mootorile antavat pinget, siis mootori kiirus ning arendatav jõumoment samuti vähenevad. Sellist kiiruse juhtimist nimetatakse analoog juhtimiseks. Seda saab realiseerida näiteks transistoriga või reostaadiga.
Robootikas juhitakse alalisvoolu mootoreid mikrokontrolleritega ning kuna need on digitaalsed seadmed, siis tuleks ka mootoreid digitaalselt juhtida. Selle saavutamiseks tuleks transistore pidevalt natuke lahti hoidmise asemel lülitada neid kiiresti sisse - välja kasutades pulsilaius modulatsiooni (PWM). Koguenergia, mis mootorile antakse jääb kusagile seisva mootori ja täiskiirusel pöörleva mootori vahepeale. Avatud oleku aja kirjeldamiseks kasutatakse töötsükli mõistet, mida mõõdetakse protsentides. 0% tähendab, et transistor on pidevalt suletud asendis ning mootor seisab, 100% tähendab, et transistor on pidevalt avatud ning mootor pöörleb nominaalkiirusel. PWMi sagedus peab olema piisavalt kõrge, et mootori pöörlemine oleks võimalikult sujuv ning väljundvõlli katkendlik pöörlemine ei tekitaks lisavibratsioone. Samuti tekitab mootori mähis madalatel sagedustel müra. Seetõttu kasutatakse tavaliselt sagedusi üle 20kHz. Sagedust piirab aga ka transistoride effektiivsus, mis kõrgemate sageduste puhul langeb.
Robotites kasutatakse ühe transistori asemel tavaliselt H-silda, mis võimaldab lisaks kiiruse muutmisele ka mootorite suunda muuta.
Digitaalsel juhtimisel (nt PWM) on mitmed eelised analoog juhtimise üle. Põhiline eelis mikrokontrolleriga juhitavate süsteemide puhul on see, et vaja on vaid üht digitaalväljundit ning puudub vajaduse keerulisel digitaal - analoog muundiri järele. Lisaks on digitaalne juhtimine effektiivsem (vähem energiat muundatakse lihtsalt soojuseks).
Lihtsustatud juhtimisskeem on näidatud kõrvalasuval joonisel. Juhtpinge Vc tuleb mikrokontrolleri väljundviigult ning lülitab transistori Q sisse - välja umbes 20kHz sagedusega. Kui Q on sisse lülitatud, liigub kogu vool I läbi mootori M. Sellisel juhul käitub transistor kui suletud lüliti ja pingelang Vq on 0-i lähedane ning mootorile jääb kogu pinge Vdd. Me saame arvutada ka transistori läbiva koguvõimsuse valemiga P = I * V.
P = I * Vq, ja kui Vq ~ 0, siis P ~ 0W
See tähendab, et transistor ei kuluta peaaegu üldse energiat avatud olekus. Sarnane situatsioon on ka juhul, kui transistor on suletud olekus. Sellisel juhul ei liigu läbi transistori ega mootori vool. Arvutades transistori läbiva võimsuse:
P = I × Vq, ja kui I = 0, siis P = 0W
Kokkuvõttes võime öelda, kui transistor on skeemis lülitava elemendina, siis on süsteemi effektiivsus väga kõrge ning transistori kasutatav võimsus on väga madal. Võrreldes lineaarse (analoog) süsteemiga, kus transistor kulutab sama palju voolu, kui juhitav mootor on tegemist väga effektiivse süsteemiga. Praktikas ei ole aga olemas kadudeta süsteemi ning nii esinevad kaod ka transistori ümberlülitamisel ühest asendist teise. Seega esinevad suuremad kaod juhul, kui transistore lülitatakse kiiremal sagedusel.
PS: mitte segi ajada RC Servo juhtsignaali PWM signaaliga
Kodulabori Mootorimoodul sisaldab Mootori plaati ning DC mootorit ülekande ning koodriga. Mootoriplaadile on võimalik ühendada kuni neli alalisvoolumootorit. Skeemid ja õpetused on vastaval alamlehel “Mootorite moodul”. Iga mootorit, mis on ühendatud H-silla külge juhitakse kahe mikrokontrolleri digitaalväljundiga. Mootori kiirust juhitakse taimeritega, mis genereerivad pideva PWM signaali H-sillale. Mootori kiirust juhtiakse suhteliste väärtustega 0 - 255, kus 0 tähendab seisvat mootorit ning 255 maksimaalsel kiirusel liikuvat mootorit.
static pin dcmotor_pins[4][2] = { { PIN(B, 7), PIN(B, 4) }, { PIN(D, 1), PIN(D, 0) }, { PIN(D, 7), PIN(D, 6) }, { PIN(D, 5), PIN(D, 4) } }; static int motorindex[4][2] = { { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 } }; // Käivita PWM valitud mootori jaoks void dcmotor_drive_pwm_init(unsigned char index, timer2_prescale prescaler) { unsigned char i, pwm; pin_setup_output(dcmotor_pins[index][0]); pin_setup_output(dcmotor_pins[index][1]); motor[index] = 1; pwm = PWMDEFAULT; for(i=0 ; i<CHMAX ; i++) // Käivita kõik kanalid { compare[i] = pwm; // algväärtusta PWM väärtused compbuff[i] = pwm; // algväärtusta PWM väärtused } // Timer 2 normaal resiimis, sea jagur timer2_init_normal(prescaler); // Timer 2 luba katkestused timer2_overflow_interrupt_enable(true); // Luba globaalsed katkestused sei(); } void dcmotor_drive_pwm(unsigned char index, signed char direction, unsigned char speed) { if(direction == -1) { compbuff[motorindex[index][0]] = 0x00; compbuff[motorindex[index][1]] = speed; } if(direction == 1) { compbuff[motorindex[index][0]] = speed; compbuff[motorindex[index][1]] = 0x00; } }
Mootorite teegi maatriksis dcmotor_pins määratakse ära viigud, kuhu on ühendatud Mootoriplaadi 4 mootori juhtsignaalid. Enne mootori kiiruse juhtimist tuleb välja kutsuda funktsioon dcmotor_drive_pwm_init selle mootori kohta (0-3), mille kiirust on soov juhtima hakata. See seab vastavad viigud väljunditeks. Samuti tuleks seadistada Timer2 jagur timer2_prescale, mis määrab PWMi sageduse. Kui koodus ei kasutata rohkem taimeri peal jooksvaid süsteeme, siis on sobilik väärtus TIMER2_NO_PRESCALE. Kui aga kasutatakse näiteks ka ultraheliandurit vmt, siis tuleks valida TIMER2_PRESCALE_8, muidu võib protsessori jõudlust väheks jääda ja anduri tulemustesse võib tekkida viga. Suuremaid jaguri väärtuseid pole soovitatav kasutada, sest see muudab mootori pöörlemise katkendlikuks tekitades vibratsiooni.
For controlling motor speed the function dcmotor_drive_pwm is included into library. With this function three parameters are needed. First is motor index (0-3), second is direction -negative direction parameter is used to give to the motor one revolving direction and other direction with positive parameter, and 0 if the motor is stopped. Third parameter is speed where the value can be from 0 to 255. The speed value is not any specific rpm, but is relative value and the actual speed is depending on the motor and power supply. The precision of motor speed control is 8-bit, meaning that smallest controlling value is 1/255 of full speed.
The following is an example program which controls first DC motor (DC motor connector 0) so that motor speed is half of the full speed. The speed is modulated with PWM signal of controlling pin.
#include <homelab/delay.h> #include <homelab/module/motors.h> int main(void) { // DC motor 0 init with no prescaler dcmotor_drive_pwm_init(0, TIMER2_NO_PRESCALE); while(1) { // DC motor drive with half of the nominal speed dcmotor_drive_pwm(0, 1, 128); } }
Another example program which controls first DC motor (DC motor connector 0) with potentiometer from Sensor module.
#include <homelab/delay.h> #include <homelab/module/motors.h> #include <homelab/adc.h> int main(void) { int speed; // Adjusting ADC adc_init(ADC_REF_AVCC, ADC_PRESCALE_8); // DC motor 0 init with no prescaler dcmotor_drive_pwm_init(0, TIMER2_NO_PRESCALE); while(1) { // Potentiometer is connected to channel 3 // Average of 4 samples are acquired speed = adc_get_average_value(3, 4); // DC motor drive with speed from potentiometer // As potentiometer has 10-bit output but DC motor drive // function 8-bit input the adc output have to be converted // to 8-bit e.g dividing the output with 4, or shifting bit // 2 position >>2 dcmotor_drive_pwm(0, 1, speed/4); } }