Skip to content

analogRead() does not reset pin properly after previous pinMode() #829

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

Open
dhalbert opened this issue Jan 15, 2024 · 3 comments
Open

analogRead() does not reset pin properly after previous pinMode() #829

dhalbert opened this issue Jan 15, 2024 · 3 comments

Comments

@dhalbert
Copy link

BSP: Arduino MBed OS Giga boards v4.0.10
Board: Giga R1
Arduino IDE: 2.2.1

Sample sketch:

void setup() {
  Serial.begin(9600);
  while (!Serial) { }

  // Attach A0 to 3.3V through a 220K or other high-value resistor,
  // so it's not stronger than the driven output.

  delay(100);
  Serial.println(analogRead(A0));

  pinMode(A0, INPUT);

  delay(100);
  Serial.println(analogRead(A0));

  Serial.println("Done");
}

void loop() {
}

On my test setup, this prints:

744
92
Done

I would expect it to print 744 or close to that twice.
Once the pin is used in the pinMode(), it appears to be pulled low.

By comparison, the same sketch on an Arduino Uno prints (with the 220K resistor connected to 5V):

1023
1023
Done

The use case is a resistive touch screen driver (https://github.com/adafruit/Adafruit_TouchScreen) which flips pins back and forth between digital input/output and analog input modes to read X/Y resistance values.

This is reminiscent of (though order is different) to #328 and arduino/ArduinoCore-renesas#58

@MattGlobal
Copy link

Hello @dhalbert , i modified your text and it seems to be working :

void setup() 
{
Serial.begin(9600);
pinMode(A0, INPUT);
}

void loop() {
  // Attach A0 to 3.3V through a 220K or other high-value resistor,
  // so it's not stronger than the driven output.

 delay(100);
  Serial.println(analogRead(A0));



delay(100);
  Serial.println("Done");

}

the problem is still the same with touchsceen... but i'm wondering if it's not just about a pins definition problem ?

@dhalbert
Copy link
Author

@MattGlobal In the example you gave, there is no pinMode() between analogRead() calls. In my example, the pin usage alternates between pinMode() and analogRead(). My hypothesis is that the second call to analogRead() is assuming the pin is already set up where as in fact its settings where changed "behind the back" of analogRead().

@dhalbert
Copy link
Author

dhalbert commented Jan 26, 2024

Here is the impl:

int analogRead(pin_size_t pin)
{
if (pin >= PINS_COUNT) {
return -1;
}
PinName name = analogPinToPinName(pin);
if (name == NC) {
return -1;
}
mbed::AnalogIn* adc = analogPinToAdcObj(pin);
if (adc == NULL) {
adc = new mbed::AnalogIn(name);
analogPinToAdcObj(pin) = adc;
#ifdef ANALOG_CONFIG
if (isAdcConfigChanged) {
adc->configure(adcCurrentConfig);
}
#endif
}
return (adc->read_u16() >> (16 - read_resolution));
}

The first time through, a new mbed::AnalogIn object is created. That's reused on subsequent calls.

A workaround might be to call analogUpdate() before every call to analogRead(). I'll try that. (EDIT: ANALOG_CONFIG isn't defined, so analogUpdate() is not included, so it requires some surgery in the sources, which is not a clean workaround for the average user.) But there's an assumption being made in the code in this file that the pin state is not changing out from under analogRead().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants