0

I am having a bit of trouble trying to read multiple Analog Input Pins (A0 and A3, in this instance). I am using a Pololu A-Star 32U4 LV Robot Controller (https://www.pololu.com/product/3116), and am using the Arduino IDE to program the board; it is recognized as a Arduino Leonardo. I am using the Joystick Library (https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-2.0) to have the controller be recognized by Windows as a Game Pad (irrelevant to the issue I am seeing, I believe).

I am simulating an Axis by using a potentiometer, with the data line running into the Analog Input, the 5V baseline coming from the board, and the Ground on the opposite of the Analog Input. This does indeed cause the values to change.

The issue that I am specifically running into is when I attempt to get the analog value for each pin that I am monitoring, it appears that the values of the other pins change at the same time. Because I am trying to use the Analog Pin values to drive an X/Y Axis, this issue manifests itself in an X/Y graph that appears linear with some sort of defined slope (with an X change leading to a Y change); rather than the expected X Horizontal only movement and Y Vertical only movement.

Further.. when I remove the second Axis (ie. only using X or only using Y), it appears to track as I expect, with the Pot moving the axis (changing the value of the Analog Input).

Here is where I check the pins in the loop:

  // Read the Analog Pins and update the controller 
  for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
    checkAnalogAxisState(a, axisPins, axisPinVals);
    delay(10);
  }

And here is where I attempt to send the X/Y Axis changes based off of the readings coming from the Analog Pins:

// Checks the Analog Pin for a value to be used as the Axis value. Only updates the state if it
// has been found to have changed. Will update the Joystick Axis based on which pin it is currently
// looking at
void checkAnalogAxisState(uint8_t pinIndex, uint8_t analogPins[], int analogPinVals[]) {
    uint8_t analogPin = analogPins[pinIndex];

    // The trick when using multiple analog sensors is to read them twice, with a small delay after each read (10ms is good)
    // then discard the first reading. This is because the ADC multiplexer needs switching time and the voltage needs 
    // time to stabilize after switching.
    int currentState = analogRead(analogPin);
    delay(10);
    currentState = analogRead(analogPin);
    delay(10);

    if(currentState <= analogPinVals[pinIndex] - 5 || currentState >= analogPinVals[pinIndex] + 5) {
        if(analogPin == X_AXIS_PIN) {
            Joystick.setXAxis(currentState - ANALOG_ADJUSTMENT);
        } else if(analogPin == Y_AXIS_PIN) {
            Joystick.setYAxis(currentState - ANALOG_ADJUSTMENT);
        }
        analogPinVals[pinIndex] = currentState;
    }
}

I try to keep the Pin and the Value of that pin in an array, but even when I do this with 2 separate variable and function calls, I still see that the Analog values change at the same time.

Here is the full sketch, I can include the full contents of ControllerDefines.h and ControllerFunctions.h if they will be helpful, but I have pulled the relevant functions from each:

#include <AStar32U4.h>
#include <Joystick.h>
#include "libraries/ControllerDefines.h"
#include "libraries/ControllerFunctions.h"

void setup() {
  // Setup pins for the Axis controls
  for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
    pinMode(axisPins[a], INPUT);
  }

  // Setup Joystick
  Joystick.begin();
  Joystick.setXAxisRange(-ANALOG_ADJUSTMENT, ANALOG_ADJUSTMENT);
  Joystick.setYAxisRange(-ANALOG_ADJUSTMENT, ANALOG_ADJUSTMENT);

  // Setup Serial Comm 
  Serial.begin(9600);
}

void loop() {
  // Read all button states and update the controller
  for(uint8_t b = 0; b < TOTAL_BUTTONS; b++) {
    checkButtonState(b, buttons, buttonStates);
  }

  // Read the Analog Pins and update the controller 
  for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
    checkAnalogAxisState(a, axisPins, axisPinVals);
    delay(10);
  }

  // Delay before polling buttons again
  delay(50);
}

Edit:

I have taken a plot of the 2 Array values over time, as can be seen here. This is with the Pot hooked up to A3, which is axisPinVals[0]: Plotted Values

Moving the Pot to A0 gives the following: Plotted Values 2

Using the modified code below:

  // Read the Analog Pins and update the controller 
  for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
    checkAnalogAxisState(a, axisPins, axisPinVals);
    delay(10);
  }

  // For the plotter
  Serial.print(axisPinVals[0]);
  Serial.print(",");
  Serial.println(axisPinVals[1]);

As you can see, the two values track together. This same behavior is not present in the buttons presses, and multiple buttons can be held at the same time with no issue.

I would expect each variable (line) to track independently of one another, when the Pot is moved from A0 to A3.

  • 1
    Just to clarify, do you have two pots connected while testing? If not, you are reading "floating" input which will not give valid results. – Nick Gammon Jan 6 at 4:12
  • I think you're on to the issue, will figure out definitively tomorrow – Brendan Lesniak Jan 6 at 5:23
1

I can't reproduce your problem. Your code is a bit lengthy to say for certain whether or not A0 and A3 clash when read in quick succession. Try this test code and see what results you get:

void setup() {
 Serial.begin (115200);
 while (!Serial) {}  // wait for Serial

 Serial.println ("Starting");
}

void loop() {

int a, b;

  a = analogRead (0);
  b = analogRead (3);

  Serial.print ("A0 = ");
  Serial.println (a);
  Serial.print ("A3 = ");
  Serial.println (b);
  delay (100);
}

I found on my Micro (which has the same processor) that the two inputs were completely independent. For example changing A3:

A0 = 0
A3 = 195
A0 = 0
A3 = 453
A0 = 0
A3 = 680
A0 = 0
A3 = 879

And then changing A0:

A3 = 0
A0 = 64
A3 = 0
A0 = 292
A3 = 0
A0 = 427
A3 = 0
A0 = 474
A3 = 0
A0 = 294
A3 = 0
A0 = 48

This was with two potentiometers connected at all times. If you only had one you might get a "floating" input.

I suggest you try the code above and confirm whether or not you get similar results. If you do, then the problem is not "Reading Multiple Analog Input Pins" but something else entirely, like logic in your code.

Even when I changed the delay in my code to 10, the figures reported were still independent. That is, one pot did not influence the other at all.

  • This is what I expected to see, I'll give it a shot; could be how I have things setup or a problem with the board itself. Luckily, I have a couple Micros on the way as they better suit my project in the end. – Brendan Lesniak Jan 6 at 4:41
  • Well, it's definitely the board. Running your code, both numbers still track each other, even when I have a single Pot changing the values. Thanks for the help and the test code. I'll accept this after a bit here. – Brendan Lesniak Jan 6 at 4:44
  • You need to have a pot in each input at the same time for a valid test. – Nick Gammon Jan 6 at 4:50
  • Your joystick would, of course, do that. Your problem might be that you are testing with a single pot, and such a test is not reproducing the live situation correctly. – Nick Gammon Jan 6 at 4:51
  • Ah yeah I can give that a shot too, that would make too much sense actually. I'll try that out here tomorrow. – Brendan Lesniak Jan 6 at 5:23
0

Try reading each input twice in a row, and use the value from the 2nd read. The input source may need additional time to charge up the sample & hold cap that is read by the ADC in the uC.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.