gpio_get_level() always returns 0 if pin mode is GPIO_MODE_OUTPUT?

User avatar
i_am_mrp
Posts: 22
Joined: Thu Sep 28, 2017 9:14 am
Location: California

gpio_get_level() always returns 0 if pin mode is GPIO_MODE_OUTPUT?

Postby i_am_mrp » Thu Oct 19, 2017 6:09 am

When a pins mode is GPIO_MODE_OUTPUT and you call gpio_set_level(pin, 1), gpio_get_level(pin) always returns 0. Reading a pins value should not require it to be input or input-output mode, correct?

I have verified the output pins voltage does go high when set, but gpio_get_level(pin) says it is 0. Note that if I change the pins mode to GPIO_MODE_INPUT_OUTPUT then I get the expected behavior.

Environment is IDF v2.1, SparkFun ESP32 Thing board. Example code and output follows:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"

// For ESP32 SparkFun ESP32 Thing Board: 12, 27
#define GPIO_OUTPUT_IO_0 12
#define GPIO_OUTPUT_IO_1 27
#define GPIO_OUTPUT_PIN_SEL ((1<<GPIO_OUTPUT_IO_0) | (1<<GPIO_OUTPUT_IO_1))

void app_main() { // app_main_gpio_toggle
gpio_config_t io_conf;
io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
// *** If GPIO_MODE_OUTPUT, then gpio_get_level(..) for either pin
// ALWAYS returns 0. Seems you must use GPIO_MODE_INPUT_OUTPUT
io_conf.mode = GPIO_MODE_OUTPUT;
io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
io_conf.pull_down_en = 0;
io_conf.pull_up_en = 1 ;
ESP_ERROR_CHECK(gpio_config(&io_conf));

ESP_ERROR_CHECK(gpio_set_level(GPIO_OUTPUT_IO_0, 0));
ESP_ERROR_CHECK(gpio_set_level(GPIO_OUTPUT_IO_1, 0));
printf("GPIO_OUTPUT_IO_0: %d\n", gpio_get_level(GPIO_OUTPUT_IO_0)) ; // 0 as expected
printf("GPIO_OUTPUT_IO_1: %d\n", gpio_get_level(GPIO_OUTPUT_IO_1)) ; // 0 as expected

printf("----------------\n") ;

ESP_ERROR_CHECK(gpio_set_level(GPIO_OUTPUT_IO_0, 1));
ESP_ERROR_CHECK(gpio_set_level(GPIO_OUTPUT_IO_1, 1));

printf("GPIO_OUTPUT_IO_0: %d\n", gpio_get_level(GPIO_OUTPUT_IO_0)) ; // 0 NOT expected
printf("GPIO_OUTPUT_IO_1: %d\n", gpio_get_level(GPIO_OUTPUT_IO_1)) ; // 0 NOT expected

vTaskDelay(10000 / portTICK_RATE_MS); // so we can see last printf's
}

Output:
I (7) gpio: GPIO[12]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (7) gpio: GPIO[27]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
GPIO_OUTPUT_IO_0: 0
GPIO_OUTPUT_IO_1: 0
----------------
GPIO_OUTPUT_IO_0: 0
GPIO_OUTPUT_IO_1: 0

stefanct
Posts: 5
Joined: Sun Mar 18, 2018 1:48 pm

Re: gpio_get_level() always returns 0 if pin mode is GPIO_MODE_OUTPUT?

Postby stefanct » Sun Mar 18, 2018 3:53 pm

I fell for this today as well. The API documentation states "GPIO get input level." This is a good hint but could be made way more obvious. I made a merge request to improve on that: https://github.com/espressif/esp-idf/pull/1740

stefanct
Posts: 5
Joined: Sun Mar 18, 2018 1:48 pm

Re: gpio_get_level() always returns 0 if pin mode is GPIO_MODE_OUTPUT?

Postby stefanct » Tue Mar 20, 2018 11:31 pm

And it was merged into the master branch within 30 hours or so... https://github.com/espressif/esp-idf/co ... 38b69d4807

kudos to espressif for this kind of community engagement and support, thank you.

Who is online

Users browsing this forum: Majestic-12 [Bot] and 7 guests