-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7bd2f94
commit 8acd8fc
Showing
14 changed files
with
118 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Servo Motor and PWM | ||
|
||
In this section, we'll connect an SG90 Micro Servo Motor to the Pico 2 and control its rotation using PWM. The servo will move in a loop, rotating from 0 degrees to 90 degrees, and then to 180 degrees. | ||
|
||
Before moving forward, make sure you've read the [PWM introduction](../blinky/pwm.md) in the Blink LED section. | ||
|
||
## Hardware Requirements | ||
- **SG90 Micro Servo Motor** | ||
- **Jumper Wires**: | ||
- **Female-to-Male** jumper wires for connecting the Pico 2 to the servo motor pins (Ground, Power, and Signal). | ||
|
||
The SG90 servo has three wires: the **red wire** supplies 5V power, the **brown wire** connects to ground (GND), and the **orange wire** receives a PWM signal to control the servo's position. | ||
|
||
## Connection Overview | ||
1. **Ground (GND)**: Connect the servo's GND pin (typically the **brown** wire, though it may vary) to any ground pin on the Pico 2. | ||
2. **Power (VCC)**: Connect the servo's VCC pin (usually the **red** wire) to the Pico 2's 5V (or 3.3V if required by your setup) power pin. | ||
3. **Signal (PWM)**: Connect the servo's control (signal) pin to **GPIO9** on the Pico 2, configured for PWM. This is commonly the **orange** wire (may vary). | ||
|
||
<img style="display: block; margin: auto;" alt="pico2" src="./images/pico-servo-circuit.png"/> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
## More on PWM | ||
|
||
The servo motor we're using operates at a 50Hz frequency, which means that a pulse is sent every 20 milliseconds (ms). | ||
|
||
Let's break this down further: | ||
- **50Hz Frequency:** Frequency refers to how many times an event happens in a given time period. A 50Hz frequency means that the servo expects a pulse to occur 50 times per second. In other words, the servo receives a pulse every 1/50th of a second, which is 20 milliseconds. | ||
- **20ms Time Interval:** This 20ms is the time between each pulse. It means that every 20 milliseconds, the servo expects a new pulse to adjust its position. Within this 20ms period, the width of the pulse (how long it stays "high") determines the angle at which the servo will move. | ||
|
||
So, when we say the servo operates at 50Hz, it means that the motor is constantly receiving pulses every 20ms to keep it in motion or adjust its position based on the width of each pulse. | ||
|
||
### Pulse Width and Duty Cycle | ||
Let's dive deeper into how different pulse widths like 0.5ms, 1.5ms, and 2.4ms affect the servo's position. | ||
|
||
<img style="display: block; margin: auto;" alt="pico2" src="./images/servo-position-pwm.jpg"/> | ||
|
||
#### 1. **0.5ms Pulse (Position: 0 degrees)** | ||
- **What Happens**: A 0.5ms pulse means the signal is "high" for 0.5 milliseconds within each 20ms cycle. The servo interprets this as a command to move to the 0-degree position. | ||
- **Duty Cycle**: The duty cycle refers to the percentage of time the signal is "high" in one complete cycle. For a 0.5ms pulse: | ||
<img style="display: block; margin: auto;" alt="pico2" src="./images/servo-pwm-05ms.png"/> | ||
This means that for just 2.5% of each 20ms cycle, the signal stays "high" causing the servo to rotate to the 0-degree position. | ||
|
||
#### 2. **1.5ms Pulse (Position: 90 degrees)** | ||
|
||
- **What Happens**: A 1.5ms pulse means the signal is "high" for 1.5 milliseconds in the 20ms cycle. The servo moves to its neutral position, around 90 degrees (middle position). | ||
- **Duty Cycle**: For a 1.5ms pulse: | ||
<img style="display: block; margin: auto;" alt="pico2" src="./images/servo-pwm-15ms.png"/> | ||
|
||
Here, the signal stays "high" for 7.5% of the cycle, which positions the servo at 90 degrees (neutral). | ||
|
||
#### 3. **2.4ms Pulse (Position: 180 degrees)** | ||
|
||
- **What Happens**: A 2.4ms pulse means the signal is "high" for 2.4 milliseconds in the 20ms cycle. The servo will move to its maximum position, typically 180 degrees (full rotation to one side). | ||
- **Duty Cycle**: For a 2.4ms pulse: | ||
<img style="display: block; margin: auto;" alt="pico2" src="./images/servo-pwm-24ms.png"/> | ||
|
||
In this case, the signal is "high" for 12% of the cycle, which causes the servo to rotate to 180 degrees. | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
## Servo and Pico | ||
|
||
To control a servo with the Raspberry Pi Pico, we need to set a 50Hz PWM frequency. Currently, RP-HAL doesn't allow directly setting the frequency, so we achieve this by adjusting the `top` and `div_int` values. | ||
|
||
Refer the 1073th page of the [RP2350](https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf) Datasheet to understand how `top` and `div_int` works. | ||
|
||
### Formula from datasheet | ||
The following formula from the datasheet is used to calculate the period and determine the output frequency based on the system clock frequency. | ||
|
||
<img style="display: block; margin: auto;" alt="pico2" src="./images/period-formula-datasheet.png"/> | ||
|
||
For the pico2, the system clock frequency (f_sys) is 150MHZ. | ||
|
||
### Let's calculate `top` | ||
We want the PWM frequency (f_pwm) to be 50 Hz. In order to achieve that, we are going to adjust the `top` and `div_int` values. | ||
|
||
The top value must be within the range of 0 to 65535 (since it's a 16-bit unsigned integer). To make sure the top value fits within this range, I chose values for the divisor (div_int) in powers of 2 (such as 8, 16, 32, 64), though this isn't strictly necessary (it's just a preference). In this case, we chose `div_int = 64` to calculate a top value that fits within the u16 range. | ||
|
||
With the chosen div_int and system parameters, we can calculate the top using the following formula: | ||
<img style="display: block; margin: auto;" alt="pico2" src="./images/top-calculation.png"/> | ||
|
||
After performing the calculation, we find that the top value is `46,874`. | ||
|
||
You can experiment with different div_int and corresponding top values. Just ensure that div_int stays within the u8 range, top fits within the u16 range, and the formula yields a 50Hz frequency. | ||
|
||
(In case you are wondering, we are not setting the `div_frac` which is 0 by default. That's why it is not included in the calculation.) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
## Introduction to Servo Motors | ||
|
||
A servo motor controls movement by adjusting its position using a feedback system. It is guided by a signal, usually Pulse Width Modulation (PWM), to reach and maintain the desired position. | ||
|
||
They are widely used in applications requiring precise motion, such as robotics, RC vehicles, and camera systems, as well as in various projects. Hobby servos, which are often used in RC toys like cars, airplanes, are also popular for building robots. | ||
|
||
In our exercise, we'll be using the hobby server (Micro Servo SG90) | ||
|
||
### How does it work? | ||
|
||
A servo motor is controlled by sending a series of pulses through its signal line. The signal has a frequency of 50Hz, with a pulse every 20 milliseconds. The width of the pulse determines the servo's position. Typically, a servo can rotate 180 degrees. | ||
|
||
|
||
### Controlling the position | ||
The position of a servo motor is controlled by sending a pulse with a specific duration. The length of the pulse determines the angle of the motor. For most servos, a 1ms pulse moves the motor to 0 degrees, a 1.5ms pulse moves it to 90 degrees (neutral position), and a 2ms pulse moves it to 180 degrees. | ||
|
||
<img style="display: block; margin: auto;" alt="pico2" src="./images/servo-pwm.png"/> | ||
|
||
However, from my experiment, I found that not all servos follow these exact timings. For example, with my servo, the pulse duration for 0 degrees was 0.5ms, 1.5ms for 90 degrees, and approximately 2.4ms for 180 degrees. I had to experiment and adjust to get it right. If you're unsure, you can use tools like an oscilloscope to fine-tune it, or simply test different values to find what works best for your specific servo. | ||
|
||
The example I'll provide in this exercise is based on my servo's configuration, you might need to adjust the values depending on the servo you're using. |