I'm making a midi controller. I need to send some control messages. I can send anything but a "0" zero. I have a test program that send the control command with data 127, then 64, then 0. The 127 and 64 send but the 0 does not. I have the output of the Arduino going into a Midi to usb converter. Then I use MidiOx to view the output. Watching MidiOx I can watch the output - the 127 and 64 are there but nothing for the 0 output.
I'm using a Arduino UNO
Here's the code:
// send a midi control message
// first on (127), then medium (64), then off (0)
// 127 goes ok, 64 goes ok, 0 doesn't send
void setup() {
// Set MIDI baud rate:
Serial.begin(31250);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
// Send control on, then control off, then on, ...
sendData(0xB0, 0x6C, 0x7F); // send control on
digitalWrite(LED_BUILTIN, HIGH); // flash the led while you're at it
delay(800);
digitalWrite(LED_BUILTIN, LOW);
sendData(0xB0, 0x6C, 0x40); // send non zero
delay(800);
sendData(0xB0, 0x6C, 0x00); // send zero
delay(800);
}
void sendData(int cmd, int data1, int data2) {
Serial.write(cmd);
Serial.write(data1);
Serial.write(data2);
}
Could 0x00 be an invalid midi command (discarded) or an end of send value? Your code simulates right (the 0x00 is serial.written) Maybe check the input device?
I've tried it by sending to the MidiOx and also to my Nord Electro 6d synth - same result. Sending the 127 turns on the piano on, sending a 0 turns it off. If I manually turn the piano off and then send the 127 it turns on. Trying the 0 send doesn't turn it off. In MidiOx I see the 127 command set, but don't see anything when I send the 0.
I am sending a control change (CC) msg. A CC is made of 3 data bytes -
B0 says it's a control change, the next number is controll to change (in my case using the Nord Controller List I see I want to send 9 for Organ enable/disable, 33 for Piano enable/disable or 42 for Synth enable/disable.
The third byte is the value - 127 for on, 0 for off except for the rotor - using the output of the Nord into MidiOx I see that 127 is fast, rotor slow is a 0x2b. They did that because there is also a "stop" state of the rotor.
I verified this by connecting the Nord to my MidiOx and pressing the rotor, organ, piano and synth on/off controls.
SOLVED - somewhat - while doing some further testing trying to see what was going on I found a solution. The Nord send out 0xB0, 0x21 which says it's a control change for the piano. Then sends either a 0x7F for On - or a 0x00 for Off. Same for the organ and synth.
So to see if the Arduino was really sending the command OK I changed the Off to a 0x01 - and then saw using MidiOx that it was working as expected. Before I reprogrammed it to send 0x00 for Off I connected it to the Nord and hit the pedal - and it switched! Sending a 0x01 for off works like the 0x00 does.
Problem solved but still no idea why sending it 0x00 as it sends does not work coming from the Arduino.
Thank you for your help - your questioning me made me dig in a different way and that brought forth the solution.
And just for the heck of it here's my current working code for using a pedal to enable/disable the Nord organ, piano, synth and rotor. I'm playing out tomorrow night - I'll let you know how it works out. (And if you see any glaring errors or adjustments - let me know please.)
/*
MIDI note player
This sketch shows how to use the serial transmit pin (pin 1) to send MIDI note data.
If this circuit is connected to a MIDI synth, it will play the notes
F#-0 (0x1E) to F#-5 (0x5A) in sequence.
The circuit:
- digital in 1 connected to MIDI jack pin 5
- MIDI jack pin 2 connected to ground
- MIDI jack pin 4 connected to +5V through 220 ohm resistor
- Attach a MIDI cable to the jack, then to a MIDI synth, and play music.
created 13 Jun 2006
modified 13 Aug 2012
by Tom Igoe
This example code is in the public domain.
https://www.arduino.cc/en/Tutorial/BuiltInExamples/Midi
*/
int note = 0x2f;
int organOn = 0;
int pianoOn = 0;
int synthOn = 0;
int rotorOn = 0;
int organPin = 9;
int pianoPin = 7;
int synthPin = 8;
int rotorPin = 10;
int lastOrganState = LOW;
int lastPianoState = LOW;
int lastSynthState = LOW;
int lastRotorState = LOW;
unsigned long lastOrganDebounceTime = 0;
unsigned long lastPianoDebounceTime = 0;
unsigned long lastSynthDebounceTime = 0;
unsigned long lastRotorDebounceTime = 0;
unsigned long debounceDelay = 100;
int controlChange = 0xB0;
int rotorCC = 0x6C; // rotor slow/fast
int pianoCC = 0x21; // piano enable/disable
int synthCC = 0x2A; // synth enable/disable
int organCC = 0x09; // organ enable/disable
int rotorCCOff = 0x2B; // rotor slow, send cc on for fast
int controlChangeOn = 0x7F; // general control change ON
int controlChangeOff = 0x01; // general control change OFF
int lightOn = false;
void setup() {
// Set MIDI baud rate:
Serial.begin(31250);
pinMode(organPin, INPUT_PULLUP);
pinMode(pianoPin, INPUT_PULLUP);
pinMode(synthPin, INPUT_PULLUP);
pinMode(rotorPin, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
// play notes from F#-0 (0x1E) to F#-5 (0x5A):
// for (int note = 0x1E; note < 0x3A; note++) {
//Note on channel 1 (0xorganCC0), some note value (note), middle velocity (0x45):
int rotorState = digitalRead(rotorPin);
if (rotorState != lastRotorState) {
lastRotorDebounceTime = millis();
}
if ((millis() - lastRotorDebounceTime) > debounceDelay) {
if (rotorState < HIGH) {
if (rotorOn == LOW) {
digitalWrite(LED_BUILTIN, true);
noteOn(controlChange, rotorCC, controlChangeOn);
rotorOn = HIGH;
} else {
noteOn(controlChange, rotorCC, rotorCCOff);
rotorOn = LOW;
digitalWrite(LED_BUILTIN, false);
}
delay(250);
}
rotorState = lastRotorState;
}
int organState = digitalRead(organPin);
if (organState != lastOrganState) {
lastOrganDebounceTime = millis();
}
if ((millis() - lastOrganDebounceTime) > debounceDelay) {
if (organState < HIGH) {
if (organOn == LOW) {
digitalWrite(LED_BUILTIN, true);
noteOn(controlChange, organCC, controlChangeOn);
organOn = HIGH;
} else {
noteOn(controlChange, organCC, controlChangeOff);
organOn = LOW;
digitalWrite(LED_BUILTIN, false);
}
delay(250);
}
organState = lastOrganState;
}
int pianoState = digitalRead(pianoPin);
if (pianoState != lastPianoState) {
lastPianoDebounceTime = millis();
}
if ((millis() - lastPianoDebounceTime) > debounceDelay) {
if (pianoState < HIGH) {
if (pianoOn == LOW) {
digitalWrite(LED_BUILTIN, true);
noteOn(controlChange, pianoCC, controlChangeOn);
pianoOn = HIGH;
} else {
noteOn(controlChange, pianoCC, controlChangeOff);
pianoOn = LOW;
digitalWrite(LED_BUILTIN, false);
}
delay(250);
}
pianoState = lastPianoState;
}
int synthState = digitalRead(synthPin);
if (synthState != lastSynthState) {
lastSynthDebounceTime = millis();
}
if ((millis() - lastSynthDebounceTime) > debounceDelay) {
if (synthState < HIGH) {
if (synthOn == LOW) {
digitalWrite(LED_BUILTIN, true);
noteOn(controlChange, synthCC, controlChangeOn);
synthOn = HIGH;
} else {
noteOn(controlChange, synthCC, controlChangeOff);
synthOn = LOW;
digitalWrite(LED_BUILTIN, false);
}
delay(250);
}
synthState = lastSynthState;
}
}
void noteOn(int cmd, int pitch, int velocity) {
Serial.write(cmd);
Serial.write(pitch);
Serial.write(velocity);
}
For anyone reading this posting - I used the code above at a gig the other night and it worked out great. Obviously, you can change the codes that are sent to do anything you can control with midi.
If you build this, let me know, any questions also - leon@zaks.com