DIY Arduino Foot Controller

Best to store preset name into a dedicated char array, I use this process:

Code:
// This is defined in a header file
char pname[MAX_PRESET_N_LENGTH];
//

 if (MIDI.getSysExArray()[5] == 0x0f){
          for(int i=0;i<31;++i){
            pname[i] = MIDI.getSysExArray()[i+6];
          }
          for(int i=31;i!=0;--i){ //backwards removal of space
            if (pname[i] == 0x20){
              pname[i] = 0x00;
            }
            else { break;}
          }
          Serial.println(pname);
        }

QUOTE]

Brilliant - thanks works a treat.
 
Almost there now - 1 little niggle where by after exiting Tuner mode (& display on LCD) - can't get it to immediately re-display my basic current preset info.
Only works after another switch is pressed.
Initial debugging shows several Tuner Sysex's are continued to be sent even after the tuner is disabled.
Does that sound right?
Probably something simple so will try working through that tonight.

Whilst I'm on - anyone know if the Sysex function ID listing at MIDI SysEx - Axe-Fx II Wiki is fully comprehensive?

Refering back to an earlier post from Jon regarding checking what sysex's are getting sent after a preset change - I seem to be getting some that are not listed. ie:

00000F3A 1 -- F0 Buffer: 10 Bytes System Exclusive 14 MIDI_GET_PRESET_NUMBER
00000F58 1 -- F0 Buffer: 67 Bytes System Exclusive 0E MIDI_GET_PRESET_EFFECT_BLOCKS_AND_CC_AND_BYPASS_STATE
00000F58 1 -- F0 Buffer: 9 Bytes System Exclusive 29 MIDI_SET_SCENE_NUMBER
00000F86 1 -- F0 Buffer: 200 Bytes System Exclusive 20 MIDI_GET_ROUTING_GRID_LAYOUT
00000FB4 1 -- F0 Buffer: 33 Bytes System Exclusive 2 MIDI_GET_PARAMETER, MIDI_SET_PARAMETER
00000FD3 1 -- F0 Buffer: 31 Bytes System Exclusive 2 MIDI_GET_PARAMETER, MIDI_SET_PARAMETER
00000FF4 1 -- F0 Buffer: 9 Bytes System Exclusive 13 ?
00001015 1 -- F0 Buffer: 9 Bytes System Exclusive 2A ?
00001037 1 -- F0 Buffer: 40 Bytes System Exclusive F MIDI_GET_PRESET_NAME
00001055 1 -- F0 Buffer: 10 Bytes System Exclusive 2F ?
00001073 1 -- F0 Buffer: 27 Bytes System Exclusive 2 MIDI_GET_PARAMETER, MIDI_SET_PARAMETER
00001091 1 -- F0 Buffer: 28 Bytes System Exclusive 2 MIDI_GET_PARAMETER, MIDI_SET_PARAMETER
000010BA 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
000010DB 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
000010F9 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001118 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001137 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001159 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001177 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001196 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
000011B4 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
000011D5 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
000011F3 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001212 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001232 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001250 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
0000126F 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
0000128E 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
000012AB 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
000012C9 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
000012E8 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001305 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001324 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001343 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001362 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?
00001382 1 -- F0 Buffer: 16 Bytes System Exclusive 18 ?

They seem to be valid msg's as the all start " SYSX: F0 00 01 74 03 ......"
 
Regarding the sysex - can't answer cause I don't use any more than tuner/preset name and number.

Regarding extra tuning messages:

If your use a tuner on CC and then look for tuner sysex, it would be best to make a global binary variable that becomes true when tuner cc is turned on, then in the read sysex function, only display incoming tuner info if the tuner variable is true.

On the other hand, if you are passively listening to tuner messages and have your LCD display tuner whenever any tuner msg is read (I.e the tuner is engaged from front panel) then I would again suggest a second Boolean tuner variable that becomes true when tuning message is received without tuner on command. In this case, the program should measure the time difference between last tuning messages, and revert back to original LCD display state when the time from the last tuner message is > threshold time, and then set the second tuning variable to false.

