Skip to content

Very inaccurate analogRead on GPIO36 with latest core installation #5503

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

Closed
proboscide99 opened this issue Aug 5, 2021 · 4 comments · Fixed by #5522
Closed

Very inaccurate analogRead on GPIO36 with latest core installation #5503

proboscide99 opened this issue Aug 5, 2021 · 4 comments · Fixed by #5522
Labels
Milestone

Comments

@proboscide99
Copy link

proboscide99 commented Aug 5, 2021

Hardware:

ESP32-WROOM-32E
Programmed with board type 'DOIT ESP32 DEVKIT V1'
using arduino ide V1.8.13 and 1.8.15 under Windows and Ubuntu (all combination, same result)

Description:

Hello,

I have a project in which I use GPIO36 (ADC1_CHANNEL_0) as analog input and everything worked fine until I updated the esp32 core to latest version (4.4), 2021/07/29 commit.
I was previously running the one-year old V3.3.

With the new core, the value returned by 'analogRead(36)' is totally wrong.

Testbench:

800mV applied on GPIO36.
Considering the ~100mV known insensitivity on the lower side, the expected ADC value is around 900 on 4095 full scale.

Sketch output with older core (v3.3.1-61-g367c3c09c):

11:11:22.115 -> 846
11:11:22.626 -> 845
11:11:23.102 -> 844
11:11:23.609 -> 846
11:11:24.121 -> 846

Output with latest core (v4.4-dev-2313-gc69f0ec32):

11:16:52.644 -> 3183
11:16:53.153 -> 3180
11:16:53.663 -> 3181
11:16:54.168 -> 3179
11:16:54.644 -> 3179
11:16:55.154 -> 3181

It takes a very low voltage to bring down the read value, that reaches zero if the pin is connected to ground (as it should).
The problem is: the response curve is totally wrong.

I read in the esp32 documentation that this pin is shared with an internal hall sensor, but for some reason, this was not an issue with the older core.

I compared the adc-related source code and found that the hallRead function in the older core used to initialize and deinitialize some internal registers, while the newer one does not. I then tried to do the same (executing the de-init code in the sketch) in the hope to get the hall sensor disabled but got no result.

Is there a way to get back the analog GPIO36 capability as it was on the V3.3 core?
I'm trying to compare the core's source but so far I couldn't spot it.

Thanks a lot and Best Regards!

Sketch:

void setup()
{
  Serial.begin(115200);

  pinMode(36, ANALOG);
}
//
void loop(void)
{
  delay(500);
  Serial.println(analogRead(36));
}

@felmue
Copy link

felmue commented Aug 6, 2021

Hello @proboscide99

I think what has changed is the default attenuation. It used to be 11dB but it looks like it is now set to 0dB by default.

Try adding this line in your setup code:

analogSetAttenuation(ADC_11db);

Thanks
Felix

@proboscide99
Copy link
Author

Thanks a lot! The 'analogSetAttenuation' didn't solve the problem, but then I searched for a pin-specific setting (because GPIO36 was the only pin affected by the attenuation shift) and that solved the problem!!!

analogSetPinAttenuation(AN_JOYSTICK_PIN, ADC_11db);

For a reason I can't explain, the "global" function you suggested didn't work, while IMHO it should have.

Thanks again
Alessandro

@felmue
Copy link

felmue commented Aug 6, 2021

Hello @proboscide99

interesting - thank you for sharing. I am glad to hear you got it working.

Thanks
Felix

@marcboon
Copy link

marcboon commented Aug 10, 2021

Thanks a lot! The 'analogSetAttenuation' didn't solve the problem, but then I searched for a pin-specific setting (because GPIO36 was the only pin affected by the attenuation shift) and that solved the problem!!!

analogSetPinAttenuation(AN_JOYSTICK_PIN, ADC_11db);

For a reason I can't explain, the "global" function you suggested didn't work, while IMHO it should have.

In 2.0.0-rc1 The function analogSetAttenuation() only sets a local (static) variable to that value. The value is used in the calibration functions, but not for a simple analogRead(). Use the analogSetPinAttenuation() function for each pin you intend to use. You only need to set it once (for example in setup()).
The default attenuation for all pins is 0dB, which gives a full-scale output at about 800mV input voltage. With 11dB attenuation the full-scale range is about 2.55V.

I'm using a ESP32-S2, where the ADC width is 13 bit by default, so full scale gives 8191 as a result. I didn't test other ESP32 versions.

me-no-dev added a commit that referenced this issue Aug 11, 2021
@me-no-dev me-no-dev added Status: In Progress ⚠️ Issue is in progress Type: Bug 🐛 All bugs labels Aug 11, 2021
@me-no-dev me-no-dev added this to the 2.0.0 milestone Aug 11, 2021
me-no-dev added a commit that referenced this issue Aug 11, 2021
newHeiko added a commit to newHeiko/wiFred that referenced this issue Aug 21, 2021
@VojtechBartoska VojtechBartoska removed the Status: In Progress ⚠️ Issue is in progress label Aug 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants