Sending one CC with MSB/LSB from Midi-ox, it works:
Code:PC_SW1=0 PC_SW2=-1 CC_SW1=-1 CC_SW2=80 CC_SW1=80 CC_SW2=81
If i unmanrk MSB/LSB nothing is sent, as happens with the midi controller.
Printing nothing implies no PC was received on channel 1.
Other than that the variables look like they work as expected.
#include <Bounce.h> // Bounce library makes button change detection easy
const int scanMax = 100; // set the time limit for CC to follow PC
const byte channel = 1; // set channel to filter/send midi
const int SW1pin = 0; // set SW1 pin
const int SW2pin = 1; // set SW2 pin
int SW1 = 80; // default SW1 CC number (D1)
int SW2 = 81; // default SW2 CC number (D1)
int SW1D2 = 0; // default SW1 CC number (D2)
int SW2D2 = 0; // default SW2 CC number (D2)
elapsedMillis scanStart;
Bounce button1 = Bounce(0, 25); // 5 = 5 ms debounce time
Bounce button2 = Bounce(1, 25); // which is appropriate for good quality mechanical pushbuttons but I'm using a bare wire!
void setup() {
Serial.begin(9600);
pinMode(SW1pin, INPUT_PULLUP);
pinMode(SW2pin, INPUT_PULLUP);
}
void loop(void)
{
button1.update();
button2.update();
// send CC messages when SW1 or SW2 are pulled LOW
if (button1.fallingEdge()) {
usbMIDI.sendControlChange(SW1, SW1D2, channel);
}
if (button2.fallingEdge()) {
usbMIDI.sendControlChange(SW2, SW2D2, channel);
}
if (usbMIDI.read(channel)) { // limit reads to single channel
if (usbMIDI.getType() == usbMIDI.ProgramChange){
scanStart = 0;
SW1 = 0;
SW1D2 = 0;
SW2 = -1;
SW2D2 = -1;
Serial.print("PC_SW1=");
Serial.println(SW1);
Serial.print("PC_SW2=");
Serial.println(SW2);
}else if(usbMIDI.getType() == usbMIDI.ControlChange) {
if (scanStart <= scanMax) {
SW1 = SW2;
SW1D2 = SW2D2;
SW2 = usbMIDI.getData1();
SW2D2 = usbMIDI.getData2();
Serial.print("CC_SW1=");
Serial.println(SW1);
Serial.print("CC_SW2=");
Serial.println(SW2);
}
}
}
if (scanStart >= scanMax) {
if (SW1 < 0) { // if there was only 1 CC SW1 is negative and we will swap and set SW2 = 0
SW1 = SW2;
SW1D2 = SW2D2;
SW2 = 0;
SW2D2 = 0;
Serial.print("TO_SW1=");
Serial.println(SW1);
Serial.print("TO_SW2=");
Serial.println(SW2);
}
}
}
...apologies for that physical vs tft buttons...
// include the ResponsiveAnalogRead library for analog smoothing
#include <ResponsiveAnalogRead.h>
#include <Bounce.h> // Bounce library makes button change detection easy
// ******CONSTANT VALUES******** - customize code behaviour here!
// SET THESE SIX VALUES!
const int pitchPin = 0; // PIN numbers ** MUST CHANGE!
const int modPin = 1;
const int modPin2 = 1;
const int pitchMaxRaw = 1019; // Max reading with full bend up... as raw 10-bit value
const int modMaxRaw = 1019; // Max reading full mod down
const int channel = 1; // MIDI channel
const int MIDIdelay = 5; // will update MIDI only if this many milliseconds have passed
//******VARIABLES***********
// data variables and a lagged copy to compare before updating MIDI value
int pitch;
int mod;
int mod2;
int pitchRaw;
int modRaw;
int modRaw2;
int pitchLag;
int modLag;
int modLag2;
elapsedMillis pitchUpdate;
elapsedMillis modUpdate;
elapsedMillis modUpdate2;
// ititialize the ReponsiveAnalogRead objects
ResponsiveAnalogRead readPitch = {pitchPin, true};
ResponsiveAnalogRead readMod = {modPin, true};
ResponsiveAnalogRead readMod2 = {modPin2, true};
void setup() {
pinMode(1, INPUT_PULLUP);
pinMode(2, INPUT_PULLUP);
}
void loop()
{
delay(100);
getAnalogData();
while (usbMIDI.read()) {
}
}
//************ANALOG SECTION**************
void getAnalogData() {
readPitch.update();
if (readPitch.hasChanged()) {
pitchRaw = readPitch.getValue();
Serial.println(pitchRaw);
// remap to output data and send if changed and MIDIdelay has lapsed since last update for that parameter
pitch = map(pitchRaw, 3, 1019, 0, 127);
pitch = max(pitch, 0); // need this now that the bottom isn't zero
pitch = min(pitch, 127); // cap to avoid overflow
if (abs(pitch - pitchLag) > 0 && pitchUpdate > MIDIdelay ) {
pitchLag = pitch;
usbMIDI.sendPitchBend(pitch, channel);
Serial.print("Joystick Pitchbend=");
Serial.println(pitch);
pitchUpdate = 0;
}
}
readMod.update();
if (readMod.hasChanged()) {
modRaw = readMod.getValue();
// remap to output data and send if changed and MIDIdelay has lapsed since last update for that parameter
mod = map(modRaw, 510, 1019, 64, 127); // N.B. - map does not limit values
mod = max(mod, 64); // minimum could overflow is modRaw is greater than calabrated -This way Y Center-Down will only send from 64 to 127 values
//mod = min(mod,64);
if (mod != modLag && modUpdate > MIDIdelay ) { // resolution reduction should be enough wi
modLag = mod;
usbMIDI.sendControlChange(1, mod, channel); // CC = 1 is mod wheel in standard MIDI
modUpdate = 0;
}
}
readMod2.update();
if (readMod2.hasChanged()) {
modRaw2 = readMod2.getValue();
// remap to output data and send if changed and MIDIdelay has lapsed since last update for that parameter
mod2 = map(modRaw2, 3, 507, 0, 63); // N.B. - map does not limit values
mod2 = max(mod2, 0); // minimum could overflow if modRaw2 is greater than calibrated
mod2 = min(mod2, 63); // This way Y Center-Up will only send from 0 till 63 values
//mod = min(mod2,63);
if (mod2 != modLag2 && modUpdate2 > MIDIdelay ) { // resolution reduction should be enough wi
modLag2 = mod2;
usbMIDI.sendControlChange(2, mod2, channel); // CC = 2 is Breath Control in standard MIDI -In this case it is
modUpdate2 = 0;
}
{
}
}
}
TIMESTAMP IN PORT STATUS DATA1 DATA2 CHAN NOTE EVENT
000392F7 23 -- E0 34 40 1 --- Pitch Bend
00039302 23 -- E0 35 40 1 --- Pitch Bend
0003930D 23 -- E0 36 40 1 --- Pitch Bend
00039315 23 -- E0 37 40 1 --- Pitch Bend
0003931F 23 -- E0 38 40 1 --- Pitch Bend
00039329 23 -- E0 39 40 1 --- Pitch Bend
00039332 23 -- E0 3A 40 1 --- Pitch Bend
0003933E 23 -- E0 3B 40 1 --- Pitch Bend
0003934A 23 -- E0 3C 40 1 --- Pitch Bend
0003935A 23 -- E0 3D 40 1 --- Pitch Bend
00039368 23 -- E0 3E 40 1 --- Pitch Bend
00039375 23 -- E0 3F 40 1 --- Pitch Bend
00039386 23 -- E0 40 40 1 --- Pitch Bend
0003C6AF 23 -- E0 41 40 1 --- Pitch Bend
TIMESTAMP IN PORT STATUS DATA1 DATA2 CHAN NOTE EVENT
000988BC 23 -- B0 02 3E 1 --- CC: Breath
000988CC 23 -- B0 02 3D 1 --- CC: Breath
000988D6 23 -- B0 02 3C 1 --- CC: Breath
000988DE 23 -- B0 02 3B 1 --- CC: Breath
000988E6 23 -- B0 02 3A 1 --- CC: Breath
000988EC 23 -- B0 02 39 1 --- CC: Breath
TIMESTAMP IN PORT STATUS DATA1 DATA2 CHAN NOTE EVENT
000A3A96 23 -- B0 01 41 1 --- CC: Modulation
000A3AB8 23 -- B0 01 42 1 --- CC: Modulation
000A3AC6 23 -- B0 01 43 1 --- CC: Modulation
000A3ACC 23 -- B0 01 44 1 --- CC: Modulation
000A3AD3 23 -- B0 01 45 1 --- CC: Modulation
000A3AD8 23 -- B0 01 46 1 --- CC: Modulation
000A3ADE 23 -- B0 01 47 1 --- CC: Modulation
000A3AE5 23 -- B0 01 48 1 --- CC: Modulation
000A3AEA 23 -- B0 01 49 1 --- CC: Modulation
000A3AF0 23 -- B0 01 4A 1 --- CC: Modulation
000A3AF6 23 -- B0 01 4B 1 --- CC: Modulation
000A3AFC 23 -- B0 01 4D 1 --- CC: Modulation
000A3B02 23 -- B0 01 4E 1 --- CC: Modulation
const int pitchMaxRaw = 1019; // Max reading with full bend up... as raw 10-bit value
pitch = map(pitchRaw, 12, 1021, 0, [B]16383[/B]);
pitch = max(pitch, 0); // need this now that the bottom isn't zero
pitch = min(pitch, [B]16383[/B]); // cap to avoid overflow