Further, I like to keep all my LCD parameters stored into their own variables, so that I can redisplay them when leaving tuner mode without querying the afx for preset name and number.


Sent from my iPhone using Tapatalk
 
Whilst I'm on - anyone know if the Sysex function ID listing at MIDI SysEx - Axe-Fx II Wiki is fully comprehensive?

It's pretty much comprehensive for the purposes of creating a properly synced MIDI foot controller, perhaps with the exception of:

1. Not documenting that for message 0x14 (GET_PRESET_NUMBER) the reply is sent out as a packet whenever the AxeFx changes preset via the rotary, to let you know something's changed.
2. Message 0x21 sent out to indicate that effect block states have changed in some way and should be requeried (user has used FX bypass on the front panel)

What Axe Edit does on top of that, is a whole different ball-game, I don't think that the intention was to fully document that, and it might even be subject to change as part of ongoing product development.

I think Evz has covered the extra Tuner messages, but I will also refer back to my earlier comments on a main state machine covering the active mode of the foot controller (PRESET, FAV, TUNER, LOOPER) and dealing with everything on that basis - If the foot controller exits Tuner Mode, and, eg. goes back to PRESET mode, it would be implicitly ignoring Tuner sysex messages anyway, so there would be no issue.

That's absolutely not meant to be an "I told you so!" rather just to highlight a good example of how clean program design can easily accommodate this sort of "unexpected" behaviour.

As to why there appear to be extra tuner messages sent through after you send the exit tuner command, it's quite possible that the incoming midi processing of the Axe Fx is given lower priority when the tuner is active, as the tuner is using a lot of CPU to do it's thing. So it's taking a while for it to get around to turning it off. It wouldn't surprise me, though there may be another reason entirely.

Glad to see things are progressing !

Jon
 
On the note if the extra tuner messages - I have the same issue, its about 8 extra messages sent after the tuner off command is sent. As Jon states, it is on the Axe's end. On the foot controller end, I wouldn't suggest expecting 8 more messages after you send an off command - waiting for specific input can cause lots of troubles if you don't get what you expect! Thats why I suggested the two boolean operators to be used like a logic table.
 
On the note if the extra tuner messages - I have the same issue, its about 8 extra messages sent after the tuner off command is sent. As Jon states, it is on the Axe's end. On the foot controller end, I wouldn't suggest expecting 8 more messages after you send an off command - waiting for specific input can cause lots of troubles if you don't get what you expect! Thats why I suggested the two boolean operators to be used like a logic table.

Absolutely ! You should be completely ignoring them (as in, no-longer "actively" processing the tuner messages) as soon as the foot controller exits tuner mode, not expecting that you'll be sent an extra few, and waiting for them to finish coming. It's exactly the kind of thing that could change behaviour with a newer Axe firmware in the future.
 
it would be best to make a global binary variable that becomes true when tuner cc is turned on, then in the read sysex function, only display incoming tuner info if the tuner variable is true.

Genius - thanks!!

I'd actually already had a boolean variable "Tuner_Is_On" defined to detect whether the Tuner was on - but adding an OR to the IF statement in the HandleSysex function has done the trick.

Code:
void HandleSystemExclusive(byte *array, byte arraySize)
{
  
  if ((array[5] == 0x0D) && (Tuner_Is_On == true))   //if Tuner Sysex is read
 
Last edited:
That's absolutely not meant to be an "I told you so!"
Jon - sometimes I just need a big kick up the you know what so don't worry about driving a point home :) & as a Husband & Dad I see absolutely nothing wrong with the odd sprinking of a good old "Told you so".

Glad to see things are progressing !

They certainly are thanks to you fellas on here - so thanks once again - all.

Next stop - teh LOOPER
 
Jon - sometimes I just need a big kick up the you know what so don't worry about driving a point home :) & as a Husband & Dad I see absolutely nothing wrong with the odd sprinking of a good old "Told you so".

Tell me about it...wife and 2 daughters..I have to get the told you sos in when I can... :lol

bossredman said:
but adding an OR to the IF statement in the HandleSysex function has done the trick.

That "&&" is an "AND" not an "OR" (which is "||") - if you'd actually used an OR, it would have made it worse, not better ! Just sayin' ;)

