The Pico/W In C: GPIO Input
Written by Harry Fairhead   
Monday, 08 July 2024
Article Index
The Pico/W In C: GPIO Input
Basic Input Functions
Press Or Hold
How Fast Can We Measure?

Basic Input Functions

We have already met the functions that set a GPIO line to input or output:

gpio_set_function (uint gpio, GPIO_FUNC_SIO)

or:

gpio_init (uint gpio)

After both we have a GPIO line set to software control and initialized to input.

You can also set the direction using:

gpio_set_dir (uint gpio, bool out)

The line is set to output if out is true and input if it is false.

Once set to input, the GPIO line is high impedance, it won’t take very much current, no matter what you connect it to. However, notice that the Pico uses 3.3V logic and you should not exceed this value on an input line – for a full discussion of how to work with input see the previous chapter.

You can read its input state using:

static bool 	gpio_get (uint gpio)

This is all there is to using a GPIO line as an input, apart from the details of the electronics and the small matter of interrupts. Notice that the function works even if the GPIO line is set to output – it reads the current level of the line as high or low.

There is also:

static uint32_t gpio_get_all ()

which will read the state of all of the GPIO lines in a single operation.

As introduced in the previous chapter you can also set the internal pull-up or pull-down resistors using one of:

gpio_pull_down (uint gpio)
gpio_pull_up (uint gpio)  
gpio_set_pulls (uint gpio, bool up, bool down)

The pull-up/down resistors are between 50 and 80kΩ.

If you want a pure push-pull mode you can turn off the resistors using:

gpio_disable_pulls (uint gpio)

The Simple Button

One of the most common input circuits is the switch or button. If you want add a button you can use any GPIO line and the circuit explained in the previous chapter. That is, the switch has to have either a pull-up or pull-down resistor either provided by you or a built-in one enabled using software.

The simplest switch input program using an internal pull-up is:

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21,false);
    gpio_pull_up(21);
gpio_set_function(22, GPIO_FUNC_SIO); gpio_set_dir(22, true);
while (true) {
if (gpio_get(21)) { gpio_put(22, 0); } else { gpio_put(22, 1); } }
}


As the internal pull-up resistor is used, the switch can be connected to the line and ground without any external resistors:

switch1

The program simply tests for the line, GP21, to be pulled low by the switch being closed and then sets GP22 high. If you connect GP22 to an LED or a logic analyzer you will see the effect of the button being closed – the LED will light up while it is pressed.


If you change gpio_pull_up(21) to gpio_pull_down(21), the way the switch is connected becomes:switch2

The program still works, but now GP21 is high when the switch is pressed and hence the LED is on when the switch is not pressed.

Should you use an internal or external resistor? The answer is that it mostly doesn’t matter as long as there is a resistor. The only problem with using an internal resistor is the possibility that the software fails to set the pull-up/down mode and leaves the input floating.

Also notice that this switch input is not debounced. The simplest way to do this is include a time delay in the loop before the line is sampled again.

If you want to respond to a button press, that is a press and a release event, then you have to test for a double transition:

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_down(21);
gpio_set_function(22, GPIO_FUNC_SIO); gpio_set_dir(22, true); gpio_put(22, 0); while (true) {
while (gpio_get(21)==0){}; while (gpio_get(21) == 1){}; gpio_put(22, 1); sleep_ms(1000); gpio_put(22, 0); } }

In this case you really do need the debounce delays if you want to avoid responding twice to what the user perceives as a single press.

A 1‑millisecond delay is probably the smallest delay that produces a button that feels as if it works. In practice, you would have to tune the delay to suit the button mechanism in use and the number of times you can allow the button to be pressed in one second.



Last Updated ( Wednesday, 10 July 2024 )