Обнаружение изменения состояния с помощью датчика цвета

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

  /*
  // Датчик распознавания цвета TCS230
  // Контакты подключения датчика к Arduino показаны в комментариях

  Color Sensor      Arduino
  -----------      --------
  VCC               5V
  GND               GND
  s0                8
  s1                9
  s2                12
  s3                11
  OUT               10
  OE                GND
*/
#include <MIDI.h>

const int s0 = 8;
const int s1 = 9;
const int s2 = 12;
const int s3 = 11;
const int out = 10;

// Контакты светодиодов, подключенные к Arduino
int redLed = 5;
int greenLed = 6;
int blueLed = 7;
// Переменные
int red = 0;
int green = 0;
int blue = 0;
int indeks = 0;
const int rgbr = 7;
const int rgbg = 6;
const int rgbb = 5;

MIDI_CREATE_DEFAULT_INSTANCE();

void setup()
{
  MIDI.begin();                      // Запускаем MIDI и слушаем канал 4

  Serial.begin(9600);
  pinMode(s0, OUTPUT);
  pinMode(rgbr, OUTPUT);
  pinMode(rgbg, OUTPUT);
  pinMode(rgbb, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(out, INPUT);
  pinMode(redLed, OUTPUT);
  pinMode(greenLed, OUTPUT);
  pinMode(blueLed, OUTPUT);
  digitalWrite(s0, HIGH);
  digitalWrite(s1, HIGH);
}

void loop()
{
  color();

  int tmpr = (((20 - red) - 10) * 30); //int tmpr=(((20-red)-10)*30);
  int tmpg = (((20 - green) - 10) * 30); //int tmpg=(((20-зеленый)-10)*30);
  int tmpb = (((20 - blue) - 10) * 30); // int tmpb=(((20-blue)-10)*30);

  if (tmpr < 0)
    tmpr = 0;

  if (tmpg < 0)
    tmpg = 0;

  if (tmpb < 0)
    tmpb = 0;

  if (tmpg > tmpb && tmpg > tmpr)
  { tmpb = 0;
    tmpr = 0;
  }
  analogWrite(rgbr, tmpr );
  analogWrite(rgbg, tmpg );
  analogWrite(rgbb, tmpb );

  static uint8_t noteOn;

  if (tmpg > 149 && tmpg < 151) {
    static uint8_t noteOn = 0;
    if (!noteOn) {
      noteOn = true;
      MIDI.sendNoteOn(79, 127, 1);    // Отправляем заметку (высота 79, скорость 127 на канале 1)
      MIDI.sendControlChange(64, 127, 1);

    }
  }
  else {
    static uint8_t noteOn = 1;
    if (noteOn) {
      noteOn = false;
      MIDI.sendNoteOff(79, 0, 1);     // Остановить заметку
      MIDI.sendControlChange(64, 0, 1);

    }
  }
}

void color()
{
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  //считаем ВЫХОД, pRed, RED


  red = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);

  digitalWrite(s3, HIGH);
  //выход счета, pСИНИЙ, СИНИЙ
  blue = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);
  digitalWrite(s2, HIGH);
  //считаем, pGreen, GREEN
  green = pulseIn(out, digitalRead(out) == HIGH ? LOW : HIGH);

}

, 👍-1

Обсуждение

пожалуйста, укажите ваши попытки, чтобы мы могли видеть, в какой области вам нужна помощь, @jsotola

Здравствуйте, я заменил свой код новыми предложениями, но все равно безрезультатно..., @robbie

пожалуйста, отформатируйте код правильно..... выделите весь текст кода и нажмите кнопку {}, @jsotola

вы отслеживаете только одну заметку (любую заметку), @jsotola

проблема в том, что я не знаю, как отслеживать заметки, которые у меня есть, @robbie

нам массив (используйте логические значения, они имеют значения true/false) .... http://www.cplusplus.com/doc/tutorial/arrays/ .... когда вы играете ноту, установите соответствующий элемент массива. ... когда вы останавливаете ноту, очищаете соответствующий элемент массива, @jsotola

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

В том-то и дело, я хочу, чтобы миди-нота или, как вы предлагаете, светодиод загорался только один раз, когда он горит зеленым, а не постоянно. Когда значения датчика изменяются и снова появляется зеленый цвет, назначенная нота будет воспроизведена (один раз). Я удалю код, но я действительно думал, что проблема проста, хотя пока недоступна для меня..., @robbie

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


1 ответ


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

2

Поскольку MIDI-библиотека для Arduino не отслеживает, какие ноты включены, а какие нет, вам придется делать это самостоятельно.

Добавьте переменную static с именем noteOn, которая будет содержать 0 или 1, отслеживая, включена у вас заметка или нет.

Затем, когда ваш loop() определяет, что необходимо включить заметку, он сначала проверяет, включена ли уже заметка. Если примечание еще не включено (!noteOn), отправьте примечание по команде и установите noteOn=true (то же самое, что noteOn=1) ), чтобы в следующий раз вы больше не отправляли заметку по команде.

void loop()
{
  static uint8_t noteOn;

  [...]

  if (tmpg > 149 && tmpg < 151) {
    if (!noteOn) {
      noteOn = true;
      MIDI.sendNoteOn(79, 127, 1);    // Отправляем заметку (высота 79, скорость 127 на канале 1)
      MIDI.sendControlChange(64, 127, 1);
    }
  } else {
    if (noteOn) {
      noteOn = false;
      MIDI.sendNoteOff(79, 0, 1);     // Остановить заметку
      MIDI.sendControlChange(64, 0, 1);
    }
  }
}
,

Спасибо, Хосе Кан, уч! Можете ли вы сказать мне, что это значит ( [...]) Кроме того, что вы подразумеваете под отслеживанием того, какие ноты включены или выключены? Я попробовал ваш код, но, к сожалению, у меня все еще есть та же проблема с повторяющимися заметками..., @robbie

[...] как раз здесь я опустил часть вашего кода, не связанную с соответствующими дополнениями, чтобы ответить на вопрос., @jose can u c

Я отредактировал ответ, чтобы лучше объяснить, что я имею в виду, говоря о том, какие заметки включены или выключены., @jose can u c

Я подумал, что мне следует прикрепить свой код к вашему дополнительному коду, но я не понимаю, как и где мне его опубликовать!, @robbie

Возможно, мне следует отредактировать исходное сообщение и заменить его новым кодом?, @robbie

Да, отредактируйте вопрос, добавьте исправленную попытку., @jose can u c

И еще: логический оператор *И* — это &&, а не &., @jose can u c

Я изменил статическую переменную noteOn так, чтобы она равнялась «0» в первом if, а затем в «else if» я изменила ее на «1». это дает мне первую ноту, сыгранную один раз, но только один раз. Я думал, что noteOn уже отслеживает, но это не так?, @robbie