MIDI контроллер на Arduino UNO остановка выполнения команды после посыла последующих команд

Van
Van аватар
Offline
Зарегистрирован: 04.10.2016

Доброго времени суток.

Кнопки на пинах 6 и 7 должны переключать пресеты вперёд-назад по миди, собственно после влючения контроллера они так и работают, но после нажатия на любую из четырёх других кнопок, кнопки на пинах 6 и 7 полностью прекращают работать до перезагрузки контроллера.

Буду премного благодарен за любую помощь, подсказку, ликбез, критику.

Собирал скетч в меру своего разумения, из различных примеров и других кусков скетчей найденых на просторах интернета, собрал франкинштейна.

Спасибо!

#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
#include <Bounce2.h>
#define PROGRAM1 2
#define PROGRAM2 3
#define PROGRAM3 4
#define PROGRAM4 5

#define LED1 8
#define LED2 9
#define LED3 10
#define LED4 11
#define BOUNCEDELAY 25
// Instantiate a Bounce object
Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();

int action = 0;
int last_action = 0;
int progNo = 0;
int upLastTime, downLastTime, upNow, downNow;

void setup() {
  //  Set MIDI baud rate:
  Serial.begin(31250);
  // Setup the button
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(PROGRAM1,INPUT);
  pinMode(PROGRAM2,INPUT);
  pinMode(PROGRAM3,INPUT);
  pinMode(PROGRAM4,INPUT);

  // Activate internal pull-up
  digitalWrite(6, HIGH); // enable pull up
  digitalWrite(7, HIGH); // enable pull up
  digitalWrite(PROGRAM1,HIGH);
  digitalWrite(PROGRAM2,HIGH);
  digitalWrite(PROGRAM3,HIGH);
  digitalWrite(PROGRAM4,HIGH);

  // After setting up the button, setup debouncer
  debouncer1.attach(PROGRAM1);
  debouncer1.interval(BOUNCEDELAY);
  debouncer2.attach(PROGRAM2);
  debouncer2.interval(BOUNCEDELAY);
  debouncer3.attach(PROGRAM3);
  debouncer3.interval(BOUNCEDELAY);
  debouncer4.attach(PROGRAM4);
  debouncer4.interval(BOUNCEDELAY);

  //Setup the LED
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  pinMode(LED3,OUTPUT);
  pinMode(LED4,OUTPUT);
  flashPin(LED1,200);
  flashPin(LED2,200);
  flashPin(LED3,200);
  flashPin(LED4,200);
  digitalWrite(LED1, HIGH );
  midiProg( 0xC0, 0);
  upLastTime = digitalRead(6);
  downLastTime = digitalRead(7);
}
void loop() {
  upNow = digitalRead(6);
  downNow = digitalRead(7);

  if (upNow == HIGH && upLastTime == LOW) {
     progNo++; // increment program change
     if(progNo > 99) progNo = 0; // stop it going too high
     MIDI.sendProgramChange(byte(progNo), 2);
     delay(20); // bit of debounce delay
  } 
    
  if (downNow == HIGH && downLastTime == LOW) {
     progNo--; // decrement program change
     if(progNo < 0) progNo = 99; // stop it going too low
     MIDI.sendProgramChange(byte(progNo), 2);
     delay(20); // bit of debounce delay
  } 

   upLastTime = upNow;
   downLastTime = downNow;
  delay(10);

 // Update the debouncer
  debouncer1.update();
  debouncer2.update();
  debouncer3.update();
  debouncer4.update();

 // Get the update value
 int value1 = debouncer1.read();
 int value2 = debouncer2.read();
 int value3 = debouncer3.read();
 int value4 = debouncer4.read();
 
 action = 0;
  if ( value1 == LOW) {
   action = 1;
 }
  if ( value2 == LOW) {
   action = 2;
 }
  if ( value3 == LOW) {
   action = 3;
 }
  if ( value4 == LOW) {
   action = 4;

 }
//select action
if (action != last_action) {
switch ( action) {
  case 0:
  break;
  case 1:
    midiProg( 0xC0, 0);
    indicator(LED1);
  break;
  case 2:
    midiProg( 0xC0, 1);
    indicator(LED2);
  break;
  case 3:
    midiProg( 0xC0, 2);
    indicator(LED3);
  break;
  case 4:
    midiProg( 0xC0, 3);
    indicator(LED4);

}
}
   last_action = action;
}
void midiProg(char status, int data ) {
  Serial.write(status);
  Serial.write(data);
}
void flashPin( int ledPin, int flashDelay ) {
  digitalWrite( ledPin, HIGH );
  delay( flashDelay );
  digitalWrite( ledPin, LOW );
}
void indicator( char nr) {
  digitalWrite( LED1, LOW );
  digitalWrite( LED2, LOW );
  digitalWrite( LED3, LOW );
  digitalWrite( LED4, LOW );
  digitalWrite( nr, HIGH );
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не работайте вслепую. Поставьте печать в монитор порта после строки 75 и после строки 82, чтобы было видно, что программа вошла в одну из этих веток. Также поставьте печать переменной action после строки 118, неплохо бы посмотртеь чему она равна. Наконец, поставьте печать какого-нибудь "отчерка", типа "---------------"  перед строкой 143. Проанализируйте результат. Если идей не появится, то выложите получившийся скетч и копипасту монитора порта.

vvadim
Offline
Зарегистрирован: 23.05.2012

да и кнопки на пинах 6 и 7 неплохо сразу по нормальному обрабатывать.

Van
Van аватар
Offline
Зарегистрирован: 04.10.2016

Спасибо. Так как я посылаю миди сообщения то в качестве монитора использую midi ox, а так же слежу за тем как реагирует мой "железный" девайс. 

Van
Van аватар
Offline
Зарегистрирован: 04.10.2016

Я б с удовольствием обработал всё "по нормальному". Но как я писал выше: Собирал скетч в меру своего разумения, из различных примеров и других кусков скетчей найденых на просторах интернета. Опыта у меня увы маловато.

 

Van
Van аватар
Offline
Зарегистрирован: 04.10.2016

Всё заработало! Разобрался самостоятельно.

Вместо MIDI.sendProgramChange(byte(progNo), 2);  прописал midiProg(0xC1,(progNo));

и всё заверте...

Теперь хотелось бы поправить скетч чтоб как то поизящней что-ли. Смотрю я на него и что-то мне видется в нём корявость.) 

