Yea, I ended up using an Arduino leonardo for it, making it work took some time but it's working like a charm
Posts by Erikcb
-
-
From the MIDI Parameter Documentation:
CC31 (Value 1/0) (1: Show Tuner, 0: Hide Tuner)
Yea, i already know that, the button does that, what i wanted is to show the tuner info in the screen, like the pitch and so so i can use the screen as a tuner (it's not like it's completely necessary for me, but i just like to learn new stuff hahaha)
-
Apparently yes, that was the issue, i had MIDI to UI enabled, so when i sent a message and the kemper reacted, he sent another message back, causing an infinite loop causing the KPA to freeze/act weird.
C
Display More#include <Control_Surface.h> #include <USB-MIDI.h> #include <Wire.h> #include <hd44780.h> // main hd44780 header #include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header hd44780_I2Cexp lcd; const int LCD_COLS = 16; const int LCD_ROWS = 2; // Instantiate the MIDI over USB USBMIDI_Interface myMIDI; USBMIDI_CREATE_DEFAULT_INSTANCE(); // Control Change values const int controlChangeValues[] = {22, 24, 27, 29, 31, 50, 51, 52, 53, 49, 48}; // Text messages const char* buttonMessages[][2] = { {"X OFF", "X ON"}, {"MOD OFF", "MOD ON"}, {"DELAY OFF", "DELAY ON"}, {"REVERB OFF", "REVERB ON"} }; unsigned long messageDisplayTime = 2500; // 3.5 seconds unsigned long lastMessageTime = 0; bool buttonMessageShowing = false; // Show a message on the LCD void showMessage(int buttonIdx, int state) { String message = buttonMessages[buttonIdx][state]; int padding = (LCD_COLS - message.length()) / 2; // Calculate padding for centering lcd.setCursor(0, 0); lcd.print(" "); // Clear the first row lcd.setCursor(padding, 0); lcd.print(message); lastMessageTime = millis(); // Update the last message time buttonMessageShowing = true; Serial.print("Showing message: "); Serial.println(message); } // MIDI callback that prints incoming SysEx messages. struct MyMIDI_Callbacks : MIDI_Callbacks { void onSysExMessage(MIDI_Interface& interface, SysExMessage sysex) override { // Check if the message is from the USB MIDI interface if (&interface != &myMIDI) return; // Handle the response for the effect module state if (sysex.length == 13 && sysex.data[0] == 0xF0 && sysex.data[1] == 0x00 && sysex.data[2] == 0x20 && sysex.data[3] == 0x33) { if (sysex.data[5] == 0x00 && sysex.data[6] == 0x01) { int buttonIdx = -1; switch (sysex.data[8]) { case 0x38: buttonIdx = 0; break; // Button 1 case 0x3A: buttonIdx = 1; break; // Button 2 case 0x3C: buttonIdx = 2; break; // Button 3 case 0x3D: buttonIdx = 3; break; // Button 4 } if (buttonIdx != -1) { int ccValue = (sysex.data[11] == 0x01) ? 0 : 1; // If on, send 0; if off, send 1 MIDI.sendControlChange(controlChangeValues[buttonIdx], ccValue, 1); showMessage(buttonIdx, ccValue); Serial.print("Sent CC for button "); Serial.print(buttonIdx + 1); Serial.print(": "); Serial.println(ccValue); } } } // Performance and slot name display if (sysex.length >= 7) { if (sysex.data[0] == 0xF0 && sysex.data[1] == 0x00 && sysex.data[2] == 0x20 && sysex.data[3] == 0x33) { if (!buttonMessageShowing) { if (sysex.data[6] == 0x07) { displayMessage(sysex, 6, 0); // Performance name on the first row } else if (sysex.data[6] == 0x03) { displayMessage(sysex, 6, 1); // Slot name on the second row } } } } } void displayMessage(SysExMessage& sysex, int startIdx, int row) { String message; for (int i = startIdx; i < sysex.length - 1; ++i) { uint8_t byte = sysex.data[i]; if (byte >= 0x20 && byte <= 0x7E) { message += char(byte); } } int padding = (LCD_COLS - message.length()) / 2; // Calculate padding for centering lcd.setCursor(0, row); lcd.print(" "); // Clear the entire row lcd.setCursor(padding, row); // Set cursor to the calculated position lcd.print(message); Serial.print("Displayed message on row "); Serial.print(row); Serial.print(": "); Serial.println(message); } } callback{}; // Buttons Initialization const int buttonPins[] = {0, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12}; const int numButtons = sizeof(buttonPins) / sizeof(buttonPins[0]); // Display a startup message void displayProgressBar() { lcd.clear(); lcd.setCursor(0, 0); lcd.print(" KEMPER "); lcd.setCursor(0, 1); lcd.print(" PROFILER "); Serial.println("Displayed progress bar"); } // Track the state for button 5 bool button5State = false; // Variables for initial delay const unsigned long initialDelay = 37500; // 37.5 seconds unsigned long setupTime = 0; bool initialDelayCompleted = false; // void setup() { Serial.begin(31250); Wire.begin(); lcd.begin(LCD_COLS, LCD_ROWS); displayProgressBar(); // Display the text on startup myMIDI.begin(); MIDI.begin(MIDI_CHANNEL_OMNI); myMIDI.setCallbacks(callback); // Initialize button pins as inputs for (int i = 0; i < numButtons; ++i) { pinMode(buttonPins[i], INPUT); } // Store the setup time setupTime = millis(); } // Define the interval between sending each SysEx message const unsigned long sysExInterval = 500; // Store the last time a SysEx message was sent unsigned long lastSysExTime = 0; // Debounce delay const unsigned long debounceDelay = 300; unsigned long lastDebounceTimes[numButtons] = {0}; // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void loop() { unsigned long currentTime = millis(); // Check if the initial delay is completed if (!initialDelayCompleted && (currentTime - setupTime >= initialDelay)) { initialDelayCompleted = true; lastSysExTime = currentTime; // Start SysEx timer after the initial delay Serial.println("Initial delay completed"); } // Clear the message if it's been displayed for the specified duration if (buttonMessageShowing && (currentTime - lastMessageTime >= messageDisplayTime)) { lcd.setCursor(0, 0); lcd.print(" "); // Clear the first row buttonMessageShowing = false; Serial.println("Cleared button message"); } // Check if it's time to send the SysEx message if (initialDelayCompleted && (currentTime - lastSysExTime >= sysExInterval)) { if (!buttonMessageShowing) { requestPerformanceName(); requestSlotName(); } lastSysExTime = currentTime; // Update the last SysEx message time } // Check buttons and send CC or SysEx for (int i = 0; i < numButtons; ++i) { if (digitalRead(buttonPins[i]) == HIGH) { if ((currentTime - lastDebounceTimes[i]) > debounceDelay) { if (i < 4) { // For buttons 1 to 4 requestEffectModuleState(i); } else if (i == 4) { // Button 5 button5State = !button5State; // Toggle the state int ccValue = button5State ? 1 : 0; MIDI.sendControlChange(controlChangeValues[i], ccValue, 1); Serial.print("Sent CC for button 5: "); Serial.println(ccValue); } else if (i == 9 || i == 10) { // Buttons 10 and 11 MIDI.sendControlChange(controlChangeValues[i], 0, 1); Serial.print("Sent CC for button "); Serial.print(i + 1); Serial.println(": 0"); } else { // For buttons 6 to 8 and 12 MIDI.sendControlChange(controlChangeValues[i], 127, 1); Serial.print("Sent CC for button "); Serial.print(i + 1); Serial.println(": 127"); } lastDebounceTimes[i] = currentTime; // Update the debounce time } } } // Update MIDI interface myMIDI.update(); } // Request the effect state for buttons 1 to 4 void requestEffectModuleState(int buttonIdx) { uint8_t sysexMessage[][11] = { {0xF0, 0x00, 0x20, 0x33, 0x00, 0x00, 0x41, 0x00, 0x38, 0x03, 0xF7}, // Button 1 {0xF0, 0x00, 0x20, 0x33, 0x00, 0x00, 0x41, 0x00, 0x3A, 0x03, 0xF7}, // Button 2 {0xF0, 0x00, 0x20, 0x33, 0x00, 0x00, 0x41, 0x00, 0x3C, 0x03, 0xF7}, // Button 3 {0xF0, 0x00, 0x20, 0x33, 0x00, 0x00, 0x41, 0x00, 0x3D, 0x03, 0xF7} // Button 4 }; myMIDI.sendSysEx(sysexMessage[buttonIdx], sizeof(sysexMessage[buttonIdx])); Serial.print("Requested effect module state for button "); Serial.println(buttonIdx + 1); } // Request performance name void requestPerformanceName() { uint8_t sysexPerformance[] = {0xF0, 0x00, 0x20, 0x33, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xF7}; myMIDI.sendSysEx(sysexPerformance, sizeof(sysexPerformance)); Serial.println("Requested performance name"); } // Request slot name void requestSlotName() { uint8_t sysexSlot[] = {0xF0, 0x00, 0x20, 0x33, 0x02, 0x7F, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF7}; myMIDI.sendSysEx(sysexSlot, sizeof(sysexSlot)); Serial.println("Requested slot name"); }
That's the code i ended up using, it's basically buttons 1 to 4 requesting the effects status on press and acting accordingly (turning the effect on/off depending on the status) button 5 toggles the tuner on and off, buttons 6 to 9 change slot, 10 and 11 go performance up/down, also it requests the performance and slot names every 500ms and prints it on the screen, buttons 1 to 4 also send a message like "Delay On" or "Delay Off" when enabling/disabling each effect.
I added a delay of 37'5 seconds to avoid the controller to start sending SysEx messages while the Kemper is booting (i had to do it cause if not the Kemper crashed on boot).
I found a way to get the SysEx messages, just connect the Kemper via USB to your PC, get a MIDI sniffer (like MIDIview/MIDI-OX) and set the profiler as input/output. Then just tweak the kemper as desired and you'll see the SysEx on the PC (i know this works for enabling/disabling stuff, not sure about changing values like volume, mix, etc.).
Of course i found this when i already gathered the SysEx by myself.
Now i'd love to know if there is a way to make the screen show the tuner info via MIDI or SysEX or whatever, like the other controllers do, but so far i only found the Sysex to enable or disable it... -
I tested with a PROFILER Head with 11 OS public beta and MIDI OX
a. via a normal USB cable connected to the Head's USB B socket,
b. with an OTraki USB to MIDI interface plugged into the Head's MIDI IN socket.
In both cases the PROFILER executes the incoming MIDI comands correctly. No loops no hangs.
I made sure, Pedals to MIDI and UI to MIDI are not activated.
I suggest you take the other device out of the equation, so you know, the PROFILER used standalone with MIDI OX is not he trouble maker.
I guess, there is a risk, that you are building a MIDI loop, where MIDI comands get bounced in circles.
I'll make sure to check that thanks!
So having UI to MIDI enabled is not necessary to get the SysEx responses as i need?
I thought it was necessary so the kemper sends the rig, slot, performance names and everything...if it's not necessary that might be the issue? -
I tested it via software (MIDI-OX) and when i send a CC or a SysEx having both the arduino and the Kemper as input and output (so the arduino can receive the sysex frome the Kemper and act accordingly) it seems like it enters in a loop where it keeps sending the CCs or SysEx messages until i disable the inputs and outputs in MIDI-OX. That might be what's causing it to freeze/act weird?? I'm not sure if that's a problem from MIDI-OX or maybe the beta is buggy and the Kemper goes nuts and starts looping...
-
I managed to get some SysEx messages using some i had and checking the midi documentation, the info about this on the documentation could be simplier tbh .
EFFECT MODULE A EFFECT MODULE B EFFECT MODULE C EFFECT MODULE D EFFECT MODULE X EFFECT MODULE MOD EFFECT MODULE DELAY EFFECT MODULE REVERB CURRENT RIG NAME CURRENT PERFORMANCE NAME CURRENT SLOT NAME REQUEST STATUS
(ON/OFF)F0 00 20 33 00 00 41 00 32 03 F7 F0 00 20 33 00 00 41 00 33 03 F7 F0 00 20 33 00 00 41 00 34 03 F7 F0 00 20 33 00 00 41 00 35 03 F7 F0 00 20 33 00 00 41 00 38 03 F7 F0 00 20 33 00 00 41 00 3A 03 F7 F0 00 20 33 00 00 41 00 3C 03 F7 F0 00 20 33 00 00 41 00 3D 03 F7 F0 00 20 33 02 7F 43 00 00 01 F7 F0 00 20 33 00 00 47 00 00 00 01 00 00 F7 F0 00 20 33 02 7F 47 00 00 00 00 00 01 F7 TOGGLE ON F0 00 20 33 00 00 01 00 32 03 00 01 F7 F0 00 20 33 00 00 01 00 33 03 00 01 F7 F0 00 20 33 00 00 01 00 34 03 00 01 F7 F0 00 20 33 00 00 01 00 35 03 00 01 F7 F0 00 20 33 00 00 01 00 38 03 00 01 F7 F0 00 20 33 00 00 01 00 3A 03 00 01 F7 F0 00 20 33 00 00 01 00 3C 03 00 01 F7 F0 00 20 33 00 00 01 00 3D 03 00 01 F7 TOGGLE OFF F0 00 20 33 00 00 01 00 32 03 00 00 F7 F0 00 20 33 00 00 01 00 33 03 00 00 F7 F0 00 20 33 00 00 01 00 34 03 00 00 F7 F0 00 20 33 00 00 01 00 35 03 00 00 F7 F0 00 20 33 00 00 01 00 38 03 00 00 F7 F0 00 20 33 00 00 01 00 3A 03 00 00 F7 F0 00 20 33 00 00 01 00 3C 03 00 00 F7 F0 00 20 33 00 00 01 00 3D 03 00 00 F7
Maybe for others it's not that hard to find out, but it took me quite some time, so i rather sharing it here so people can see it.
There's many other things you can do with SysEx messages, but those are the ones i need so far so this are the ones i have.
Now i need to do some changes in the code so the buttons request the status and act accordingly.
And the most important thing, get to know what's causing the Kemper to freeze when i connect the controller and if it's a bug of the beta wait for it to get fixed...
Hope that those SysEx messages help someone!! -
I'm having a similar problem with MIDI command interaction with the KPA via USB-A, whether it's CC or PC or SYSEX commands, as long as it's Rig or Slot switching via midi commands, it inevitably crashes, and there's no workaround for that at the moment
Yea, I already saw your post, I guess it's a bug of the beta?? (first bug I experience in a beta so far)
Hope it can be solved fast, thanks!
And hope someone knows about the sysex for effects too
-
I'm trying to modify my midi controller (it used to send CCs via midi cable) to send CCs and SysEx messages via usb, so i can request some info (effect status, rig/performance/slot names...) and for some reason my kemper freezes when i send a message.
C
Display More#include <Control_Surface.h> #include <USB-MIDI.h> #include <Wire.h> #include <hd44780.h> // main hd44780 header #include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header hd44780_I2Cexp lcd; const int LCD_COLS = 16; const int LCD_ROWS = 2; // Instantiate the MIDI over USB interface USBMIDI_Interface myMIDI; // Custom MIDI callback that prints incoming SysEx messages. struct MyMIDI_Callbacks : MIDI_Callbacks { void onSysExMessage(MIDI_Interface& interface, SysExMessage sysex) override { // Check if the message is from the USB MIDI interface if (&interface != &myMIDI) return; // Check the first few bytes of the SysEx message to determine its type if (sysex.length >= 7) { if (sysex.data[0] == 0xF0 && sysex.data[1] == 0x00 && sysex.data[2] == 0x20 && sysex.data[3] == 0x33) { if (sysex.data[6] == 0x07) { displayMessage(sysex, 6, 0); // Performance name on the first row } else if (sysex.data[6] == 0x03) { displayMessage(sysex, 6, 1); // Slot name on the second row } } } } void displayMessage(SysExMessage& sysex, int startIdx, int row) { String message; for (int i = startIdx; i < sysex.length - 1; ++i) { uint8_t byte = sysex.data[i]; if (byte >= 0x20 && byte <= 0x7E) { message += char(byte); } } int padding = (LCD_COLS - message.length()) / 2; // Calculate padding for centering lcd.setCursor(0, row); lcd.print(" "); // Clear the entire row lcd.setCursor(padding, row); // Set cursor to the calculated position lcd.print(message); } } callback{}; USBMIDI_CREATE_DEFAULT_INSTANCE(); // Buttons Initialization const int buttonPins[] = {0, 13, 4, 5, 6, 7, 8, 9, 10, 11, 12}; const int numButtons = sizeof(buttonPins) / sizeof(buttonPins[0]); const int controlChangeValues[] = {22, 24, 27, 28, 31, 50, 51, 52, 53, 49, 48}; // Function to display a fake progress bar void displayProgressBar() { lcd.clear(); lcd.setCursor(0, 0); lcd.print(" KEMPER "); lcd.setCursor(0, 1); lcd.print(" PROFILER "); } // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void setup() { Serial.begin(31250); Wire.begin(); lcd.begin(LCD_COLS, LCD_ROWS); displayProgressBar(); // Display the fake progress bar on startup myMIDI.begin(); MIDI.begin(MIDI_CHANNEL_OMNI); myMIDI.setCallbacks(callback); // Initialize button pins as inputs for (int i = 0; i < numButtons; ++i) { pinMode(buttonPins[i], INPUT); } } // Define the interval between sending each SysEx message (in milliseconds) const unsigned long sysExInterval = 1000; // 2 seconds // Variable to store the last time a SysEx message was sent unsigned long lastSysExTime = 0; // Variable to store the last time a Control Change message was sent unsigned long lastCCTime = 0; // Debounce delay const unsigned long debounceDelay = 600; unsigned long lastDebounceTimes[numButtons] = {0}; // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void loop() { unsigned long currentTime = millis(); // Check if it's time to send the SysEx message if (currentTime - lastSysExTime >= sysExInterval) { requestPerformanceName(); requestSlotName(); lastSysExTime = currentTime; // Update the last SysEx message time } // Check buttons and send Control Change messages for (int i = 0; i < numButtons; ++i) { if (digitalRead(buttonPins[i]) == HIGH) { if ((currentTime - lastDebounceTimes[i]) > debounceDelay) { MIDI.sendControlChange(controlChangeValues[i], 127, 1); lastDebounceTimes[i] = currentTime; // Update the debounce time } } } // Update MIDI interface myMIDI.update(); delay(100); } // Function to request performance name void requestPerformanceName() { uint8_t sysexPerformance[] = {0xF0, 0x00, 0x20, 0x33, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xF7}; myMIDI.sendSysEx(sysexPerformance, sizeof(sysexPerformance)); } // Function to request slot name void requestSlotName() { uint8_t sysexSlot[] = {0xF0, 0x00, 0x20, 0x33, 0x02, 0x7F, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF7}; myMIDI.sendSysEx(sysexSlot, sizeof(sysexSlot)); }
I'm new to programming and SysEx and all, but i find weird that it only crashes when i send a message.
The idea is to send CC and SysEx, so far I send SysEx every X time (the one in the code is just for testing, I don't know how often i caa request it without the kemper having issues) and send CCs when pressing the buttons, but the kemper "randoml"y freezes some times.I'm using the front USB A port, right now i don't have any other way to test it.
I tried many things and i changed the code many times, this is the closest i've been to make it work, but for some reason the unit keeps freezing...
Any idea why could it be or what could cause It?I'd also like to make some buttons to request stomps status (mostly X, Mod, Delay, and Reverb, but if I could find the ones for the other stack it would be great too) and act accordingly, if it's off turn it on and so, but I can't find the SysEx messages for that, I only have the Mod one and only cause I got it from support.
EDIT: I changed the code, it'sstill freezing, not all the times, but it still happens
-
i did share some sysex code for this here:
PostRE: Profiler MIDI documentation - information missing on string parameter addresses
ok guys, so digging out an OLD project i started years ago and gave up on, i got as far as controlling the Kemper with midi and retrieving the preset/slot names using system-exclusive. Demo here:
youtu.be/KZTmyCH1Sqs
the bit of code for getting the names via sysex:
(Code, 22 lines)
Sorry, i'm not offering technical support. It has been so long that i done this project i'd effectively be starting from scratch to unravel this lot.
Hope the above helps and shows you what is possible.slateboyFebruary 22, 2024 at 4:08 PM SEND call for rig name
F0 00 20 33 02 7F 43 00 00 01 F7
(you already got this)What are you receiving back and how are you dealing with that data?
I'm just trying to find stuff in Google and test things, trial and error, you know, so I'm not very sure what I'm doing or how I'm approaching to get it working hahahah
This is the code I'm using. I had to attach it as a txt file cause it's too long. It's sending the sysex, but i think it's not able to translate it properly and post it on the screen.
The code could be better and more organised, i know, but as i said i barely know what I'm doing.
There's some stuff i have to remove, i tried to make it write the rig name manually and also save them in the eeprom so it's shown when turned on, but it's not necessary now.
I want to make it work first, then I'll (probably) make it look better.
I know the sysex y posted are working cause I'm testing them with a midi monitor that lets me send and receive sysex messages (it's called Midi-OX).
-
Just got the sysex for the current performance/rig/slot names, i'll leave them here in case someone ever needs them, it works properly via software, now all i need is to figure out what's wrong with my code!!
- Current Slot Name:
0xF0, 0x00, 0x20, 0x33, 0x02, 0x7F, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF7 - Current Rig Name:
0xF0, 0x00, 0x20, 0x33, 0x02, 0x7F, 0x43, 0x00, 0x00, 0x01, 0xF7 - Current Performance:
0xF0, 0x00, 0x20, 0x33, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xF7
- Current Slot Name:
-
check you not got a midi-through enabled sending back exactly what you send out
It's not that, i have no idea what's the issue, right now i'm trying to figure out what the sysex for the performance name is, since i can't find anything in the documentation, nor the sysex nor the nrpn...
I guess there is something wring with the way the code is retrieveing the sysex...
Anyway, for now i want to know if there is a way to get the performance name or not, since i can't find anything anywhere about it, i'll try to fix the code later...
-
So, i am sending 0xF0, 0x00, 0x20, 0x33, 0x02, 0x7F, 0x43, 0x00, 0x00, 0x01, 0xF7 which according to the manual is the sysex to request the current values of the rig name but all i get for response is the same exact sysex, it's not including the rig name for some reason, do i have to send anything else besides that sysex?
EDIT: I managed to send and receive the messages via software, i need to figure out/find what the performance name sysex is, and find out what's wrong with my code, but we're getting closer!
-
It will get returned as another sysex message with the text encoded as ascii characters. Your mission is to extract the hex digits that represent the characters within the sysex message and then convert each into a readable character then output as astring.
I see, interesting, I'll take a look at it tomorrow, thanks!
-
I have not done any midi to/from the kemper over USB. I have not reached the stage where i have made (reflashed the arduino to create) a class-compliant (recognisable) USB-midi device. I am only as far as midi over the standard 5-pin, so unable to comment. Sorry.
no worries, i'm starting to make it work, it's taking time, but it's ok, i managed to send sysex and receive them and print on the screen, but i think i have to get it translated or something, cause i'm getting the sysex message as it is, i'll figure it out eventually hahaha
thanks!
-
Are we sure sending sysex via USB is doable at this point? I've been trying stuff all day and nothing worked, i can't even make the arduino to send sysex, of course not talking about reading them...
I managed to make it send sysex via midi, but no luck with USB so far...
EDIT: i just managed to send sysex via usb on it, so it's doable, the kemper is freezing again tho)
This should be the sysex to get the rig name right? Does it also work in performance mode? Or do i have to find some sysex to retrieve slot name??
All i need is the screen to show performance name and the slot/rig name for the moment. -
Yes, it can be heavy-going! Take a look at this thread:
PostRE: Profiler MIDI documentation - information missing on string parameter addresses
ok guys, so digging out an OLD project i started years ago and gave up on, i got as far as controlling the Kemper with midi and retrieving the preset/slot names using system-exclusive. Demo here:
youtu.be/KZTmyCH1Sqs
the bit of code for getting the names via sysex:
(Code, 22 lines)
Sorry, i'm not offering technical support. It has been so long that i done this project i'd effectively be starting from scratch to unravel this lot.
Hope the above helps and shows you what is possible.slateboyFebruary 22, 2024 at 4:08 PM I'll take a look on it, althought i have no idea how to make it work hahah
Thanks!!
-
This is starting to seem pretty hard, i'm ok with "only" using CCs instead od nrpn and the issue with having to press twice for effects is not really too nanoying, i barely enable/disable stuff, but i'd like to use the screen to retrieve info from the kemper, i've been researching for a while, no luck so far
-
So apparently it was an issue cause by the kemper sending info and the arduino not reading it, causing the kemper to freeze, i added this
Code
Display MoremidiEventPacket_t rx; do { rx = MidiUSB.read(); if (rx.header != 0) { Serial.print("Received: "); Serial.print(rx.header, HEX); Serial.print("-"); Serial.print(rx.byte1, HEX); Serial.print("-"); Serial.print(rx.byte2, HEX); Serial.print("-"); Serial.println(rx.byte3, HEX); } } while (rx.header != 0);
to my code and apparently it's not freezing now, also, i noticed that normal CCs are working properly (same as they did in my old code).
So i have a few questions.
1) If i use the controller to switch between rigs in performance mode, go performance up/down, enable the tuner and turn effects on/off, what's the advantage of using nrpn agains normal CCs as i was using?
2) My code was not acting properly since the beggining, it wasn't "remembering" the effect status, so some times to turn effects on/off i have to press the button twice (let's say delay is off, i press once, the arduino sends off CC, so it does nothing, and then i have to press it again to turn it on) is there a workaround for that? It's not a big issue for me since i don't play live or anything, but it would be cool to get it fixed.3) Any idea how could i make the screen to show kemper info? Mostly performance in one row and rig name on the second one, i dont need too much stuff.
Thanks!
-
Have you got some kind of midi monitor device? Worth checking if there is any unwanted midi data or other noise getting sent that is not required. or perhaps it is sending/getting incomplete midi messages?
Or maybe (as i have had in the past) the ardiuno is stalling and not sending out a steady/even flow of midi data. I found that constantly updating the screen on the arduino LCD takes a lot of processing-power that affects midi transmission and better to update the display only when needed, ie a change of data. Therefore the priority is prioritising midi data flow rather than a visual.
This are two different midi monitors (software) showing what the arduino is sending (two messages each, turn on/off, two different presses) there's no more messages unless i press the button again and there's no signs of it disconnecting or anything...
I don't think there's anything wrong, i set the baud rate to 31250 and it still freezes my kemper as soon as i connect it, i didn't change anything in the code besides the baud rate (maybe there is something wrong with the code? no idea...)
EDIT: I just tried to connect it with an empty code, and the kemper is not crashing...
-
The standard for midi (not USB midi) is a baud rate of 31250 so that must be adhered to
I already tried with 31250 but the kemper still freezed, i have no idea why
Quote from slateboythis is the bit that i initially figured out with trial-and-error rather than an educated approach.
The "proper way" would be to find the range of that parameter, in this case -6db to +6db where 0dB is mid-way, therefore a full-scale range of 12
divide the NRPN range 16383 into 12 = 1365 per dB step (could be taken as smaller steps if you want 0.1dB resolution) then to get the values
1365 x 6 = 8192 (0dB setting) then divide by 128 for the MSB value which = 64 ( i've lost the LSB value somewhere there...)
That's actually easier than i thought, thanks.