Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP32 C3 digitalRead() returns always 0, should return the pin level #5552

Closed
helmut64 opened this issue Aug 16, 2021 · 30 comments · Fixed by #6602
Closed

ESP32 C3 digitalRead() returns always 0, should return the pin level #5552

helmut64 opened this issue Aug 16, 2021 · 30 comments · Fixed by #6602
Assignees
Labels
Chip: ESP32-C3 Issue is related to support of ESP32-C3 Chip Status: Test needed Issue needs testing
Milestone

Comments

@helmut64
Copy link

When I do a digitalWrite() to set the GPIO pin (e.g. 2) to HIGH, a digitalRead(2) returns always 0
It should return the pin level as it does not the regular ESP32 or the S2
Arduino-esp32 version: 2.0.0-alpha1
Regards Helmut

@atanisoft
Copy link
Collaborator

This is expected behavior as the pin is configured as output only. Reading an output pin will always return zero. The pin must be configured as INPUT_OUTPUT for the read to work. Unfortunately there is no Arduino API to configure a pin as INPUT_OUTPUT, you can however call:

gpio_set_direction(PIN, GPIO_MODE_INPUT_OUTPUT);

where PIN is the target GPIO number.

@helmut64
Copy link
Author

Hi Mike, thank you for that advise, your workaround works.
However I am using the Arduino API, digitalRead on the output set GPIO's works on Arduino (ESP32, Atmel-D21, ESP32-S2, etc). On Mbed OS this is also supported. I believe it would be great if the C3 behaves like the other boards/platforms.

Again, thank you for your advise.
PS: I am using like many others reading the GPIO and setting the inverted value.
Regards from Hannover Helmut

@chegewara
Copy link
Contributor

There is simple explanation. ESP32 C3 just does not support it.
You can use this simple sketch, which is using esp-idf API, to test it:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(7, OUTPUT);
  digitalWrite(7, 0);
  delay(1000);
  Serial.print("pin level: ");
  Serial.println(gpio_get_level((gpio_num_t)7));
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(1000);
  digitalWrite(7, 1);
  Serial.print("pin level: ");
  Serial.println(gpio_get_level((gpio_num_t)7));
  digitalWrite(7, 0);
  delay(1000);
  Serial.print("pin level: ");
  Serial.println(gpio_get_level((gpio_num_t)7));
}

Like you said, it works on S2 and does not work on C3, and it cant be changed or fixed in arduino as long as it wont be "fixed" in esp-idf. This also may be C3 hardware design and cant be fixed.

@igrr

@helmut64
Copy link
Author

Again, I understand that it is not working. Ff it can be fixed in the IDF, I would recommend to do so.

@chegewara
Copy link
Contributor

Then you should report it in esp-idf, not here, if you understand it.

@helmut64
Copy link
Author

But here is the place for the ESP32-C3-Arduino, and it is an Arduino behaviour. I will have a look into the IDF source to check out what is behind.

@chegewara
Copy link
Contributor

I did show you example code with plain esp-idf API, it is not arduino, which shows the same output:
gpio_get_level((gpio_num_t)7)

@atanisoft
Copy link
Collaborator

This CAN work in arduino-esp32 but the support code for it does not exist yet. A new pin mode will be necessary (INPUT_OUTPUT or similar name) which is a combination of the current INPUT and OUTPUT modes. The underlying ESP-IDF code does not support reading the state of an OUTPUT only pin and that is why the current arduino code does not work as you might expect.

As for why this works for ESP32 and ESP32-S2 but not ESP32-C3 that is due to the ESP32-C3 code using ESP-IDF APIs whereas the others are using a local implementation which does not work for the ESP32-C3 (and long term should be removed entirely in favor of ESP-IDF APIs).

@chegewara
Copy link
Contributor

@atanisoft this is esp-idf API, which works on esp32 with pin OUTPUT only:
gpio_get_level((gpio_num_t)7)
the same API does not work on C3, so the problem is not arduino perse, and difference in esp-idf on different models.

@atanisoft
Copy link
Collaborator

@chegewara it shouldn't work even in ESP-IDF unless the pin mode is INPUT_OUTPUT since the HAL code references the hardware IN register which is not updated as part of OUTPUT only pin manipulation.

@chegewara
Copy link
Contributor

Maybe it should not work, but it works. Either way it may be consider bug and should be reported in esp-idf, not here.

To be honest until now ive been thinking the same way, that reading OUTPUT pin should not be possible and i never before even did try it, since there is INPUT_OUTPUT option.

@helmut64
Copy link
Author

A common technic ist digitalWrite(!digitalWrite()) to invert the current output.
For me this was just once reason why existing software did not work with the C3.

@lbernstone
Copy link
Contributor

I think the expected arduino behavior here is that you can digitalRead an output pin. That probably means the implementation is INPUT_OUPUT once the core is fully refactored on the idf hal.

@atanisoft
Copy link
Collaborator

The ESP32-C3 uses ESP-IDF APIs but ESP32 and ESP32-S2 use direct register access. This issue should be used to standardize on ESP-IDF APIs AND default OUTPUT mode to be INPUT_OUTPUT.

@chegewara
Copy link
Contributor

@atanisoft are you sure? As far as i understand C3 is not using esp-idf, but i may be wrong:
https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c#L324

@atanisoft
Copy link
Collaborator

