This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| en:iot-open:practical:hardware:itt:avr:servo [2025/08/26 11:13] – created ingmar05 | en:iot-open:practical:hardware:itt:avr:servo [2025/09/02 14:28] (current) – raivo.sell | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ====== Servomotor ====== | ||
| + | ===== Theory ===== | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | [{{ : | ||
| + | |||
| + | RC (// | ||
| + | |||
| + | The controlling signal of the servo motor is a specific pulse with a modulated signal (PWM), where the width of the pulse determines the position of the rotor. The period of the signal is 20 ms (50 Hz), and the width of the high period is 1 ms – 2 ms. 1 ms marks one extreme position, and 2 ms marks the second one. 1,5 ms marks the middle position of the servo motor’s rotor. | ||
| + | |||
| + | A traditional RC servo motor is also known as an analogue servo motor. It is because in the last decade, so-called digital servo motors have become common. The difference between those two is that in an analogue servo motor, the motor is controlled by the same 50 Hz PWM input signal. In a digital servo motor, the motor is controlled by a microcontroller with a much higher frequency signal. The input signal is the same in the digital servo motor, but a higher modulation frequency of the motor enables much more precise and faster position determination. | ||
| + | |||
| + | |||
| + | ===== Practice ===== | ||
| + | |||
| + | On the HomeLab module, there are two plugs for connecting RC servo motors. The PWM ends of the plugs are connected to the pins of the microcontroller, | ||
| + | |||
| + | The timer must be set up in PWM production mode, where the maximum value of the timer is determined with the ICR register. With the maximum value changed in the program and in the pace divider of the timer, the precise PWM frequency for controlling the servo motor can be determined. With the comparison register of the timer, the lengths of both high semi-periods of the PWM signal can be determined. The timers have special comparing units that monitor the value of the counter, and in case it remains equal to the value of the comparison register, they change the output value of the comparing units. The following is the program code of the servo motor control library of the HomeLab. For the purpose of functionality, | ||
| + | |||
| + | <code c> | ||
| + | // The value of the timer (20 ms)for achieving the full period of PWM | ||
| + | // F_CPU is the clock rate of the microcontroller, | ||
| + | // 50 Hz and 8 | ||
| + | #define PWM_PERIOD | ||
| + | |||
| + | // Middle position of PWM servo (5 ms / 20 ms) | ||
| + | // Middle position is 15/200 of the full period | ||
| + | #define PWM_MIDDLE_POS | ||
| + | |||
| + | // Factor for converting the percents (-100% to 100%)to periods | ||
| + | // +1 is added to ensure that semi periods would reach to the boundaries | ||
| + | // of 1 ms and 2 ms or // a little over | ||
| + | #define PWM_RATIO | ||
| + | |||
| + | // Set-up of the pins | ||
| + | static pin servo_pins[2] = | ||
| + | { | ||
| + | PIN(B, 5), PIN(B, 6) | ||
| + | }; | ||
| + | |||
| + | // Preparing the servo motor for working | ||
| + | void servomotor_init(unsigned char index) | ||
| + | { | ||
| + | // The pin of PWM signal for output | ||
| + | pin_setup_output(servo_pins[index]); | ||
| + | |||
| + | // Setup of timer 1 | ||
| + | // Prescaler = 8 | ||
| + | // Fast PWM mode, where TOP = ICR | ||
| + | // OUTA and OUTB to low in comparison | ||
| + | timer1_init_fast_pwm( | ||
| + | TIMER1_PRESCALE_8, | ||
| + | TIMER1_FAST_PWM_TOP_ICR, | ||
| + | TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, | ||
| + | TIMER1_FAST_PWM_OUTPUT_CLEAR_ON_MATCH, | ||
| + | TIMER1_FAST_PWM_OUTPUT_DISABLE); | ||
| + | |||
| + | // Determining the period by the maximum value | ||
| + | timer1_set_input_capture_value(PWM_PERIOD); | ||
| + | } | ||
| + | |||
| + | // Determining the position of the servo motor | ||
| + | // The parameter of the position is from -100% to +100%. | ||
| + | void servomotor_position(unsigned char index, signed short position) | ||
| + | { | ||
| + | switch (index) | ||
| + | { | ||
| + | case 0: | ||
| + | timer1_set_compare_match_unitA_value( | ||
| + | PWM_MIDDLE_POS + position * PWM_RATIO); | ||
| + | break; | ||
| + | |||
| + | case 1: | ||
| + | timer1_set_compare_match_unitB_value( | ||
| + | PWM_MIDDLE_POS + position * PWM_RATIO); | ||
| + | break; | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | The example program uses the described functions of the library of the HomeLab. At the beginning of the program, the servo motor’s PWM signal generator is started with the // | ||
| + | |||
| + | <code c> | ||
| + | // Testing program of the servo motor | ||
| + | #include < | ||
| + | |||
| + | // Main program | ||
| + | int main(void) | ||
| + | { | ||
| + | |||
| + | // Set-up of the motor | ||
| + | servomotor_init(1); | ||
| + | |||
| + | // Determining the position of the servo motor | ||
| + | servomotor_position(1, | ||
| + | |||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Task to be implemented ==== | ||
| + | |||
| + | - Use a servo motor to block and unblock the distance sensor range and present the measured distance on the LCD (use previous scenarios and instructions for the sensor and LCD) | ||