110 lines
4.6 KiB
Markdown
110 lines
4.6 KiB
Markdown
## Read Button
|
|
|
|
This example uses `gpio_get` api call to read and return the logic level of a gpio pin. A button is used to control the logic level of the pin. The connections are made as below. An additional concept called pulling is used to properly switch between high and low.
|
|
|
|
```c
|
|
int buttonPin = 15;
|
|
int ledPin = 14;
|
|
gpio_init(buttonPin);
|
|
gpio_init(ledPin);
|
|
gpio_set_dir(buttonPin, GPIO_IN);
|
|
gpio_pull_down(buttonPin);
|
|
gpio_set_dir(ledPin, GPIO_OUT);
|
|
|
|
while (true){
|
|
gpio_put(ledPin, gpio_get(buttonPin));
|
|
sleep_ms(10);
|
|
}
|
|
```
|
|
|
|
The usual `gpio_init` and `gpio_set_dir` are used to initialize and set the direction of the pins. Here, the pin which connects to the button gets set as input using `GPIO_IN`. The button is also configured in pull down configuration. [This guide](https://eepower.com/resistor-guide/resistor-applications/pull-up-resistor-pull-down-resistor) explains the use of pull up and pull down resistors.
|
|
|
|
- insert gif of controlling led with button
|
|
|
|
The same code can be used for controlling the fan from earlier experiment. LED connected to the `ledPin` is replaced with connection to the gate pin of the mosfet.
|
|
|
|
- insert gif of controlling fan with button
|
|
|
|
## ToggleButton
|
|
|
|
Instead of setting the fan status to be the same as the the button status, this example toggles everytime the button is pressed.
|
|
|
|
Below code demonstrates using a button to toggle the state of the fan between on and off.
|
|
|
|
```c
|
|
int buttonStatus = gpio_get(buttonPin);
|
|
bool outputStatus = false;
|
|
int state = buttonStatus * 2 + gpio_get(buttonPin);
|
|
while (true)
|
|
{
|
|
state = buttonStatus * 2 + gpio_get(buttonPin);
|
|
switch (state)
|
|
{
|
|
case 1:
|
|
outputStatus = !outputStatus;
|
|
gpio_put(ledPin, outputStatus);
|
|
buttonStatus = 1;
|
|
sleep_ms(10);
|
|
break;
|
|
case 2:
|
|
buttonStatus = 0;
|
|
sleep_ms(10);
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
```
|
|
|
|
To toggle the state on button state changes, change in button press is recorded using `buttonStatus` variable.
|
|
|
|
If the button is pressed, `buttonState` will be `0` and new state will be `1`. Hence, the value in the `status` variable will be `1`. When this happens, the fan state is toggled. Output doesn't change when the button is released.
|
|
|
|
|
|
Small delay is added to mitigate switch bouncing, as explained in [Circuit Basics blog on switch de-bouncing](https://www.circuitbasics.com/how-to-use-switch-debouncing-on-the-arduino/).
|
|
|
|
- insert gif of fan toggling.
|
|
|
|
## EfficientRead
|
|
|
|
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.
|