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
The Motor module of the HomeLab includes motor board and DC motor equipped with integrated gearbox and encoder. Motor board allows connecting up to four DC motors. The schemes and instructions for connection are found in the chapter “Motors module”. Every motor is connected to H-bridge which is controlled with two digital output pins of the microcontroller. Motor speed is controlled by timers which are generating software PWM signal for H-bridge. Motor speed can be controlled by relative value between 0 to 255, where 0 means that motor is stopped and 255 that motor runs at maximum speed.
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 } }; // Initialize PWM for specified DC motor. 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++) // initialize all channels { compare[i] = pwm; // set default PWM values compbuff[i] = pwm; // set default PWM values } // Timer 2 normal regime, set prescaler timer2_init_normal(prescaler); // Timer 2 interrupts set enabled timer2_overflow_interrupt_enable(true); // Enable global interrupts 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; } }
With the array dcmotor_pins in the library, the controlling pins of four motor-controllers are determined. Before controlling the motors and their speed, function dcmotor_drive_pwm_init with the number of the motor-controller (0 – 3) must be called out. It sets the pins as output. In addition prescaler - timer2_prescale prescaler have to be set as a second parameter. Prescaler sets PWM frequency and is important when using other timer based functions on the same time. If only motors are used TIMER2_NO_PRESCALE value is most suitable. If other timer based functions are used on the same time e.g. ultrasonic sensor TIMER2_PRESCALE_8 is recommended value. Bigger prescaler values are not suitable for DC motor speed control as vibration will be too high. However the same function can be used for example flashing the LED and in this case bigger prescaler values are important to consider.
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); } }