@chegewara Certain... https://github.com/espressif/arduino-esp32/blob/master/cores/esp32/esp32-hal-gpio.c#L41 This if/elif block enters this line when using the C3.

@chegewara
Copy link
Contributor

ok, i did some more testing
@helmut64 my bad, it looks like the problem is with arduino-esp32, not esp-idf, sorry

there is something odd with pinMode, because setting mode with esp-idf gpio_set_direction call and read value from OUTPUT only pin is consistent on S2, C3 and probably esp32 too, always 0.

@VojtechBartoska VojtechBartoska added the Status: Test needed Issue needs testing label Aug 18, 2021
@helmut64
Copy link
Author

I did some testing once again, it is only a C3 problem, the S2 or the regular ESP32 and other MCUs don't show this behaviour.

void setup() {
  Serial.begin(115200);
  pinMode(2, OUTPUT);
}

void loop() {
  digitalWrite(2, HIGH);
  Serial.printf("Pin: %d\n", digitalRead(2));
  delay(1000);
  digitalWrite(2, LOW);
  Serial.printf("Pin: %d\n", digitalRead(2));
  delay(1000);
}

@VojtechBartoska
Copy link
Contributor

Hello @helmut64 , sorry for late reply. Are you able to test your issue on development version 2.0.3-RC1 to check if this is still valid? You can take a look on Docs where is explained how to choose development release version in Arduino IDE.

@VojtechBartoska VojtechBartoska added Chip: ESP32-C3 Issue is related to support of ESP32-C3 Chip Resolution: Awaiting response Waiting for response of author labels Mar 30, 2022
@helmut64
Copy link
Author

Hello @VojtechBartoska the problem still exists with the 2.0.3-RC1 release

@VojtechBartoska VojtechBartoska removed the Resolution: Awaiting response Waiting for response of author label Mar 30, 2022
@VojtechBartoska VojtechBartoska added this to the 2.0.3 milestone Mar 30, 2022
@VojtechBartoska
Copy link
Contributor

Thanks for testing, adding it to our Roadmap and we will investigate it more.

@atanisoft
Copy link
Collaborator

atanisoft commented Mar 30, 2022

@helmut64 That is expected behavior for a GPIO that has been configured as OUTPUT. It needs to be configured as INPUT_OUTPUT to have digitalRead(PIN) return a value that has been set via digitalWrite(PIN).

@VojtechBartoska INPUT_OUTPUT is not currently implemented in arduino-esp32, IDF supports this functionality and it would likely be a one-line change in esp32-hal-gpio.c to remap OUTPUT to INPUT_OUTPUT transparently for the user. This is also not specific to the C3, it occurs on all ESP32 variants.

@VojtechBartoska
Copy link
Contributor

Thanks @atanisoft for your extensive explanation. @P-R-O-C-H-Y Can you please take a look as you refactored GPIO?

@atanisoft
Copy link
Collaborator

@P-R-O-C-H-Y Change

#define OUTPUT 0x02
to 0x3 which maps to https://github.com/espressif/esp-idf/blob/e3c0229d2ec9bfd0203a3cab18d6642798457578/components/hal/include/hal/gpio_types.h#L376. Perhaps it would make more sense to use the IDF type values directly?

@helmut64
Copy link
Author

Dear @atanisoft I understand, however in Arduino ESP32, Atmel D21 and all others Arduino's the GPIO OUTPUT reading is working. I watched that this compatibility problem exists only with the C3

@atanisoft
Copy link
Collaborator

this compatibility problem exists only with the C3

That is due to C3 being the only ESP32 variant that uses the IDF APIs so far. It is not a bug in so far as how the pin is configured, it is strictly OUTPUT only and IDF does not track the state for OUTPUT only pins. It must be configured as INPUT_OUTPUT for IDF APIs to track and return the state.

@P-R-O-C-H-Y
Copy link
Member

@atanisoft Do you think its best to change OUTPUT to 0x03 (to be input_output) or add INPUT_OUTPUT option separately?

@helmut64
Copy link
Author

As Arduino pinMode has no INPUT_OUTPUT, I believe when pinMode OUTPUT is specified it should handle it as GPIO_MODE_INPUT_OUTPUT. This would be compatible with other existing Arduino MCUs. @P-R-O-C-H-Y

@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Apr 12, 2022

@helmut64 I will make the change, it makes sense to be as close as we can to Arduino official API. Will do some tests before placing PR to make sure, changing that doesn't break anything else :)

@VojtechBartoska VojtechBartoska moved this from Todo to Under investigation in Arduino ESP32 Core Project Roadmap Apr 20, 2022
@VojtechBartoska VojtechBartoska moved this from Under investigation to In Progress in Arduino ESP32 Core Project Roadmap Apr 20, 2022
Repository owner moved this from In Progress to Done in Arduino ESP32 Core Project Roadmap Apr 21, 2022
@AcidCaos
Copy link

Hi, I recently updated from 2.0.2 to 2.0.3, and a pinMode(16, OUTPUT) on my code, which worked fine before, does not now: it makes my board reboot. I'm using a TTGO LoRa T3_V1.6.1. I've tried to put 0x02 instead of OUTPUT, but it still does not work, so not really sure if it is related with this commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Chip: ESP32-C3 Issue is related to support of ESP32-C3 Chip Status: Test needed Issue needs testing
Projects
Development

Successfully merging a pull request may close this issue.

7 participants