Add blink PWM example

This commit is contained in:
Derek Jamison 2023-07-01 09:40:35 -05:00
parent ecbb5c037b
commit 5c5333e55e
4 changed files with 84 additions and 0 deletions

View File

@ -0,0 +1,31 @@
# GPIO_BLINK_PWM
This is the classic "Hello World" of GPIO, where we blink an LED using PWM (Pulse Width Modulation). You will need an LED (any color is fine) and a resistor (220 ohms - 1 kilohm should be fine). Connect the long side of the LED into pin A7. Connect the short size of the LED to one side of the resistor (doesn't matter which side). Connect the other side of the resistor to any of the pin GND.
Run the application and the LED should start blinking. Hold the back button to exit.
## How it works
- Pulse width modulation is supported on pin A7 using FuriHalPwmOutputIdTim1PA7. You can also do pulse width modulation on pin A4 using FuriHalPwmOutputIdLptim2PA4. Using PWM has the advantage that the voltage on the pins transition automatically at some fixed frequency and duty cycle, without your code having to keep changing the state of the pins. The PWM library only supports an integer for the frequency, so it will not work for if you need to blink slower than 1 Hz (1 time per second). The duty cycle is the percentage of time the light should be on (so it should typically be a number between 1 and 99).
- We define a variable for our LED...
```c
const FuriHalPwmOutputId channel_led = FuriHalPwmOutputIdTim1PA7;
```
- We start the PWM timer, blinking LED at 1 Hz, 20% duty cycle (the pin will be at 3.3 volts 20% of the time, then 0 volts the remainder).
```c
furi_hal_pwm_start(channel_led, 1, 20);
```
- In a loop we sleep if the back button is not currently pressed.
```c
while(furi_hal_gpio_read(pin_back)) {
furi_delay_ms(100);
}
```
- We stop the PWM timer. This stops the timer and sets the pin to analog (floating input).
```c
furi_hal_pwm_stop(channel_led);
```

View File

@ -0,0 +1,10 @@
App(
appid="gpio_blink_pwm",
name="GPIO Blink PWM",
apptype=FlipperAppType.EXTERNAL,
entry_point="gpio_blink_pwm_app",
requires=["gui"],
stack_size=2 * 1024,
fap_icon="blink_pwm.png",
fap_category="GPIO",
)

View File

@ -0,0 +1,43 @@
#include <furi_hal.h>
#include <furi_hal_pwm.h>
#include <gui/gui.h>
// Pin A7 is FuriHalPwmOutputIdTim1PA7, pin A4 is FuriHalPwmOutputIdLptim2PA4.
const FuriHalPwmOutputId channel_led = FuriHalPwmOutputIdTim1PA7;
const GpioPin* const pin_back = &gpio_button_back;
static void my_draw_callback(Canvas* canvas, void* context) {
UNUSED(context);
canvas_set_font(canvas, FontPrimary);
canvas_draw_str(canvas, 5, 8, "GPIO - BLINK PWM LED");
canvas_draw_str(canvas, 5, 22, "Connect long LED to pin");
canvas_draw_str(canvas, 5, 32, "A7. Connect short LED");
canvas_draw_str(canvas, 5, 42, "to 220 ohm resistor.");
canvas_draw_str(canvas, 5, 52, "Connect other end of");
canvas_draw_str(canvas, 5, 62, "resistor to pin GND.");
}
int gpio_blink_pwm_app(void* p) {
UNUSED(p);
// Show directions to user.
Gui* gui = furi_record_open(RECORD_GUI);
ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, my_draw_callback, NULL);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
// Start blinking LED at 1 Hz, 20% duty cycle
furi_hal_pwm_start(channel_led, 1, 20);
// Hold the back button to exit (since we only scan it when restarting loop).
while(furi_hal_gpio_read(pin_back)) {
furi_delay_ms(100);
}
// Stop blinking LED (floating input)
furi_hal_pwm_stop(channel_led);
// Remove the directions from the screen.
gui_remove_view_port(gui, view_port);
return 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB