This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
en:iot-open:practical:hardware:sut:stm32:emb10_1 [2024/04/10 17:22] – created ktokarz | en:iot-open:practical:hardware:sut:stm32:emb10_1 [2024/04/10 19:09] (current) – [EMB10: Controlling standard servo] ktokarz | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== | + | ====== |
- | You will learn how to control a standard miniature servo with the STM32 System on Chip. Standard miniature analogue servo is controlled with a PWM signal of frequency 50Hz with a duty cycle period between 1 ms (rotate to 0) and 2 ms (rotate to 180 degrees), where 1.5 ms corresponds to 90 degrees. | + | You will learn how to control a standard miniature servo with the STM32 System on Chip. Standard miniature analogue servo is controlled with a PWM signal of frequency 50Hz with a duty cycle period between 1 ms (rotate to 0) and 2 ms (rotate to 180 degrees), where 1.5 ms corresponds to 90 degrees. Some servos have other duty cycle minimum and maximum values, always refer to the documentation. |
<note warning> | <note warning> | ||
A servo has a red arrow presenting the gauge' | A servo has a red arrow presenting the gauge' | ||
Line 6: | Line 6: | ||
The servo is an example of a physical actuator. It requires some time to operate and change the position. Please give it time to set a new position between consecutive changes of the control PWM signal. Moreover, because of the observation via camera, too quick rotation may not be observable at all depending on the video stream fps. A gap of 2s between consecutive rotations is usually a reasonable choice. | The servo is an example of a physical actuator. It requires some time to operate and change the position. Please give it time to set a new position between consecutive changes of the control PWM signal. Moreover, because of the observation via camera, too quick rotation may not be observable at all depending on the video stream fps. A gap of 2s between consecutive rotations is usually a reasonable choice. | ||
===== Prerequisites ===== | ===== Prerequisites ===== | ||
- | To ease servo control, instead | + | A good understanding |
- | <code bash> | + | \\ |
- | ib_deps = dlloydev/ESP32 ESP32S2 AnalogWrite@^5.0.2 | + | Some servos tend to go below 1 ms and above 2 ms to achieve a full 180-degree rotation range. |
- | </code> | + | |
- | This library requires minimum setup but, on the other hand, supports, i.e. fine-tuning of the minimum and maximum duty cycle as some servos tend to go beyond 1ms and above 2ms to achieve a full 180-degree rotation range. | + | |
===== Suggested Readings and Knowledge Resources ===== | ===== Suggested Readings and Knowledge Resources ===== | ||
* [[en: | * [[en: | ||
- | * [[en: | + | * [[en: |
- | * [[en: | + | |
- | * [[en: | + | |
* [[en: | * [[en: | ||
+ | * [[en: | ||
+ | * [[en: | ||
===== Hands-on Lab Scenario ===== | ===== Hands-on Lab Scenario ===== | ||
Line 25: | Line 23: | ||
==== Start ==== | ==== Start ==== | ||
- | Check if the servo is in the camera view. The servo is controlled with GPIO 37. | + | In the laboratory equipment, |
+ | \\ | ||
+ | The hardware timer library implements functions which allow us to control the duty cycle of the PWM signal and express it in different formats, including percentages. In the case of setting the PWM duty cycle expressed in percentages, | ||
==== Steps ==== | ==== Steps ==== | ||
Line 31: | Line 31: | ||
<note warning> | <note warning> | ||
=== Step 1 === | === Step 1 === | ||
- | Include | + | Include |
<code c> | <code c> | ||
- | #include <Servo.h> | + | #include " |
- | # | + | #include <HardwareTimer.h> |
+ | # | ||
</ | </ | ||
- | MG 90 servos that we use in our lab are specific. As mentioned above, to achieve a full 180-degree rotation range, their minimum and maximum duty cycle timings go far beyond standards. Here, we declare minimum and maximum values for the duty cycle (in microseconds) and a PWM control channel (2): | + | |
+ | We will also need some variables: | ||
<code c> | <code c> | ||
- | #define PWMSRV_Ch | + | // PWM variables definitions |
- | #define srv_min_us | + | TIM_TypeDef *SRVInstance; |
- | #define srv_max_us 2400 | + | uint32_t channelSRV; |
+ | HardwareTimer *MyTimServo; | ||
</ | </ | ||
=== Step 2 === | === Step 2 === | ||
- | Define a servo controller object: | + | The hardware timer library uses internal timer modules and allows us to define channels attached to the timer. Channels represent the output pins connected to the hardware elements. Our laboratory board uses the same timer to control the servo and fan. In this example, we will use one channel for the servo only setting the proper PWM frequency of the timer. The channel connected to the servo controls the PWM duty cycle. |
+ | |||
+ | Create the timer instance type based on the servo pin: | ||
<code c> | <code c> | ||
- | static Servo srv; | + | TIM_TypeDef *SRVInstance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(SERVO_PWM_PIN), |
</ | </ | ||
+ | < | ||
+ | The same timer is used for the fan in the scenario STM_1A. | ||
+ | </ | ||
- | === Step 3 === | + | Define the channel |
- | Initialise parameters (duty cycle, | + | |
<code c> | <code c> | ||
- | srv.attach(SRV_PIN, PWMSRV_Ch, | + | channelSRV = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(SERVO_PWM_PIN), PinMap_PWM)); |
</ | </ | ||
- | 50Hz frequency is standard, so we do not need to configure it. | ||
+ | Instantiate HardwareTimer object. Thanks to ' | ||
+ | <code c> | ||
+ | MyTimServo = new HardwareTimer(SRVInstance); | ||
+ | </ | ||
+ | |||
+ | Configure and start PWM | ||
+ | <code c> | ||
+ | MyTimServo-> | ||
+ | </ | ||
+ | |||
+ | === Step 3 === | ||
+ | MG 90 servos that we use in our lab are specific. As mentioned above, to achieve a full 180-degree rotation range, their minimum and maximum duty cycle timings go far beyond standards. We will create a function for calculating the duty cycle for the servo with the angle as the input parameter. | ||
+ | |||
+ | <code c> | ||
+ | void fSrvSet(int pAngle) | ||
+ | { | ||
+ | if (pAngle< | ||
+ | if (pAngle> | ||
+ | int i_srv=500+(200*pAngle)/ | ||
+ | MyTimServo-> | ||
+ | }; | ||
+ | </ | ||
=== Step 4 === | === Step 4 === | ||
- | Rotating a servo is as easy as writing | + | Rotating a servo is as easy as calling our function with the desired angle as the parameter, e.g.: |
<code c> | <code c> | ||
- | srv.write(SRV_PIN,180); | + | fSrvSet(90); |
delay(2000); | delay(2000); | ||
</ | </ | ||
Line 67: | Line 96: | ||
**How do I know minimum and maximum values for the timings for servo operation? | **How do I know minimum and maximum values for the timings for servo operation? | ||
+ | **Would it be possible to control the servo and fan with the same program?**: Yes, but you have to remember that servo has very strict timing requirements. Because both elements share the same timer, they also share the same frequency which must be set according to the servo requirements. | ||
==== Result validation ==== | ==== Result validation ==== |