首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Arduino Uno:在播放、停止、录制时,从古巴抓拍MIDI打开录音标志。

Arduino Uno:在播放、停止、录制时,从古巴抓拍MIDI打开录音标志。
EN

Stack Overflow用户
提问于 2021-01-20 13:45:55
回答 3查看 380关注 0票数 1

我想要一个亮着的录音标志,根据我的录音软件的播放状态来改变颜色。我在下面写了Arduino代码来打开三个继电器中的一个(LED灯),当我按下停止、播放或在音乐软件Cubase中录制时。当按下时,古巴酶传送这些midi字符串:

代码语言:javascript
复制
Cubase sends "B0 0C 0E   B0 2C 44" when it begins to PLAY
Cubase sends "B0 0C 0E   B0 2C 43" when it begins to STOP
Cubase sends "B0 0C 0E   B0 2C 45" when it begins to RECORD

我有找到第一个字节的代码,然后等待第二个字节。但那是不必要的。

我所需要的是,例如,是"B0 2C 44“(或176-44-68小数点)出现,我打开游戏(绿色)发光二极管。

它工作了。

然而,并不是所有的时间。每第四次或第五次,它都感觉不到。我把我用的硬件放在笔记里。

我做了好几天的研究,也知道其他人也在经历同样的问题,但我似乎找不到解决办法。谢谢你的建议。

代码语言:javascript
复制
/*RECORDING SIGN for Steinberg Cubase Pro 11
Copyright (c) 2021 by Tom Sylvester, Inc. A North Carolina Corp
Feel free to use this code in your own project.  Just credit me.
Monitoring MidiOX, I determined:
Cubase sends "B0 0C 0E   B0 2C 44" when it begins to PLAY
Cubase sends "B0 0C 0E   B0 2C 43" when it begins to STOP
Cubase sends "B0 0C 0E   B0 2C 45" when it begins to RECORD
Cubase sends "B0 0C 0E   B0 2C 42" when it begins to SCRUB FWD
Cubase sends "B0 0C 0E   B0 2C 41" when it begins to SCRUB REW
Cubase sends "B0 0C 0F   B0 2C 43" when LOOP is set to ON
Cubase sends "B0 0C 0F   B0 2C 03" when LOOP is set to OFF
The following code takes these strings and turns the LED Relays On/Off.
    
PARTS:
Arduino Uno R3 Microcontroller ($14)
UBld.it MIDI Breakout Board ($12)
HiLetgo 5V 4 Channel Relay Shield ($8)
5V LED Strip Light ($9)
Striveday 22 AWG 5 conductor wire ($18)
FORE MIDI to USB Interface MIDI Cable Adapter ($20)
Wolfwhoop PW-D Control Buck Converter 6-24V to 5V
1.5A Step-Down Regulator Module Power Inverter Volt Stabilizer ($2)
9V DC Adapter ($9)  
Radio Shack Project Enclosure (5x2x2.5) ($10)
SUBTOTAL: $93
Custom Etched Acrylic Logo (8.5x11x.25) approx $22
TOTAL: $115
*/
    
// VARIABLES
int dataStop = 67;
int dataPlay = 68;
int dataRecord = 69;
int dataFwd = 66;
int dataRev = 65;
int StayOnRecord = 0;
  
// MIDI 
byte status1;
byte data11;
byte data12;
    
// RELAYS
#define relay2Blue 6
#define relay3Green 5
#define relay4Red 4
    
void setup() {
  Serial.begin(31250);
  pinMode(relay2Blue, OUTPUT);
  pinMode(relay3Green, OUTPUT);
  pinMode(relay4Red, OUTPUT); 
  digitalWrite(relay2Blue, HIGH); // TURN ON BLUE RELAY (#2) INITIALLY
}
   
void checkMIDI() {
  do {
    if (Serial.available()) {
      status1 = Serial.read(); // read first byte
      data11 = Serial.read();  // read next byte
      data12 = Serial.read();  // read final byte

      // STOP
      if ((status1 == 176) && (data11 == 44) && (data12 == dataStop)) {
        StayOnRecord = 0;
        digitalWrite(relay2Blue, HIGH);
        digitalWrite(relay3Green, LOW);
        digitalWrite(relay4Red, LOW);
      }
    
      // RECORD
      if ((status1 == 176) && (data11 == 44) && (data12 == dataRecord)) {
        StayOnRecord = 1;
        digitalWrite(relay2Blue, LOW);    
        digitalWrite(relay3Green, LOW);
        digitalWrite(relay4Red, HIGH);
      }
                          
      // PLAY
      if ((status1 == 176) && (data11 == 44) && (data12 == dataPlay)) {
        if (StayOnRecord == 0) { // Cubase sends a PLAY command after RECORD, so this keeps PLAY (GREEN) from lighting up during RECORD (RED)
          digitalWrite(relay2Blue, LOW);    
          digitalWrite(relay3Green, HIGH);
          digitalWrite(relay4Red, LOW);
        }
        StayOnRecord = 0; // ...then RESETs it.
      }
    
      // FAST FORWARD
      if ((status1 == 176) && (data11 == 44) && (data12 == 66)) {
        for (int i=1; i<=6 ; i++) { 
          digitalWrite(relay2Blue, HIGH);
          digitalWrite(relay4Red, LOW); 
          digitalWrite(relay3Green, HIGH); // TURN ON ALL RELAYS
          delay(20);
          digitalWrite(relay2Blue, LOW);
          digitalWrite(relay4Red, LOW); 
          digitalWrite(relay3Green, LOW);  // TURN OFF ALL RELAYS
          delay(20);
        }
        digitalWrite(relay3Green, LOW);
        digitalWrite(relay4Red, LOW);
        digitalWrite(relay2Blue, HIGH);    // TURN ON BLUE RELAY (#2)
        StayOnRecord = 0;
        delay(10);
      }
    
      // FAST REVERSE
      if ((status1 == 176) && (data11 == 44) && (data12 == 65)) {
        for (int i=1; i<=6 ; i++) { 
          digitalWrite(relay2Blue, HIGH);
          digitalWrite(relay4Red, LOW); 
          digitalWrite(relay3Green, HIGH); // TURN ON ALL RELAYS
          delay(20);
          digitalWrite(relay2Blue, LOW);
          digitalWrite(relay4Red, LOW); 
          digitalWrite(relay3Green, LOW);  //TURN OFF ALL RELAYS
          delay(20);
        }
        digitalWrite(relay3Green, LOW);
        digitalWrite(relay4Red, LOW);
        digitalWrite(relay2Blue, HIGH);    //TURN ON BLUE RELAY (#2)
        StayOnRecord = 0;
        delay(10);
      }
    }
  }
  while (Serial.available() > 2); // when at least three bytes available   
}
    
void loop(){
  checkMIDI();
  delay(10);
}

Arduino,与继电器盾牌:

工作记录标志:

EN

回答 3

Stack Overflow用户

发布于 2021-01-20 23:36:46

很酷的计划!

每次通过loop(),您都会调用您的checkMIDI(),这将测试一个字符是否可用,但随后尝试读取三个值。将do while更改为while (Serial.available() >= 3) { ... }可能会修复它,这可能就足够了。

一种选择--使用MIDI库,让它为您进行收集和解析。您将定义一个回调以获取CC命令,并决定如何处理它们。https://github.com/FortySevenEffects/arduino_midi_library

另一种选择,重新扫描设置一些标志,并使用loop().下面是一个粗糙的骨架:

代码语言:javascript
复制
const byte IDLE = 0, NEEDCC = 1, NEEDNUM = 2;

byte midiscanstate = IDLE;

// this is inside loop()
if serial available
    b = serial read
    switch midiscanstate
    case IDLE
        if b == B0
            midiscanstate = NEEDCC
    case NEEDCC
        if b == 0x2C
            midiscanstate = NEEDNUM
        else
            midiscanstate = IDLE
    case NEEDNUM
        doaction(b)
        midiscanstate = IDLE
    default
        midiscanstate = IDLE

画出改变状态的状态和字节,以确保我的状态是正确的。我想那会管用的。(如果midi的实时信息妨碍了他们的话,他们可能会忽略这些信息)。哈哈!玩得开心!

票数 0
EN

Stack Overflow用户

发布于 2021-01-22 00:40:03

@aMike,谢谢你的想法。您的回拨建议几乎奏效了。它将转到下面的doCC回调(我用!= 0测试了它,并且简单地打开了过程中的中继)。但是,为了执行IF..THENCASE,我需要知道status1data11data12 12E 213将作为什么返回。唉,没有串行监视器(<>9600波德),我在一个房间关灯。它应该发送"B0 2C 44“,但显然不是。你帮了大忙--快到了!

代码语言:javascript
复制
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void handleControlChange(byte status1, byte data11, byte data12);

// VARIABLES
byte dataStop = 0x43;
byte dataPlay = 0x44;
byte dataRecord = 0x45;
int StayOnRecord = 0;
  
// RELAYS
#define relay2Blue 6
#define relay3Green 5
#define relay4Red 4
    
void doCC(byte status1, byte data11, byte data12)
{
      // STOP
      if ((status1 == 0xB0) && (data11 == 0x2C) && (data12 == 0x43)) {
        StayOnRecord = 0;
        digitalWrite(relay2Blue, HIGH);
        digitalWrite(relay3Green, LOW);
        digitalWrite(relay4Red, LOW);
      }
    
      // RECORD
      if ((status1 == 0xB0) && (data11 == 0x2C) && (data12 == 0x45)) {
        StayOnRecord = 1;
        digitalWrite(relay2Blue, LOW);    
        digitalWrite(relay3Green, LOW);
        digitalWrite(relay4Red, HIGH);
      }
                          
      // PLAY
      if ((status1 == 0xB0) && (data11 == 0x2C) && (data12 == 0x44)) {
        if (StayOnRecord == 0) {                  // Cubase sends a PLAY command after RECORD, so this keeps PLAY (GREEN) from lighting up during RECORD (RED)
          digitalWrite(relay2Blue, LOW);    
          digitalWrite(relay3Green, HIGH);
          digitalWrite(relay4Red, LOW);
        }
        StayOnRecord = 0;                         // ...then RESETs it.
      }
}


void setup() {
  pinMode(relay2Blue, OUTPUT);
  pinMode(relay3Green, OUTPUT);
  pinMode(relay4Red, OUTPUT); 
  digitalWrite(relay2Blue, HIGH);               // TURN ON the BLUE LED Relay (#2) INITIALLY

    MIDI.begin(MIDI_CHANNEL_OMNI);             // Listen on all channels
//    MIDI.turnThruOff();          
    MIDI.setHandleControlChange(doCC);    
}


void loop()
{
  MIDI.read();
}
票数 0
EN

Stack Overflow用户

发布于 2021-01-24 14:48:21

“非常感谢,”迈克。你的想法是正确的。现在,这段代码工作得非常完美,没有任何跳出:

代码语言:javascript
复制
#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();
void handleControlChange(byte status1, byte data11, byte data12);

// VARIABLES
byte dataStop = 0x43;
byte dataPlay = 0x44;
byte dataRecord = 0x45;
byte dataFFWD = 0x42;
byte dataFREV = 0x41;
int StayOnRecord = 0;
  
// RELAYS
#define relay2Blue 6
#define relay3Green 5
#define relay4Red 4
    
void doCC(byte status1, byte data11, byte data12){
     // get note value
      status1 = MIDI.getChannel();
      data11 = MIDI.getData1();
      data12 = MIDI.getData2();

      // STOP
      if (data12 == dataStop) {
        StayOnRecord = 0;
        digitalWrite(relay2Blue, HIGH);
        digitalWrite(relay3Green, LOW);
        digitalWrite(relay4Red, LOW);
      }
    
      // RECORD
      if (data12 == dataRecord) {
        StayOnRecord = 1;
        digitalWrite(relay2Blue, LOW);    
        digitalWrite(relay3Green, LOW);
        digitalWrite(relay4Red, HIGH);
      }
                          
      // PLAY
      if (data12 == dataPlay) {
        if (StayOnRecord == 0) {                  // Cubase sends a PLAY command after RECORD, so this keeps PLAY (GREEN) from lighting up during RECORD (RED)
          digitalWrite(relay2Blue, LOW);    
          digitalWrite(relay3Green, HIGH);
          digitalWrite(relay4Red, LOW);
        }
        StayOnRecord = 0;                         // ...then RESETs it.
      }

      // Fast FWD
      if (data12 == dataFFWD) {
        StayOnRecord = 0;
        digitalWrite(relay2Blue, HIGH);
        digitalWrite(relay3Green, HIGH);
        digitalWrite(relay4Red, LOW);
      }

      // Fast REV
      if (data12 == dataFREV) {
        StayOnRecord = 0;
        digitalWrite(relay2Blue, LOW);
        digitalWrite(relay3Green, HIGH);
        digitalWrite(relay4Red, HIGH);
      }


}


void setup() {
  pinMode(relay2Blue, OUTPUT);
  pinMode(relay3Green, OUTPUT);
  pinMode(relay4Red, OUTPUT); 
  digitalWrite(relay2Blue, HIGH);               // TURN ON the BLUE LED Relay (#2) INITIALLY
  MIDI.begin(MIDI_CHANNEL_OMNI);               // Listen on all channels
  MIDI.turnThruOff();          
  MIDI.setHandleControlChange(doCC);    
}


void loop()
{
  MIDI.read();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65810782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档