MIDI / BB / VL3 / Arduino Remote - (programming help)

STOP and read first line at least!!! Not Spam, not trolling. Some educational/marketing click bait totally relevant to the thread.

TLDR scroll down to (bottom):



for my eventual question.

I’m new to MIDI so I’m experimenting. Now that BeatBuddy takes MIDI INPUT with it’s latest firmware, it’s essentially one of the most awesomely powerful digital MIDI devices on the market.

Anyhow, I got to thinking, in theory, since the BeatBuddy understands “some” MIDI messages, I can plug in a single cable and I’ll instantly have a way to interface with all it’s functions, remotely, with just about any other MIDI capable device in the world, including but not limited to, guitar pedals, phones, keyboards, computers, watches, and light bulbs.

In short, I said, “theory”, for a reason. It turns out there is an international MIDI standard, that all hardware manufactures try to adhere to, when building products. That’s only partly true. Then there is the software side, which is also supposed to adhere to “The standard”. What I’ve discovered after researching and playing with MIDI guitar stuff, is that designers, both hardware and software, all have their own MIDI dialect and interpretation of “The Standard”.

The problem with that is, in Digital World, where most musicians now frequent on a daily basis, the entire population of said world only understands the dialect spoken by other Digital World people. Consequently, even if the dialect is exactly the same (never happens), there is still room for interpretation issues, and often times, nobody understands anything and nothing gets done.

Ok, that last bit wasn’t entirely true. The DW people have what they call translators. They listen to commands spoken by tourists, and then the translators speak the commands to the DW people, who can now understand those commands perfectly [insert laughter]. The process also works in reverse just as efficiently [louder laughter].
[CENTER][/CENTER]
In summary, I’m using an Arduino UNO[/URL], with an optional Olimex MIDI Shield, to send MIDI commands to the BeatBuddy (and VL3). The BeatBuddy is acting as The MIDI Master (a.k.a. Pit Boss) and listening to commands on it’s MIDI input and sending commands, like song tempo, to the VL3 via it’s MIDI output. The VL3 is listening to the BeatBuddy (and the Arduino) via it’s MIDI input. For those that don’t know, The VL3 is, for lack of a better description, a digital floor based guitar/amp fx processor, a vocal processor, a looper, and a mixer, all in one box. Both the BeatBuddy and the VL3 are “almost” fully MIDI compatible, in all modes, [URL=‘http://www.midiworld.com/basics/’]In, Out, and Thru.

This is what I know so far:

These MIDI messages tell the BB to make various sounds: These should adhere to “The standard”, but annoyingly so, not everyone adheres to “The standard”, so this isn’t a global constant (weak code humor). I had inquired previously as to what note the percussion samples on the BB were “tuned to” in another thread, but never really got a straight answer. I suppose that is borderline proprietary information, but the cat is out of the bag, so here they be.

33 A0 Metronome
36 C1 Kick Drum
37 C#1 Cross Stick
38 D1 Snare
39 D#1 Handclaps
42 F#1 Hi-Hats Closed
43 G1 Tom 4 (Floor)
44 G#1 Foot Hi-hat
45 A1 Tom 3 (Low)
46 A#1 Hi-Hat Open
48 C2 Tom 2 (Hi-Mid)
49 C#2 Crash Cymbal 1
50 D2 Tom 1 (High)
51 D#2 Ride Cymbal
53 F2 Ride C. Bell
55 G2 Splash 1
57 A2 Crash Cymbal 2
59 B2 Splash 2

Basically (pun intended), I tell the Arduino (translator) to send this command to the BeatBuddy:

MIDI.sendNoteOn(36,100,1);  //MIDI OUT to BB telling (asking) it to make a noise, in this case, a kick drum sample at 100 velocity on channel 1. (by default, the BB listens to all channels.)

MIDI Messages that the BeatBuddy will accept from Arduino Uno: I can’t find anything online that tells me exactly what the code should be, so I’m hoping a fellow nerd can help me out:

Again, this is what I know:

VL3 Preset Change (via MIDI thru):

MIDI.sendProgramChange(XX, 1);  //via BB MIDI thru (configured for merge): tells VL3 to change to preset XX

Tempo:
tells the BB to increment tempo by 1 when a button on the Arduino is pressed. There is some funky stuff that has to happen with the MSB at certain values, hence the switch function. With the right math, I think this could be shortened, but math isn’t my strong suit.

void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
switch (tempo) {
case 128:
MSB=1;
tempo=-128;
break;
case 0:
MSB=2;
tempo=-256;
break;
case -211:
MSB=0;
tempo=40;
break;
}
MIDI.sendControlChange(106,MSB,1); // (CC,MSB,channel)
MIDI.sendControlChange(107,tempo++,1); // (CC,LSB,channel)
delay(100); //debounce
}
}

UPDATE: Also found this, which is infinitely easier.

MIDI.sendControlChange(97,1,1);  //  (CC,MSB,channel) - decreases tempo by 1
MIDI.sendControlChange(96,1,1);  //  (CC,MSB,channel) - increases tempo by 1

Volume:

MIDI.sendControlChange(108, XX, 1);  //--- change volume on BB to XX%: Use a pot to get the XX value----------

UPDATE: I ended up using a cheap encoder instead of a pot as I wanted to preserve the analog inputs on my Arduino for something else. Most of the code that’s out there for encoders is horrible, including the stuff on the Arduino site. After many an hour of struggling, I found this and it works beautifully, even with $1 encoders:
It came from this guy: http://www.buxtronix.net/2011/10/rotary-encoders-done-properly.html


// encoder pin A to Arduino pin 2   <--- special interrupt pin
// encoder pin B to Arduino pin 3  < --- special interrupt pin
// encoder ground pin to ground (GND)

#include <Rotary.h>

Rotary r = Rotary(2, 3);

void setup() {
Serial.begin(9600);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
}

void loop() {   // main execution loop    }

ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result == DIR_NONE) {
// do nothing
}
else if (result == DIR_CW) {
Serial.println("ClockWise");            // send CC commands here
}
else if (result == DIR_CCW) {
Serial.println("CounterClockWise");       // send CC commands here
}
}

Drum Set:

MIDI.sendControlChange(116, X, 1); //---- change BB drum set to X (could use a single digital button to increment through them)-----------

Tap Tempo:
I actually read this in the BeatBuddy MIDI manual I think, but sending a CC, control change in this case, like the following, is supposed to tell the BB to Tap Tempo: - This needs clarification. Is it supposed to bring up the tap tempo screen? If I send it a bunch of times, is it just like tapping on the tap tempo screen?

CC:117

[CENTER]********************************************************
********************************************************[/CENTER]

What I can’t figure out, is how to translate the Tap Tempo MIDI message into Arduino. I believe it should look something like the following, but I don’t understand enough MIDI or Arduino to know what the first two parameters (X) should be, and/ or, if I need to send one line, or multiple lines, like the tempo code above.

MIDI.sendControlChange(X, X, 1);

Sorry for length, but if you can, please educate me, and hopefully a few others.

Thanks in advance.
-Steve

now that I think about it, I wonder if Arduino makes an accelerometer?

Now presenting, “The Dumstick”. Seriously, that’s what I’d call it. The Aerodrum product is cool, but put an accelerator (I’ll be tearing apart my cell phone in about 10 minutes) in a drum stick head so it sends a programmable MIDI signal to the BeatBuddy (is there such thing as wireless MIDI?), to play the next linear note. Optionally*, have it clock synced like fills and transitions, such that an air drummer can’t really miss a note. In other words, air drumming, or even swinging one stick, tells the BB to advance the song and play the correct MIDI notes for the song, but the BeatBuddy plays them in time… so I suppose you could really suck as a drummer or swing one stick madly out of time and thus, look like a terrible drum syncing fool, but it would still sound great. *The other option is to turn “Smart Drummer” off and play notes immediately. I guess that might be “Free Form” or “Practice Mode” or “Accompany Mode”… or something.

I think I’ll start working on this concept now by myself, but as it turns out I found this, so an outfit like Singular Sound or Apple will probably beat me (HA!) to market. Maybe I can get officially licensed and make enough money to quit my job and move someplace warmer.

Please feel free to contribute to this thread, maybe help the project along.

Re tap tempo, CC 117.
According to the manual you send CC 117 to the BB messages at the tempo you want. So if you want 120 bpm, you send CC 117 messages 120 times a minute.
Format in Arduino using the midi library I see that you are using would be (assuming channel 1):

MIDI.sendControlChange(117, 0, 1);

That is CC 117, The data byte (zero) is not used, channel 1).
Just send that in a loop at the temp you want.

So something like:

#define tempo 120 // 120 bpm
int delaytime = 60000/tempo; // delay interval in milli secs

for (int i=0;i < 20;i++) {
MIDI.sendControlChange(117, 0, 1);
delay(delaytime);
}

You can also send the CC command (on the std serial output port) with:

Serial.write(0xB0); // CC to midi channel 1
Serial.write(117); // 117 - tap tempo
Serial.write(0); // data byte, not used

@Big E…awesome thank you!

Ugh. After some testing, the code above doesn’t appear to work with either library. It compiles just fine and the Arduino is sending what I tell it to the BB, but the BB doesn’t acknowledge that anything is being sent.

This actually does work to set the BB tempo:

//— sets tempo to XXbpm----------
MIDI.sendControlChange(107, XX, 1);

Why that works and the the one you provided doesn’t, is still beyond me.

Using the logic above, I created this basic loop. I looks for a button to be pressed then increments the tempo. Works great until the tempo hits 127 and then the BB locks up at 40bmp. Sigh.

void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
if (tempo >= 126){tempo = 50;}
else {tempo++;}
MIDI.sendControlChange(107, tempo, 1);
delay(150);
}
}

I’ve never actually tried the 117 thing, just going on what I read from the manual
According to the v1.85 manual “Sending out the CC-117 MIDI command multiple times is like tapping out the tempo with the pedal” so it seams reasonable to me that to set a tempo using it you would send 117 messages are the tempo you require.
You have to enable it in settings on the BB though although I think it is enabled by default.

If you want to explicitly set the tempo using midi though you can use CC 106 and CC 107. Your code is only using 107 which is why it is not working correctly, you have to send both 106 and 107 so send 106 and THEN send 107.
See this thread for a long winded description of the CC commands you need and how the values work:
http://mybeatbuddy.com/forum/index.php?threads/tempo-changes.5658/

THIS —> http://mybeatbuddy.com/forum/index.php?threads/tempo-changes.5658/

Using the above link, I was able to come up with the following Arduino sketch to increment the BB tempo with a button. Pressing a button increments tempo by 1. The tricky part was the MSB (Most Significant Bit) because it needs to change at 128 and then again at 256. So the switch statement looks at the tempo and when it gets to 128, the MSB becomes 1 and the tempo becomes -128. Then, when the tempo is incremented all the way to 0, it sets the MSB to 2 and the tempo to -256. When the tempo gets to -211, it resets the MSB to 0 and the tempo to 40.

void loop() { buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { switch (tempo) { case 128: MSB=1; tempo=-128; break; case 0: MSB=2; tempo=-256; break; case -211: MSB=0; tempo=40; break; } MIDI.sendControlChange(106,MSB,1); // (CC,MSB,channel) MIDI.sendControlChange(107,tempo++,1); // (CC,LSB,channel) delay(100); //debounce } }

I don’t claim to understand exactly why it works, but reading Big E’s replies in the link has helped me tremendously. Eventually the button will become a decoder so I can increase or decrease the tempo, or perhaps two buttons. Progress.

Even better, just send this and the BB will figure it out:

MIDI.sendControlChange(97,1,1); // (CC,MSB,channel) - decreases tempo by 1
MIDI.sendControlChange(96,1,1); // (CC,MSB,channel) - increases tempo by 1