Проблема с кодированием цикла 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;

}

, 👍0

Обсуждение

У вас должна быть другая функция для проверки датчиков, чтобы не было всего этого кода вырезания и вставки (который некоторые люди считают плохим программированием). В вашей функции checkSensor() проверьте, какой датчик активен, и вызовите новую функцию для его обработки. Я бы, вероятно, использовал конструкцию switch/case для этого https://beginnersbook.com/2017/08/cpp-switch-case/, @Dougie

Что это значит? ... для меня это не имеет никакого смысла ... «каждый датчик будет воспроизводить каждую ноту шкалы сам по себе при каждом нажатии пальца», @jsotola

Спасибо за вашу помощь. @jsotola ... это означает, что если я буду продолжать нажимать только на первый датчик, я буду слышать каждую ноту шкалы одну за другой, поэтому я знаю, что проблема связана с циклом for, поскольку он продолжает циклически повторяться. На самом деле, все датчики будут делать это. Думаю, я не уверен, как это сделать с помощью отдельной функции, но я посмотрю на это, Дуги, спасибо., @Robbie Perry

вы говорите «продолжайте постукивать»… значит ли это, что вы нажимаете на датчик и слышите одну ноту, затем снова нажимаете и слышите следующую ноту и так далее?, @jsotola

Да это верно. Конечно, если я держу палец на датчике, я слышу сустейн этой ноты, пока снова не уберу палец., @Robbie Perry

а, это не то, что вы хотите? ... вы не хотите слышать следующую ноту, вы хотите слышать одну и ту же ноту при каждом нажатии?, @jsotola

Вы правы jsotola. Я хочу слышать одну и ту же ноту при каждом касании одного и того же сенсора., @Robbie Perry


2 ответа


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

1

Что ж, поработав еще немного, я обнаружил, что единственным изменением, которое все исправило, было просто это (в операторах 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;

}````````
,

1

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

Вместо цикла внутри 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