From 33fdab9c18a0d34bc324d76be52682af2a93634b Mon Sep 17 00:00:00 2001 From: "Phani Pavan K: iDellToast" Date: Sun, 2 Feb 2025 12:14:10 +0530 Subject: [PATCH] add interrupt read example --- 1_Basic_GPIO/digitalIn.md | 44 ++++++++++++++++++++++++++++++++++++-- 1_Basic_GPIO/digitalOut.md | 3 ++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/1_Basic_GPIO/digitalIn.md b/1_Basic_GPIO/digitalIn.md index 87c9121..ec05dc7 100644 --- a/1_Basic_GPIO/digitalIn.md +++ b/1_Basic_GPIO/digitalIn.md @@ -64,6 +64,46 @@ Small delay is added to mitigate switch bouncing, as explained in [Circuit Basic - insert gif of fan toggling. -## EfficientToggle +## EfficientRead -This example reads the changes in digital states using the interrupt model. Above examples use the polling method which constantly checks the state of the pin. Interrupt only mode only triggers a particular code to run only if a particular state is observed. +This example reads the changes in digital states using the interrupt read model. All the above examples use polling method which constantly checks the state of the pin. Interrupt mode triggers a particular code to run only if a particular state is observed on a given pin. + +```c +#define BUTTON_PIN 15 +#define LED_PIN 14 + +void ReadLED(int pin, uint32_t event) +{ + if (pin == BUTTON_PIN && event & GPIO_IRQ_EDGE_RISE) + { + gpio_put(LED_PIN, 1); + } + else if (pin == BUTTON_PIN && event & GPIO_IRQ_EDGE_FALL) + { + gpio_put(LED_PIN, 0); + } +} + +int main() +{ + stdio_init_all(); + gpio_init(BUTTON_PIN); + gpio_init(LED_PIN); + + gpio_set_dir(BUTTON_PIN, GPIO_IN); + gpio_set_dir(LED_PIN, GPIO_OUT); + + gpio_set_drive_strength(LED_PIN, GPIO_DRIVE_STRENGTH_8MA); + gpio_pull_down(BUTTON_PIN); + + gpio_set_irq_enabled_with_callback(BUTTON_PIN, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, ReadLED); + while (1) + sleep_ms(1e10); +} +``` + +In the interrupt model, the code to run when an interrupt in triggered must be stored in a function, `ReadLED` in this case. The `ReadLED` function takes 2 arguments, one of them is the pin on which the interrupt is triggered, and `event` contains the what kind of interrupt is triggered. If the logic level changes from low to high, the LED pin is set to ON, else it is set to OFF. + +Most of the code in `main` is the same from older examples, to initialize, set the direction and supplementary settings like drive strength and pull. The new function here, `gpio_set_irq_enabled_with_callback` attaches the `ReadLED` function to a GPIO Pin. The first argument is the gpio pin to attach the interrupt, it is the same as the gpio pin use everywhere. Second argument is for providing the incidents when the function should run. Third argument is a to mention if this interrupt is enabled of not and the fourth argument is the function to call when the mentioned incident happens on the mentioned pin. + +Since this is detached from the main loop, the main code can move on to run other functions, which is nothing in this case. diff --git a/1_Basic_GPIO/digitalOut.md b/1_Basic_GPIO/digitalOut.md index 4b07316..7931ca8 100644 --- a/1_Basic_GPIO/digitalOut.md +++ b/1_Basic_GPIO/digitalOut.md @@ -283,8 +283,9 @@ onDelay = (onDelay+1) % totalDelay; } ``` -`onDelay` is maintained such that total time for each iteration remains constant, equal to `totalDelay`. This above code will make the LED look like the brightness changes. +The value of `onDelay` is maintained such that total time including the led off delay for each iteration remains constant, equal to `totalDelay`. This above code will make the LED look like the brightness changes. +This technique of changing the on time and off time for a given time period is called Pulse Width Modulation (PWM). The frequency of this signal is calculated as `1/totalDelay`, which is `1/(0.01 seconds)` => 100Hz. PWM can be achieved more efficiently using the dedicated PWM signal blocks available on the pico, which will be discussed in the later sections. --- ## Summary