Проблема с кодированием цикла for
У меня есть проблема с этим фрагментом кода, связанная с использованием 3 емкостных датчиков, каждый из которых выводит миди-ноту, выбранную из одной из трех шкал, выбранных с помощью горшка. Что касается сенсоров срабатывания нот и шкалы выбора кастрюли, то все идеально. Однако каждый датчик будет воспроизводить каждую ноту гаммы отдельно при каждом нажатии пальцем. Это, конечно, не то, что я имею в виду, поскольку каждый датчик должен запускать только соответствующую ноту. Спасибо за любые подсказки и советы!!
#include <SPI.h>
#include <CapacitiveSensor.h>
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// миди ноты
int c3 = 36;
int d3 = 38;
int e3 = 40;
int g3 = 43;
int a3 = 45;
int c4 = 48;
int d4 = 50;
int e4 = 52;
int g4 = 55;
int a4 = 57;
int c5 = 60;
int d5 = 62;
int e5 = 64;
int g5 = 67;
int a5 = 69;
int c6 = 72;
/////// код & 2d массив для выбора масштаба
const int columns = 3;
const int scales = 3;
int potVal = 0;
const int notes[scales][columns] = {
{c3, d3, e3},
{c4, d4, e4},
{c5, d5, e5}
};
const int numberOfSensors = 3;
int sensorPin[numberOfSensors] = {38, 39, 40};
/////////
static const unsigned ledPin1 = 22; // вывод светодиода на Arduino Mega
static const unsigned ledPin2 = 23;
static const unsigned ledPin3 = 24;
int val = 10; // это значение лучше всего около "10". работает с "умножить"
// и "Порог" для включения полифонии!
int Threshold = (0); //Порог срабатывания mp3
int Multiply = (0); //увеличивает или уменьшает общую чувствительность
CapacitiveSensor cs_2_38 = CapacitiveSensor(2, 38); //Мегасенсорные контакты
CapacitiveSensor cs_2_39 = CapacitiveSensor(2, 39);
CapacitiveSensor cs_2_40 = CapacitiveSensor(2, 40);
void setup()
{
for (int i = 0; i < numberOfSensors; i++) {
pinMode(sensorPin[i], INPUT);
Serial.begin(9600); //миди(31250)
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
}
}
void loop()
{
int potVal = map(analogRead(A2), 0, 1024, 0, 3);
for (int i = 0; i < numberOfSensors; i++) {
checkSensor(potVal, i);
}
}
void checkSensor(int scaleIndex, int columnIndex)
{
static boolean lastSensorHit1 = false;
static boolean lastSensorHit2 = false;
static boolean lastSensorHit3 = false;
bool sensorHit3 = cs_2_40.capacitiveSensor(Multiply) / val > (Threshold);
bool sensorHit2 = cs_2_39.capacitiveSensor(Multiply) / val > (Threshold);
bool sensorHit1 = cs_2_38.capacitiveSensor(Multiply) / val > (Threshold);
Multiply = map(analogRead(A0), 0, 1023, 150, 5);
Threshold = map(analogRead(A1), 0, 1023, 150, 5);
long total1 = cs_2_38.capacitiveSensor(Multiply);
long total2 = cs_2_39.capacitiveSensor(Multiply);
long total3 = cs_2_40.capacitiveSensor(Multiply);
int Art1 = total1 / val;
int Art2 = total2 / val;
int Art3 = total3 / val;
if (sensorHit1 != lastSensorHit1)
if (sensorHit1 && !lastSensorHit1)
{
digitalWrite(ledPin1, HIGH);
MIDI.sendNoteOn(notes[scaleIndex][columnIndex], 127, 1); // Отправить заметку (высота 80, скорость 127 на канале 1)
MIDI.sendControlChange(64, 127, 1);
}
else {
digitalWrite(ledPin1, LOW);
MIDI.sendNoteOff(notes[scaleIndex][columnIndex], 0, 1); // Остановить заметку
MIDI.sendControlChange(64, 0, 1);
}
if (sensorHit2 != lastSensorHit2)
if (sensorHit2 && !lastSensorHit2)
{
digitalWrite(ledPin2, HIGH);
MIDI.sendNoteOn(notes[scaleIndex][columnIndex], 127, 1); // Отправить заметку (высота 79, скорость 127 на канале 1)
MIDI.sendControlChange(64, 127, 1);
}
else {
digitalWrite(ledPin2, LOW);
MIDI.sendNoteOff(notes[scaleIndex][columnIndex], 0, 1); // Остановить заметку
MIDI.sendControlChange(64, 0, 1);
}
if (sensorHit3 != lastSensorHit3)
if (sensorHit3 && !lastSensorHit3)
{
digitalWrite(ledPin3, HIGH);
MIDI.sendNoteOn(notes[scaleIndex][columnIndex], 127, 1); // Отправить заметку (высота 78, скорость 127 на канале 1)
MIDI.sendControlChange(64, 127, 1);
}
else {
digitalWrite(ledPin3, LOW);
MIDI.sendNoteOff(notes[scaleIndex][columnIndex], 0, 1); // Остановить заметку
MIDI.sendControlChange(64, 0, 1);
}
lastSensorHit1 = sensorHit1;
lastSensorHit2 = sensorHit2;
lastSensorHit3 = sensorHit3;
}
@Robbie Perry, 👍0
Обсуждение2 ответа
Лучший ответ:
Что ж, поработав еще немного, я обнаружил, что единственным изменением, которое все исправило, было просто это (в операторах if/else)..... изменение MIDI.sendNoteOn(notes[scaleIndex][columnIndex], 127, 1);
в MIDI.sendNoteOn(notes[scaleIndex][0], 127, 1);
[columnIndex] должен быть [0], [1] или [2] представляющий одну из трех шкал в назначенном массиве. Это нормально, так как я пишу код для нескольких датчиков. Однако для 16 датчиков мне придется использовать цикл for .... Спасибо за вашу помощь! Вот полный код для тех, кому он нужен... включая некоторые изменения в светодиодах...
#include <CapacitiveSensor.h>
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
int c3 = 36;
int d3 = 38;
int e3 = 40;
int g3 = 43;
int a3 = 45;
int c4 = 48;
int d4 = 50;
int e4 = 52;
int g4 = 55;
int a4 = 57;
int c5 = 60;
int d5 = 62;
int e5 = 64;
int g5 = 67;
int a5 = 69;
int c6 = 72;
const int columns = 3;
const int scales = 3;
int potVal = 0;
const int notes[scales][columns] = {
{c3, d3, e3},
{c4, d4, e4},
{c5, d5, e5}
};
const int numberOfSensors = 3;
const int sensorPin[numberOfSensors] = {38, 39, 40};
const int ledPin[numberOfSensors] = {22, 23, 24};
const int val = 10; // это значение лучше всего около "10". работает с "умножить"
// и "Порог" для включения полифонии!
int Threshold = (0); //Порог срабатывания mp3
int Multiply = (0); //увеличивает или уменьшает общую чувствительность
CapacitiveSensor cs_2_38 = CapacitiveSensor(2, 38);
CapacitiveSensor cs_2_39 = CapacitiveSensor(2, 39);
CapacitiveSensor cs_2_40 = CapacitiveSensor(2, 40);
void setup()
{
Serial.begin(9600);//миди(31250)
for (int i = 0; i < numberOfSensors; i++) {
pinMode(ledPin[i], OUTPUT);
}
}
void loop()
{
int potVal = map(analogRead(A2), 0, 1024, 0, 3);
for (int i = 0; i < numberOfSensors; i++) {
checkSensor(potVal,i);
}
}
void checkSensor(int scaleIndex, int columnIndex)
{
static boolean lastSensorHit1 = false;
static boolean lastSensorHit2 = false;
static boolean lastSensorHit3 = false;
bool sensorHit1 = cs_2_38.capacitiveSensor(Multiply) / val > (Threshold);
bool sensorHit2 = cs_2_39.capacitiveSensor(Multiply) / val > (Threshold);
bool sensorHit3 = cs_2_40.capacitiveSensor(Multiply) / val > (Threshold);
Multiply = map(analogRead(A0), 0, 1023, 150, 5);
Threshold = map(analogRead(A1), 0, 1023, 150, 5);
if (sensorHit1 != lastSensorHit1)
if (sensorHit1 && !lastSensorHit1)
{
digitalWrite(ledPin[0], HIGH);
MIDI.sendNoteOn(notes[scaleIndex][0], 127, 1);
MIDI.sendControlChange(64, 127, 1);
}
else {
digitalWrite(ledPin[0], LOW);
MIDI.sendNoteOff(notes[scaleIndex][0], 0, 1);
MIDI.sendControlChange(64, 0, 1);
}
if (sensorHit2 != lastSensorHit2)
if (sensorHit2 && !lastSensorHit2)
{
digitalWrite(ledPin[1], HIGH);
MIDI.sendNoteOn(notes[scaleIndex][1], 127, 1);
MIDI.sendControlChange(64, 127, 1);
}
else {
digitalWrite(ledPin[1], LOW);
MIDI.sendNoteOff(notes[scaleIndex][1], 0, 1);
MIDI.sendControlChange(64, 0, 1);
}
if (sensorHit3 != lastSensorHit3)
if (sensorHit3 && !lastSensorHit3)
{
digitalWrite(ledPin[2], HIGH);
MIDI.sendNoteOn(notes[scaleIndex][2], 127, 1);
MIDI.sendControlChange(64, 127, 1);
}
else {
digitalWrite(ledPin[2], LOW);
MIDI.sendNoteOff(notes[scaleIndex][2], 0, 1);
MIDI.sendControlChange(64, 0, 1);
}
lastSensorHit1 = sensorHit1;
lastSensorHit2 = sensorHit2;
lastSensorHit3 = sensorHit3;
}````````
Я только изучаю эту программу, поэтому я могу ошибаться в этом, и я приношу свои извинения, если это так.
Вместо цикла внутри void setup()
инициализируйте каждый вывод отдельно. Также вы говорите системе запустить MIDI и установить pinMode
3 раза.
Внутри функции Void checkSensor
вы устанавливаете все sensorHits
каждый раз, когда функция запускается, вы можете немного сэкономить, используя lastSensorHit(i)
.
Я только что заметил, что у вас есть команда if, запускающая эту функцию как (int i = 0; i < numberOfSensors; i++)
. У вас нет датчика 0, поэтому вы можете изменить его на (int i = 1; i < numberOfSensors+1; i++)// или просто изменить его на 4
.
Внутри функции checkSensor не похоже, что ваша переменная val имеет значение.
if (sensorHit1 != lastSensorHit1)
это все еще находится в той же функции, что и раньше, и будет выполняться один раз для каждого канала, который вы указали в управляющей функции if.
Может быть, переместить это в цикл void() или создать собственную функцию?
Спасибо, Джефф А., вы сделали несколько интересных замечаний. У меня будет возможность снова поработать с этим позже сегодня вечером, и я сообщу о своем прогрессе!, @Robbie Perry
Всем спасибо за помощь, но это выше моего понимания, извините. Мне нужно пойти и узнать обо всех процессах, происходящих в этом коде, чтобы я мог лучше подойти к нему., @Robbie Perry
Надеюсь, ты сможешь разобраться. Удачи и счастливого Рождества, @Jeff A
Абсолютно!! Вас тоже с Рождеством, Джефф А., @Robbie Perry
ЗАМЕЧАТЕЛЬНО, хорошая работа. Чтобы облегчить чтение, вы можете поставить `
` в начале и в конце вашего кода, это облегчит чтение. Это ключ слева от 1, @Jeff A
Да, я никак не могу разобраться с сообщениями на этом форуме. Я отредактирую это сейчас!, @Robbie Perry
- Использование аналогового входа для чтения кнопки
- Преобразование строки в массив символов
- Можно ли использовать цифровые контакты в качестве выхода ШИМ?
- Bluetooth-модуль HC-05 не принимает AT-команды
- Объединение кода для нескольких датчиков в одной программе
- Использование модуля JYETech 2.4 Inch LCD Display Screen Module с Arduino?
- Может ли Arduino UNO постоянно хранить код?
- Проблемы с срабатыванием датчика PIR сами по себе
У вас должна быть другая функция для проверки датчиков, чтобы не было всего этого кода вырезания и вставки (который некоторые люди считают плохим программированием). В вашей функции checkSensor() проверьте, какой датчик активен, и вызовите новую функцию для его обработки. Я бы, вероятно, использовал конструкцию switch/case для этого https://beginnersbook.com/2017/08/cpp-switch-case/, @Dougie
Что это значит? ... для меня это не имеет никакого смысла ... «каждый датчик будет воспроизводить каждую ноту шкалы сам по себе при каждом нажатии пальца», @jsotola
Спасибо за вашу помощь. @jsotola ... это означает, что если я буду продолжать нажимать только на первый датчик, я буду слышать каждую ноту шкалы одну за другой, поэтому я знаю, что проблема связана с циклом for, поскольку он продолжает циклически повторяться. На самом деле, все датчики будут делать это. Думаю, я не уверен, как это сделать с помощью отдельной функции, но я посмотрю на это, Дуги, спасибо., @Robbie Perry
вы говорите «продолжайте постукивать»… значит ли это, что вы нажимаете на датчик и слышите одну ноту, затем снова нажимаете и слышите следующую ноту и так далее?, @jsotola
Да это верно. Конечно, если я держу палец на датчике, я слышу сустейн этой ноты, пока снова не уберу палец., @Robbie Perry
а, это не то, что вы хотите? ... вы не хотите слышать следующую ноту, вы хотите слышать одну и ту же ноту при каждом нажатии?, @jsotola
Вы правы jsotola. Я хочу слышать одну и ту же ноту при каждом касании одного и того же сенсора., @Robbie Perry