Piing
Axe-Master
It has one bug. I don't know why, but it only reads the Preset Name when pressing the switch two times or when selecting a scene.
Problem solved! Ver 6.9 posted.
I have isolated the part of the program that reads the SysEx from the Axe-Fx and debug by sending data to the Serial Monitor
Code:
#include <LiquidCrystal.h>
#include <MIDI.h>
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7);
// constants
static const unsigned ttt = 50; // tempo led illumination time (ms)
static const unsigned ledPin = 50; // tempoLED pin
unsigned long tt; // time tempo sysex pulse detected
char pname[32];
byte pdata[12];
int initial = 0;
int preset = 0;
int scene = 0;
int ppreset = 0;
int blk = 0;
int cc = 0;
int byp = 0;
bool updLCD = false;
unsigned long ct; // call time of FX request in millis
// sysex requests
byte RQSTNAME[6] = { 0x00, 0x01, 0x74, 0x03, 0x0F, 0x09 };
byte RQSTNUM[6] = { 0x00, 0x01, 0x74, 0x03, 0x14, 0x12 };
byte RQSTCC[6] = { 0x00, 0x01, 0x74, 0x03, 0x0E, 0x08 };
byte RQSTSCENE[6] = { 0x00, 0x01, 0x74, 0x03, 0x29, 0x2F };
void setup() {
Serial.begin(115200);
lcd.begin(16, 2);
lcd.clear();
pinMode(ledPin, OUTPUT);
MIDI.begin();
MIDI.turnThruOff();
MIDI.setHandleSystemExclusive(HandleSysEx);
MIDI.sendSysEx(6,RQSTNUM);
delay(50);
MIDI.sendSysEx(6,RQSTNAME);
delay(50);
updLCD = true;
}
void loop() {
MIDI.read();
// update tempo led
if ((millis() - tt) > ttt) {
digitalWrite(ledPin, LOW);
tt = 0; // reset tempo pulse detected time
}
// check if FX block status needs updating
if (ct > 0 && (ct + 100) < millis()) {
MIDI.sendSysEx(6,RQSTCC);
ct = 0;
updLCD = true;
Serial.println("FX block status needs updating");
}
// update LCD display
if (updLCD == true) { Serial.println("Updating LCD");
lcd.clear();
lcd.setCursor(0,0);
lcd.print(pname);
lcd.setCursor(0,1);
lcd.print("Prog:");
lcd.print(preset);
lcd.setCursor(8,1);
lcd.print("Scn:");
lcd.print(scene);
updLCD = false;
}
}
// parse preset number from sysex data
int parseNum(const byte * sysex, int l) {Serial.println("// parse preset number from sysex data");
int out = 0;
if (sysex[6] == 0x00) {
out = int(sysex[7]);
} else {
out = int(sysex[7]) + 128 * int(sysex[6]);
}
return out;
}
// parse preset name from sysex data
void parseName(const byte * sysex, int l) { Serial.println("// parse preset NAME from sysex data");
int out = 0;
// reset char array to spaces
for(byte i = 0x00; i < 0x14; i++) {
pname[i] = 0x20;
}
// get sysex data into char array pname
for(byte i = 0x00; i < 0x14; i++) {
//char p = sysex[i + 6];
pname[i] = sysex[i + 6];
}
}
// callback - handle sysex
void HandleSysEx(byte *SysExArray, unsigned int size) {
int sizear = 0;
if(SysExArray[0]==0xF0) {
Serial.print("MIDI IN:");
Serial.println(SysExArray[5],HEX);
switch (SysExArray[5]) {
case 0x0F: { ;// preset name
Serial.println("case 0x0F // preset name");
const byte *sys = MIDI.getSysExArray();
sizear = MIDI.getSysExArrayLength();
parseName(sys,sizear);
updLCD = true;
break;
}
case 0x29: { // scene
Serial.println("case 0x29 // Scene");
scene = SysExArray[6] + 1;
updLCD = true;
break;
}
case 0x21: { // MIDI event ACK??
Serial.println("case 0x21 // MIDI event ACK?e");
ct = millis();
MIDI.sendSysEx(6,RQSTNUM);
MIDI.sendSysEx(6,RQSTNAME);
updLCD = true;
break;
}
case 0x14: { // preset num
Serial.println("case 0x14 // preset num");
const byte *sys = MIDI.getSysExArray();
sizear = MIDI.getData1();
preset = parseNum(sys,sizear);
MIDI.sendSysEx(6,RQSTNAME);
delay(50);
updLCD = true;
break;
}
case 0x0E: { // FX data
Serial.println("case 0x0E // FX data");
const byte *sys = MIDI.getSysExArray();
sizear = MIDI.getData1();
break;
}
case 0x10: { // tempo
Serial.println("case 0x10E // tempo");
tt = millis();
digitalWrite(ledPin, HIGH);
break;
}
}
}
}
I've found that when changing a preset I was receiving only 0x14 (presetNumber) but not 0x0F (presetName), so I've inserted this line inside case 0x14: { // preset num:
MIDI.sendSysEx(6,RQSTNAME);
delay(50);
I don't know if that is the most orthodox way to do it, but it works
Now It reads the PresetName when selecting the preset from both the controller or the Axe-FX front panel
Last edited: