Чтение нескольких аналоговых входных контактов
У меня возникли некоторые проблемы при попытке прочитать несколько контактов аналогового входа (в данном случае 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 дает следующее:
Используя измененный код ниже:
// Чтение аналоговых выводов и обновление контроллера
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.
@Brendan Lesniak, 👍1
Обсуждение2 ответа
Лучший ответ:
Я не могу воспроизвести вашу проблему. Ваш код немного длинный, чтобы точно сказать, конфликтуют ли 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
Попробуйте прочитать каждое входное значение дважды подряд и использовать значение из второго чтения. Источнику входного сигнала может потребоваться дополнительное время для зарядки семпла и усилителя. удерживайте крышку, которая считывается АЦП в uC.
- Отправка значения с одного Arduino на другой
- Использование аналогового входа для чтения кнопки
- Как работать с аналоговыми контактами в цикле?
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Распиновка аналога Arduino Pro Micro
- analogRead всегда 1023 на Arduino Due
- Мигните светодиодом 5 раз с помощью цикла for
- Чтение частоты ввода в цифровых выводах
Просто чтобы уточнить: во время тестирования у вас подключены два горшка? Если нет, вы читаете «плавающий» ввод, который не даст действительных результатов., @Nick Gammon
Думаю, вы разбираетесь в этом вопросе, завтра разберёмся окончательно., @Brendan Lesniak