But what you did is quite correct - just let those extraneous messages fall by the wayside as they arrive. You decide when you want to accept them.

Jon
 
That "&&" is an "AND" not an "OR" (which is "||")

Doh!!!

I was so excited at getting the thing working - I temporarily lost the ability to type what I was actually meaning.
I did indeed mean it to be AND.

Thanks for keeping me right Dad :lol
 
Hi,
Been running through my code trying tidy stuff up.
I got to the switch polling section which I recall Evz provided.
it looks for the pin to be
Code:
! = high
Sorry probably showing my ignorance, but why use 'not equal ' to high as opposed to just equal to low.
Are there more than 2 states (high & low)?
 
why use 'not equal ' to high as opposed to just equal to low.
Are there more than 2 states (high & low)?

It's a reasonable question !

Pin state is a boolean, so no, there are only 2 possible states, high and low. != HIGH and == LOW are equivalent, which one you use depends on how you conceptually view the problem you're trying to solve - it's like "glass is half empty" vs. "glass is half full"

Comparisons with zero, are probably the quickest operation a microprocessor can do, so that could favour the == LOW version, but for a boolean type, I'd be surprised if the C++ compiler wasn't optimising != HIGH anyway. You'd have to look at the generated assembly language to be sure.

Writing code is as much an art form as it is a science - you'll find there are often several ways to achieve the same thing, and everyone has their own personal style ! Programming languages exist to make it easier to express the problem you are trying to solve in ways that feel more natural to the implementor.

It's all good :)

Jon
 
Cheers Jon - I can only assume you are related to both Van Gogh & Einsein then.
<blushes> I'll take complements where they're offered, but really, I've just been lucky enough to hone my skillz pursuing a career, in something I loved as a slightly geeky kid in the 70s.

It's kind of weird thinking back to how I started on Z80s and 6502s programming assembler...and here we are discussing doing MIDI in C/C++ on an ARM micro !

Happy days !


Sent from my GT-I9505 using Tapatalk
 
So - the Looper?

Wondering the best way to approach this.
I know I have to have a Looper block in any preset I want to use it in (goes without saying I guess).

But what is folks' thoughts on the best way to have the Looper Block setup in each preset.
ie default always on or default bypassed.

Does the Looper suck tone or add gain - such that it may be best to have the block bypassed for general non-Looper usage.

Initially I've got its such that the Looper Block is Bypassed as default in the preset.
I've added a dedicated "Looper" switch, which:
- Enables the Looper Block (CC 33)
- Flips my "Scene - 1 to 4" switches to Looper functionality switches:
ie (Rec CC28, Play CC29, Overdub CC31, Undo CC121]).

This will probably change as I will probably want to change scenes & also Presets whilst in Looper mode - but for now was just looking to get it working in some form)

Anyone know what the MFC "Looper Control Mode" - physically does.
Is it just configuring the footswitches which can be used to perform the various functions of the Looper?
Or does it also physically enable/bypass the Looper block itself.
 
Sorry, I've never used the looper, and don't have an MFC anymore, so can't help here!
 
Last edited:
I have an MFC-101 but I've never really tried the looper out. I just tried it now, and it doesn't appear to activate the looper block if it isn't already active.

Hopefully someone who knows a bit more about it can chime in, but if you are stuck for info, I can put it through it's paces a bit more, but might be the weekend before I can sort it out !

Jon
 
Back
Top Bottom