Чтение нескольких аналоговых входных контактов

analogread loop joystick

У меня возникли некоторые проблемы при попытке прочитать несколько контактов аналогового входа (в данном случае A0 и A3). Я использую контроллер робота Pololu A-Star 32U4 LV (https://www.pololu.com/product/3116 ), и я использую Arduino IDE для программирования платы; он распознается как Arduino Leonardo. Я использую библиотеку джойстиков (https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-2.0) чтобы контроллер распознавался Windows как геймпад (я думаю, это не имеет отношения к проблеме, с которой я столкнулся).

Я моделирую ось с помощью потенциометра, при этом линия данных идет к аналоговому входу, базовая линия 5 В поступает с платы, а земля находится напротив аналогового входа. Это действительно приводит к изменению значений.

Проблема, с которой я конкретно сталкиваюсь, заключается в том, что когда я пытаюсь получить аналоговое значение для каждого контакта, который я отслеживаю, оказывается, что значения других контактов изменяются одновременно. Поскольку я пытаюсь использовать значения аналоговых выводов для управления осью X/Y, эта проблема проявляется в графике X/Y, который выглядит линейным с каким-то определенным наклоном (с изменением X, ведущим к изменению Y); а не ожидаемое только горизонтальное движение по X и только вертикальное движение по Y.

Более того... когда я удаляю вторую ось (т. е. только используя X или только используя Y), кажется, что она отслеживается так, как я ожидаю: потенциометр перемещает ось (меняя значение аналогового входа).

р>

Вот где я проверяю контакты в контуре:

  // Чтение аналоговых выводов и обновление контроллера
  for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
    checkAnalogAxisState(a, axisPins, axisPinVals);
    delay(10);
  }

И вот здесь я пытаюсь отправить изменения по осям X/Y на основе показаний, поступающих с аналоговых контактов:

// Проверяет аналоговый вывод на наличие значения, которое будет использоваться в качестве значения оси. Обновляет состояние только в том случае, если оно
// обнаружено изменение. Обновит ось джойстика в зависимости от того, какой контакт она сейчас использует.
// смотря на
void checkAnalogAxisState(uint8_t pinIndex, uint8_t analogPins[], int analogPinVals[]) {
    uint8_t analogPin = analogPins[pinIndex];

    // Хитрость при использовании нескольких аналоговых датчиков заключается в том, чтобы прочитать их дважды с небольшой задержкой после каждого чтения (хорошо 10 мс)
    // затем отбрасываем первое чтение. Это связано с тем, что мультиплексору АЦП требуется время переключения и напряжение.
    // время стабилизации после переключения.
    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;
    }
}

Я пытаюсь сохранить вывод и значение этого вывода в массиве, но даже когда я делаю это с двумя отдельными вызовами переменных и функций, я все равно вижу, что аналоговые значения изменяются одновременно.

Вот полный эскиз, я могу включить полное содержимое ControllerDefines.h и ControllerFunctions.h, если они будут полезны, но я извлек соответствующие функции из каждого:

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

void setup() {
  // Настройка контактов для элементов управления Axis
  for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
    pinMode(axisPins[a], INPUT);
  }

  // Настройка джойстика
  Joystick.begin();
  Joystick.setXAxisRange(-ANALOG_ADJUSTMENT, ANALOG_ADJUSTMENT);
  Joystick.setYAxisRange(-ANALOG_ADJUSTMENT, ANALOG_ADJUSTMENT);

  // Настройка последовательной связи
  Serial.begin(9600);
}

void loop() {
  // Читаем все состояния кнопок и обновляем контроллер
  for(uint8_t b = 0; b < TOTAL_BUTTONS; b++) {
    checkButtonState(b, buttons, buttonStates);
  }

  // Чтение аналоговых выводов и обновление контроллера
  for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
    checkAnalogAxisState(a, axisPins, axisPinVals);
    delay(10);
  }

  // Задержка перед повторным опросом кнопок
  delay(50);
}

Изменить:

Я построил график изменения значений двух массивов с течением времени, как можно увидеть здесь. Это когда Pot подключен к A3, то есть axisPinVals[0]: Построенные значения

Перемещение горшка на A0 дает следующее: Построенные значения 2

Используя измененный код ниже:

  // Чтение аналоговых выводов и обновление контроллера
  for(uint8_t a = 0; a < TOTAL_AXIS_PINS; a++) {
    checkAnalogAxisState(a, axisPins, axisPinVals);
    delay(10);
  }

  // Для плоттера
  Serial.print(axisPinVals[0]);
  Serial.print(",");
  Serial.println(axisPinVals[1]);

Как видите, эти два значения совпадают. Подобного поведения нет при нажатии кнопок, и одновременно можно без проблем удерживать несколько кнопок.

Я ожидаю, что каждая переменная (линия) будет отслеживаться независимо друг от друга, когда горшок перемещается из A0 в A3.

, 👍0

Обсуждение

Просто чтобы уточнить: во время тестирования у вас подключены два горшка? Если нет, вы читаете «плавающий» ввод, который не даст действительных результатов., @Nick Gammon

Думаю, вы разбираетесь в этом вопросе, завтра разберёмся окончательно., @Brendan Lesniak


2 ответа


Лучший ответ:

1

Я не могу воспроизвести вашу проблему. Ваш код немного длинный, чтобы точно сказать, конфликтуют ли A0 и A3 при быстром последовательном чтении. Попробуйте этот тестовый код и посмотрите, какие результаты вы получите:

void setup() {
 Serial.begin (115200);
 while (!Serial) {}  // ждем 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);
}

На моем Micro (с тем же процессором) я обнаружил, что два входа полностью независимы. Например, изменение A3:

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

А затем меняем 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

Это было с двумя постоянно подключенными потенциометрами. Если бы у вас был только один, вы могли бы получить «плавающий» ввод.

Я предлагаю вам попробовать приведенный выше код и проверить, получите ли вы аналогичные результаты. Если да, то проблема не в «Чтении нескольких выводов аналогового входа», а в чем-то совершенно другом, например в логике вашего кода.

Даже когда я изменил задержку в своем коде на 10, полученные цифры по-прежнему были независимыми. То есть один горшок вообще не влиял на другой.

,

Это то, что я ожидал увидеть, попробую; может быть дело в том, как у меня все настроено, или проблема в самой плате. К счастью, у меня есть пара микросхем, поскольку в конечном итоге они лучше подходят для моего проекта., @Brendan Lesniak

Ну, это определенно доска. При выполнении вашего кода оба числа по-прежнему отслеживают друг друга, даже если у меня есть один банк, меняющий значения. Спасибо за помощь и тестовый код. Я приму это через некоторое время., @Brendan Lesniak

Для корректного теста вам необходимо иметь пот на каждом входе *одновременно*., @Nick Gammon

Ваш джойстик, конечно, сделает это. Ваша проблема может заключаться в том, что вы тестируете один банк, и такой тест не воспроизводит реальную ситуацию правильно., @Nick Gammon

Ах да, я тоже могу попробовать, на самом деле это имело бы слишком много смысла. Я попробую это здесь завтра., @Brendan Lesniak

В этом была проблема; Я читал плавающую булавку., @Brendan Lesniak


0

Попробуйте прочитать каждое входное значение дважды подряд и использовать значение из второго чтения. Источнику входного сигнала может потребоваться дополнительное время для зарядки семпла и усилителя. удерживайте крышку, которая считывается АЦП в uC.

,