Как использовать потенциометр для доступа к данным в двумерном массиве?
Я пытаюсь создать двухмерный массив нот, разделенных на 3 гаммы. В каждой гамме по 3 ноты. Есть 3 кнопки для воспроизведения каждой ноты, и я хочу использовать доступный потенциометр для выбора каждой из воспроизводимых гамм.
Несмотря на мои поиски, я не могу понять, как это сделать правильно. Пока это то, что у меня есть.
Использование Arduino Uno:
// музыкальные ноты
int C = 1046;
int D = 1175;
int E = 1319;
int F = 1397;
int G = 1598;
int A = 1760;
int B = 1976;
int C1 = 2093;
int D1 = 2349;
const int numScales = 3;
const int numNotesPerScale = 3;
const int notes[numScales][numNotesPerScale] = {
{C, D, E},
{F, G, A},
{B, C1, D1}
};
const int numberOfButtons = 3;
int buttonPin[numberOfButtons] = {2, 7, 4};
//int notes[numberOfButtons] = {C, D, E};
int ledPin[numberOfButtons] = {11, 10, 9};
int buttonState = 0; // переменная для чтения статуса кнопки
int speaker = 3; // название клавиши динамика
void setup() {
for (int i = 0; i < numberOfButtons; i++) {
pinMode(buttonPin[i], INPUT);
pinMode(ledPin[i], OUTPUT);
}
pinMode(speaker, OUTPUT); // устанавливаем динамик в качестве выхода
}
void loop() {
int numScales = map(analogRead(A2), 0, 1023, 0, 2);
//int numScales = AnalogRead(A2/341);
for (int i = 0; i < numberOfButtons; i++) {
checkButton(buttonPin[i], notes[i], ledPin[i]);
}
}
void checkButton(int buttonPin, int note, int ledPin)
{
// прочитать состояние значения кнопки:
buttonState = digitalRead(buttonPin);
// проверяем, нажата ли кнопка. Если да, то состояние кнопки ВЫСОКОЕ:
if (buttonState == HIGH){
digitalWrite(ledPin, HIGH);
tone(speaker, note); // воспроизвести ноту
delay(100); // ждем 1/10 секунды
} } else {
digitalWrite(ledPin, LOW);
noTone(speaker); // остановить воспроизведение ноты
}
}
@Robbie Perry, 👍1
Обсуждение2 ответа
Использование функции Arduino map()
кажется разумным подходом к этому, однако у вас есть проблема с индексацией.
if (numScales == 3); {
Возможно, это не то, что вам нужно, так как это условие никогда не может быть истинным, поскольку вы установили его в диапазоне от 0 до 2 до того, как дойдете до этой проверки.
Учитывая только релевантное измерение, вы представляете массив из трех элементов, в котором будут допустимые номера элементов 0, 1 и 2
Вы вызываете map(analogRead(A2), 0, 1023, 0, 2);
, который может выдавать результат в диапазоне 0-2, пока все хорошо.
Но затем проверьте значение 3, которое не только недопустимо, как в индексе массива из 3 элементов, но и не может быть создано вашим кодом.
Кроме того, вам, вероятно, следует прекратить попытки использовать переменную numScales
для выполнения двойной задачи, сохраняя как начальный размер, так и позже также текущий индекс. И вам, вероятно, следует передать это как аргумент, а не делать его глобальной переменной.
Вы также не можете использовать текущий масштаб в качестве индекса в массиве заметок. Синтаксис двойного индексирования массива будет следующим: notes[x][y]
, но, конечно, это следует делать только с указателями на существующие элементы.
Возможно, также было бы неплохо добавить некоторый отладочный вывод внутренней логики, например, распечатать как необработанные показания АЦП, так и результат сопоставления их с выбранной «шкалой».
Я боюсь, что дерьмо в программировании на самом деле не позволяет мне правильно усвоить некоторые из этих ответов. Если я удалю "int numScales = map(analogRead(A2), 0, 1023, 0, 2);" и раскомментируйте "//int notes[numberOfButtons] = {C, D, E};" тогда каждая кнопка будет играть C, D или E. Это работает нормально, пока я не решил добавить способ изменения гаммы. Является ли двумерный массив лучшим способом сделать это, и это очень сложная проблема?, @Robbie Perry
Массив 2d не является необоснованным, используйте синтаксис индексации, указанный в этом посте, и убедитесь, что ваши индексы являются законными. Может быть, сначала сделать версию, которая распечатывает индексы, которые она будет использовать, но на самом деле их не использует. Поэкспериментируйте со своими кнопками и ручкой и убедитесь, что то, что они *будут* делать, разумно. Затем добавьте, чтобы он действительно это делал., @Chris Stratton
Вы также можете сгладить массив [x][y] до чего-то вроде array[x+(3*y)], @Chris Stratton
Одно упоминание о разумности меня пугает!!!!, @Robbie Perry
Как мне добавить свой обновленный код для анализа и дальнейших комментариев, пожалуйста?, @Robbie Perry
// музыкальные ноты
int C = 1046;
int D = 1175;
int E = 1319;
int F = 1397;
int G = 1598;
int A = 1760;
int B = 1976;
int C1 = 2093;
int D1 = 2349;
const int columns = 3;
const int scales = 3;
int potVal = 0;
const int notes[scales][columns] = {
{C, D, E},
{F, G, A},
{B, C1, D1}
};
const int numberOfButtons = 3;
int buttonPin[numberOfButtons] = {2, 7, 4};
int ledPin[numberOfButtons] = {11, 10, 9};
int buttonState = 0; // переменная для чтения статуса кнопки
int speaker = 3; // название клавиши динамика
void setup() {
Serial.begin(9600);
for (int i = 0; i < numberOfButtons; i++) {
pinMode(buttonPin[i], INPUT);
pinMode(ledPin[i], OUTPUT);
}
pinMode(speaker, OUTPUT); // устанавливаем динамик в качестве выхода
}
void loop() {
int potVal = map(analogRead(A2), 0, 1024, 0, 3);
Serial.println(notes[2][2]);
for (int i = 0; i < numberOfButtons; i++) {
//checkButton(buttonPin[i], notes[scales][columns], ledPin[i]);
checkButton(potVal,i);
}
}
void checkButton(int scaleNum, int buttonNum)
{
// прочитать состояние значения кнопки:
buttonState = digitalRead(buttonPin[buttonNum]);
// проверяем, нажата ли кнопка. Если да, то состояние кнопки ВЫСОКОЕ:
if (buttonState == HIGH) {
digitalWrite(ledPin[buttonNum], HIGH);
tone(speaker, notes[scaleNum][buttonNum]); // воспроизвести ноту
delay(100); // ждем 1/10 секунды
} else {
digitalWrite(ledPin[buttonNum], LOW);
noTone(speaker); // остановить воспроизведение ноты
}
}
Ок, спасибо всем за помощь! Вот завершенный и работающий код для всех, кто может найти его полезным. Почему так сложно загрузить код на этот сайт?, @Robbie Perry
Этот код неверен. Как объяснялось ранее, 3 не является допустимым индексом в массиве из 3 элементов. Вы должны вернуть максимум вашей функции карты к 2, как это было раньше, а не к 3., @Chris Stratton
Извините, Крис, я продолжаю зацикливаться на этом, но недавно мне было указано, что это создает равномерный спред по всему диапазону банка и на самом деле никогда не дает значение 3. Я по-старому сопоставил его с 2, используя максимум 1023, и это создает проблемы, потому что 1 простирается почти до конца диапазона банков и продолжает чередоваться с 2, поэтому нет стабильности. ....... "1023/1024 составляет 2,9999 с чем-то, и поэтому округляется до 2. Отображение от 0 до 2 будет означать, что только самая последняя позиция будет отображаться до 2"., @Robbie Perry
- Как контролировать скорость двухпроводного вентилятора с помощью Arduino и только потенциометра?
- Как вы справляетесь с дрейфом датчиков?
- Как использовать функцию карты
- Установите значения ползункового потенциометра
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Как справиться с rollover millis()?
что ты не в состоянии понять? ... создать 2d-массив, прочитать статус кнопки, прочитать положение горшка или что-то еще? ... вам нужно определить, в чем заключается реальная проблема ... никто не сможет вам помочь, пока вы не узнаете, в чем вам нужна помощь, @jsotola
Я думаю, что мой горшок не распознается и вместо этого к моему массиву 2d обращаются как к одному массиву. Вот почему я не получаю никакой истинной последовательности нот. Мой вопрос в том, как мне взять «int numScales = map (analogRead (A2), 0, 1023, 0, 2);» и использовать его для доступа к весам?, @Robbie Perry