I use ableton live for my solo ambient projects, but my new combo Mithril are 2 vocals and myself on acoustic, so I wanted a simple, practical looper option. I had previously used a line 6 M13 (too big/limited) and an M9 (which I broke while trying to replace the micro-switches!). Finally, I persuaded myself (and my wife) that a Line 6 HX effects would fit the bill. After shopping around, I found one at £358, well below the typical street price, so I bought one.

The pedal is quite amazing and really well thought through in terms of usability. Plus, it has midi control, which I’ve used to overcome the main limitation of a one-pedal looper, that of stopping by double click. It may be my age, but when I’m recording a live loop, I find double tapping throws my timing out. Or at least, I feel it does! Since I’m getting handy at building midi projects using the arduino chip, I built myself a small pedal to plug into the HX midi in socket.

Whilst I could assign any looper controls to a pedal (except, infuriatingly, a “clear loop” command), I kept it basic, with a pedal for “stop” and another for “play”. I added LEDs (colour matched to the pedal light!) and it works faultlessly. It’s powered via USB, so needs suitable power socket handy.

I then extended the code to that switching “play” on also switched FS3 on, set to add a little dirt for solos. Pressing stop switches off both the loop and the boost.

Here’s a fritzing of the layout

and here’s the arduino code, for those in the know 😉


// midi controller for line 6 M9 to control looper - solo OD
// apr 19

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

MIDI_CREATE_DEFAULT_INSTANCE();
// Constants
#define SWITCH1 3 // play
#define SWITCH2 2 // stop
#define SWITCHES 2    // how many switches?
# define LED1 5 // channel 1
# define LED2 4 // channel 2
int thisLed = 0;

int switches[SWITCHES] = { SWITCH1, SWITCH2 };
int switchState[SWITCHES] = { LOW, LOW };   // Initial state of switch
int leds[SWITCHES] = { LED1, LED2 };
int currentSwitch = 0;
int play = 0; // state or recording
unsigned long SwitchMillis = 0; // when button was released
unsigned long DebounceMillis = 20; //
unsigned long CurrentMillis = 0;

void setup()
{
  MIDI.begin(1);
  // Setup Switches and activation LEDs
  for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
  {
    pinMode( switches[currentSwitch], INPUT );          // Set pin for switch
    digitalWrite( switches[currentSwitch], HIGH );      // Turn on internal pullup
    pinMode( leds[currentSwitch], OUTPUT );
    digitalWrite( leds[currentSwitch], HIGH );
  }
  intro();
}

void loop()
{
  CurrentMillis = millis();  // get the time at the start of this loop()
  if (CurrentMillis - SwitchMillis >= DebounceMillis)  //is it time to check the switches?
  {
    SwitchMillis = millis(); //re-initilize Timer
    for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
    {
      if ( (digitalRead(switches[currentSwitch]) != switchState[currentSwitch] ) && (switchState[currentSwitch] == HIGH) )
      {
        switch ( currentSwitch )
        {
          case 0: //  play
            {
              MIDI.sendControlChange(61, 127, 1); // play
              delay(200); // slow down commands so the HX doesn't crash!
              MIDI.sendControlChange(51, 127, 1); // FS3
              digitalWrite( leds[0], HIGH );
              digitalWrite( leds[1], LOW );
              play = 1;
            }
            break;
          case 1:  // stop
            {
              MIDI.sendControlChange(61, 0, 1); // stop
              if (play)
              {
              delay(200); // slow down commands so the HX doesn't crash!
              MIDI.sendControlChange(51, 127, 1); // FS3
              play = 0;
              }
              digitalWrite( leds[1], HIGH );
              digitalWrite( leds[0], LOW );
            }
            break;
        }
      } // end if changed
      switchState[currentSwitch] = digitalRead( switches[currentSwitch] );
    } // go thru switches
  } // end check switches
} // end loop

void intro () // startup flashes
{
  for ( int i = 0; i < 6; i++ ) // startup flashes
  {
    for ( thisLed = 0; thisLed < SWITCHES; thisLed++ )
    {
      digitalWrite( leds[thisLed], LOW );
      delay(160);
      digitalWrite( leds[thisLed], HIGH );
    }
  }
}