Skip to content

Commit

Permalink
pwm
Browse files Browse the repository at this point in the history
  • Loading branch information
ImplFerris committed Oct 23, 2024
1 parent 37088c0 commit 527b219
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 33 deletions.
74 changes: 41 additions & 33 deletions src/blinky/pwm.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,17 @@ PWM stands for **Pulse Width Modulation**. It is a technique used to control the

In PWM, a digital signal switches between **on** and **off** states. The **duty cycle** of the signal determines how long it stays on compared to how long it stays off.

- **Duty Cycle**: The percentage of time the signal is on during one cycle.
- **Duty Cycle**:
The percentage of time the signal is on during one cycle.
<img style="display: block; margin: auto;" alt="pico2" src="../images/pwm-duty-cycle.png" />
<span style="text-align: center;display: block; margin: auto; font-size: 12px;">Image Credit: Wikipedia</span>
- For example:
- 100% duty cycle means the signal is always on.
- 50% duty cycle means the signal is on half the time and off half the time.
- 0% duty cycle means the signal is always off.

For LED brightness, PWM works by rapidly turning the LED on and off. If this happens fast enough, our eyes perceive a steady light, and the brightness increases with a higher duty cycle.

Refer the 1073th page of the [RP2350](https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf) Datasheet for more information.

In the previous example code, we use PWM to fade an LED.

### Fading Up
The code below gradually increases the LED brightness by adjusting the duty cycle from 0 to 25,000, with a small delay between each step:
```rust
for i in LOW..=HIGH {
delay.delay_us(8);
let _ = channel.set_duty_cycle(i);
}
```
The delay ensures the LED brightens gradually. Without it, the brightness would change too quickly for the eye to notice, making the LED appear to jump from dim to bright. The delay allows for a smooth, noticeable "fading up" effect. Dont' believe me! Adjust the delay to 0 and observe. You can increase the delay (eg: 25) and observe the fading effect.

Note: `set_duty_cycle` function under the hood writes the given value into CC register(Count compare value).

### Fading Down
The following code decreases the LED brightness by reducing the duty cycle from 25,000 to 0.
```rust
// Here rev is to reverse the iteration. so it goes from 25_000 to 0
for i in (LOW..=HIGH).rev() {
delay.delay_us(8);
let _ = channel.set_duty_cycle(i);
}
```

### Pause
After fading up and down, the program pauses for 500 milliseconds before repeating the cycle, allowing the LED to rest briefly.

Play around by adjusting the `delay` and observe. You can even comment out one of the for loop and observe the effect.


## PWM Peripheral in RP2350
The PWM peripheral is responsible for generating PWM signals. The Pico 2 features 12 PWM generators, known as slices, with each slice having two channels(A/B). This configuration results in a total of 24 PWM output channels available for use.

Expand Down Expand Up @@ -73,3 +44,40 @@ Get a mutable reference to channel B of PWM4 and direct its output to GPIO pin 2
let channel = &mut pwm.channel_b;
channel.output_to(pins.gpio25);
```

## Fading Effect

For LED brightness, PWM works by rapidly turning the LED on and off. If this happens fast enough, our eyes perceive a steady light, and the brightness increases with a higher duty cycle.


In the previous example code, we use PWM to fade an LED.

### Fading Up
The code below gradually increases the LED brightness by adjusting the duty cycle from 0 to 25,000, with a small delay between each step:
```rust
for i in LOW..=HIGH {
delay.delay_us(8);
let _ = channel.set_duty_cycle(i);
}
```
The delay ensures the LED brightens gradually. Without it, the brightness would change too quickly for the eye to notice, making the LED appear to jump from dim to bright. The delay allows for a smooth, noticeable "fading up" effect.

Dont' believe me! Adjust the delay to 0 and observe. You can increase the delay (eg: 25) and observe the fading effect.

Note: `set_duty_cycle` function under the hood writes the given value into CC register(Count compare value).

### Fading Down
The following code decreases the LED brightness by reducing the duty cycle from 25,000 to 0.
```rust
// Here rev is to reverse the iteration. so it goes from 25_000 to 0
for i in (LOW..=HIGH).rev() {
delay.delay_us(8);
let _ = channel.set_duty_cycle(i);
}
```

### Pause
After fading up and down, the program pauses for 500 milliseconds before repeating the cycle, allowing the LED to rest briefly.

Play around by adjusting the `delay` and observe. You can even comment out one of the for loop and observe the effect.

Binary file added src/images/pwm-duty-cycle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 527b219

Please sign in to comment.