Если подскажите как "по нормальному" всё сверстать. Век вас помнить буду!

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Van пишет:

Если подскажите как "по нормальному" всё сверстать. Век вас помнить буду!

Например, так: http://arduino.ru/forum/programmirovanie/klassy-arduino-po-qwone-dlya-chainikov

Van
Van аватар
Offline
Зарегистрирован: 04.10.2016

Выявилась проблема. Переключение с первой кнопки на 3 и 4 происходит с ощутимой задержкой. Из за чего так может происходить? Подскажите пожалуйста!

Van
Van аватар
Offline
Зарегистрирован: 04.10.2016
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
#include <Bounce2.h>
#define PROGRAM1 2
#define PROGRAM2 3
#define PROGRAM3 4
#define PROGRAM4 5

#define LED1 8
#define LED2 9
#define LED3 10
#define LED4 11
#define BOUNCEDELAY 25
// Instantiate a Bounce object
Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();
Bounce debouncer3 = Bounce();
Bounce debouncer4 = Bounce();

int action = 0;
int last_action = 0;
int progNo = 0;
int upLastTime, downLastTime, upNow, downNow;

void setup() {
  //  Set MIDI baud rate:
  Serial.begin(31250);
  // Setup the button
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(PROGRAM1,INPUT);
  pinMode(PROGRAM2,INPUT);
  pinMode(PROGRAM3,INPUT);
  pinMode(PROGRAM4,INPUT);

  // Activate internal pull-up
  digitalWrite(6, HIGH); // enable pull up
  digitalWrite(7, HIGH); // enable pull up
  digitalWrite(PROGRAM1,HIGH);
  digitalWrite(PROGRAM2,HIGH);
  digitalWrite(PROGRAM3,HIGH);
  digitalWrite(PROGRAM4,HIGH);

  // After setting up the button, setup debouncer
  debouncer1.attach(PROGRAM1);
  debouncer1.interval(BOUNCEDELAY);
  debouncer2.attach(PROGRAM2);
  debouncer2.interval(BOUNCEDELAY);
  debouncer3.attach(PROGRAM3);
  debouncer3.interval(BOUNCEDELAY);
  debouncer4.attach(PROGRAM4);
  debouncer4.interval(BOUNCEDELAY);

  //Setup the LED
  pinMode(LED1,OUTPUT);
  pinMode(LED2,OUTPUT);
  pinMode(LED3,OUTPUT);
  pinMode(LED4,OUTPUT);
  flashPin(LED1,200);
  flashPin(LED2,200);
  flashPin(LED3,200);
  flashPin(LED4,200);
  digitalWrite(LED1, HIGH );
  midiProg( 0xC0, 0);
  upLastTime = digitalRead(6);
  downLastTime = digitalRead(7);
}
void loop() {
  upNow = digitalRead(6);
  downNow = digitalRead(7);

  if (upNow == HIGH && upLastTime == LOW) {
     progNo++; // increment program change
     if(progNo > 99) progNo = 0; 
     midiProg(0xC1,(progNo));
     
  } 
    
  if (downNow == HIGH && downLastTime == LOW) {
     progNo--; // decrement program change
     if(progNo < 0) progNo = 99; 
     midiProg(0xC1,(progNo));
     
  } 

   upLastTime = upNow;
   downLastTime = downNow;
  

 // Update the debouncer
  debouncer1.update();
  debouncer2.update();
  debouncer3.update();
  debouncer4.update();

 // Get the update value
 int value1 = debouncer1.read();
 int value2 = debouncer2.read();
 int value3 = debouncer3.read();
 int value4 = debouncer4.read();
 
 action = 0;
  if ( value1 == LOW) {
   action = 1;
 }
  if ( value2 == LOW) {
   action = 2;
 }
  if ( value3 == LOW) {
   action = 3;
 }
  if ( value4 == LOW) {
   action = 4;

 }
//select action
if (action != last_action) {
switch ( action) {
  case 0:
  break;
  case 1:
    midiProg( 0xC0, 0);
    indicator(LED1);
  break;
  case 2:
    midiProg( 0xC0, 1);
    indicator(LED2);
  break;
  case 3:
    midiProg( 0xC0, 2);
    indicator(LED3);
  break;
  case 4:
    midiProg( 0xC0, 3);
    indicator(LED4);

}
}
   last_action = action;
}
void midiProg(char status, int data ) {
  Serial.write(status);
  Serial.write(data);
}
void flashPin( int ledPin, int flashDelay ) {
  digitalWrite( ledPin, HIGH );
  delay( flashDelay );
  digitalWrite( ledPin, LOW );
}
void indicator( char nr) {
  digitalWrite( LED1, LOW );
  digitalWrite( LED2, LOW );
  digitalWrite( LED3, LOW );
  digitalWrite( LED4, LOW );
  digitalWrite( nr, HIGH );
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Продолжаем работать вслепую? Ну-ну.