Connecting arduino to a Multi effect guitar processor

Hello!
I'm working on build a footswitch MIDI controller for my NUX MG-30 (Guitar effect processor), it's a pretty simple circuit with 3 buttons, 3 leds and a potentiometer that will be controlling the expression pedal,

The code also it's very simple and it's based from this video https://www.youtube.com/watch?v=nh7J71ItDn8&t=9s

/////////////////////////////////////////////
// Choosing your board
// Define your board, choose:
// "ATMEGA328" if using ATmega328 - Uno, Mega, Nano...
// "ATMEGA32U4" if using with ATmega32U4 - Micro, Pro Micro, Leonardo...
// "TEENSY" if using a Teensy board
// "DEBUG" if you just want to debug the code in the serial monitor
// you don't need to comment or uncomment any MIDI library below after you define your board

#define TEENSY 1 //* put here the uC you are using, like in the lines above followed by "1", like "ATMEGA328 1", "DEBUG 1", etc.

/////////////////////////////////////////////
// LIBRARIES
// -- Defines the MIDI library -- //

// if using with ATmega328 - Uno, Mega, Nano...
#ifdef ATMEGA328
#include <MIDI.h> // by Francois Best
MIDI_CREATE_DEFAULT_INSTANCE();

// if using with ATmega32U4 - Micro, Pro Micro, Leonardo...
#elif ATMEGA32U4
#include "MIDIUSB.h"

#endif
// ---- //

/////////////////////////////////////////////
// BUTTONS
const int N_BUTTONS = 3; //*  total numbers of buttons
const int BUTTON_ARDUINO_PIN[N_BUTTONS] = {2, 3, 4}; //* pins of each button connected straight to the Arduino

int buttonCState[N_BUTTONS] = {};        // stores the button current value
int buttonPState[N_BUTTONS] = {};        // stores the button previous value

//#define pin13 1 //* uncomment if you are using pin 13 (pin with led), or comment the line if not using
//byte pin13index = 12; //* put the index of the pin 13 of the buttonPin[] array if you are using, if not, comment

// debounce
unsigned long lastDebounceTime[N_BUTTONS] = {0};  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    //* the debounce time; increase if the output flickers

/////////////////////////////////////////////
// POTENTIOMETERS
const int N_POTS = 1; //* total numbers of pots (slide & rotary)
const int POT_ARDUINO_PIN[N_POTS] = {A0}; //* pins of each pot connected straight to the Arduino

int potCState[N_POTS] = {0}; // Current state of the pot
int potPState[N_POTS] = {0}; // Previous state of the pot
int potVar = 0; // Difference between the current and previous state of the pot

int midiCState[N_POTS] = {0}; // Current state of the midi value
int midiPState[N_POTS] = {0}; // Previous state of the midi value

const int TIMEOUT = 300; //* Amount of time the potentiometer will be read after it exceeds the varThreshold
const int varThreshold = 10; //* Threshold for the potentiometer signal variation
boolean potMoving = true; // If the potentiometer is moving
unsigned long PTime[N_POTS] = {0}; // Previously stored time
unsigned long timer[N_POTS] = {0}; // Stores the time that has elapsed since the timer was reset

/////////////////////////////////////////////
// LEDS

const int N_LEDS = 3;
const int LED_ARDUINO_PIN[N_LEDS] = {8, 9, 10};

int ledCState[N_LEDS] = {0};        // stores the led current value
int ledPState[N_LEDS] = {0};        // stores the led previous value

/////////////////////////////////////////////
// MIDI
byte midiCh = 0; //* MIDI channel to be used
byte note = 36; //* Lowest note to be used
byte cc = 78; //* Lowest MIDI CC to be used

/////////////////////////////////////////////
// SETUP
void setup() {

  // Baud Rate
  // use if using with ATmega328 (uno, mega, nano...)
  // 31250 for MIDI class compliant | 115200 for Hairless MIDI
  //MIDI.begin(MIDI_CHANNEL_OMNI);
  Serial.begin(31250); 

#ifdef DEBUG
Serial.println("Debug mode");
Serial.println();
#endif

  // Buttons
  // Initialize buttons with pull up resistors
  for (int i = 0; i < N_BUTTONS; i++) {
    pinMode(BUTTON_ARDUINO_PIN[i], INPUT_PULLUP);
  }

#ifdef pin13 // initialize pin 13 as an input
pinMode(BUTTON_ARDUINO_PIN[pin13index], INPUT);
#endif

}

/////////////////////////////////////////////
// LOOP
void loop() {

  buttons();
  potentiometers();

}

/////////////////////////////////////////////
// BUTTONS
void buttons() {

  for (int i = 0; i < N_BUTTONS; i++) {

    buttonCState[i] = digitalRead(BUTTON_ARDUINO_PIN[i]);  // read pins from arduino

#ifdef pin13
if (i == pin13index) {
buttonCState[i] = !buttonCState[i]; // inverts the pin 13 because it has a pull down resistor instead of a pull up
}
#endif

    if ((millis() - lastDebounceTime[i]) > debounceDelay) {

      if (buttonPState[i] != buttonCState[i]) {
        lastDebounceTime[i] = millis();
        if (buttonCState[i] == LOW) {
          digitalWrite(LED_ARDUINO_PIN[i], HIGH);
          ledCState[i] = 1;
          for(int j = 0; j < N_LEDS; j++){
            if(i != j){
              digitalWrite(LED_ARDUINO_PIN[j], LOW);
              ledCState[j] = 0;
            }
          }
          // Sends the MIDI note ON accordingly to the chosen board
#ifdef ATMEGA328
// use if using with ATmega328 (uno, mega, nano...)
MIDI.sendControlChange(79, i, midiCh); // note, velocity, channel

#elif ATMEGA32U4
// use if using with ATmega32U4 (micro, pro micro, leonardo...)
controlChange(midiCh, 79, i); // channel, note, velocity
MidiUSB.flush();

#elif TEENSY
//do usbMIDI.sendNoteOn if using with Teensy
usbMIDI.sendControlChange(79, i, midiCh); // note, velocity, channel

#elif DEBUG
Serial.print(i);
Serial.println(": button on");
#endif

        }
        else {

          // Sends the MIDI note OFF accordingly to the chosen board
#ifdef ATMEGA328
// use if using with ATmega328 (uno, mega, nano...)
//MIDI.sendNoteOn(79, 0, midiCh + 1); // note, velocity, channel

#elif ATMEGA32U4
// use if using with ATmega32U4 (micro, pro micro, leonardo...)
//noteOn(midiCh, note + i, 0);  // channel, note, velocity
MidiUSB.flush();

#elif TEENSY
//do usbMIDI.sendNoteOn if using with Teensy
//usbMIDI.sendNoteOn(note + i, 0, midiCh); // note, velocity, channel

#elif DEBUG
Serial.print(i);
Serial.println(": button off");
#endif
        }
        buttonPState[i] = buttonCState[i];
        ledPState[i] = ledCState[i];
      }
    }
  }
}

/////////////////////////////////////////////
// POTENTIOMETERS
void potentiometers() {


  for (int i = 0; i < N_POTS; i++) { // Loops through all the potentiometers

    potCState[i] = analogRead(POT_ARDUINO_PIN[i]); // reads the pins from arduino

    midiCState[i] = map(potCState[i], 0, 1023, 0, 127); // Maps the reading of the potCState to a value usable in midi

    potVar = abs(potCState[i] - potPState[i]); // Calculates the absolute value between the difference between the current and previous state of the pot

    if (potVar > varThreshold) { // Opens the gate if the potentiometer variation is greater than the threshold
      PTime[i] = millis(); // Stores the previous time
    }

    timer[i] = millis() - PTime[i]; // Resets the timer 11000 - 11000 = 0ms

    if (timer[i] < TIMEOUT) { // If the timer is less than the maximum allowed time it means that the potentiometer is still moving
      potMoving = true;
    }
    else {
      potMoving = false;
    }

    if (potMoving == true) { // If the potentiometer is still moving, send the change control
      if (midiPState[i] != midiCState[i]) {

        // Sends the MIDI CC accordingly to the chosen board
#ifdef ATMEGA328
// use if using with ATmega328 (uno, mega, nano...)
MIDI.sendControlChange(78, midiCState[i], midiCh); // cc number, cc value, midi channel

#elif ATMEGA32U4
//use if using with ATmega32U4 (micro, pro micro, leonardo...)
controlChange(midiCh, 78, midiCState[i]); //  (channel, CC number,  CC value)
MidiUSB.flush();

#elif TEENSY
//do usbMIDI.sendControlChange if using with Teensy
usbMIDI.sendControlChange(78, midiCState[i], midiCh); // cc number, cc value, midi channel

#elif DEBUG
Serial.print("Pot: ");
Serial.print(i);
Serial.print(" ");
Serial.println(midiCState[i]);
//Serial.print("  ");
#endif

        potPState[i] = potCState[i]; // Stores the current reading of the potentiometer to compare with the next
        midiPState[i] = midiCState[i];
      }
    }
  }
}

/////////////////////////////////////////////
// if using with ATmega32U4 (micro, pro micro, leonardo...)
#ifdef ATMEGA32U4

// Arduino (pro)micro midi functions MIDIUSB Library
void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}
#endif

My problem is, it works pretty good when in connect the arduino and the pedal to the computer and send the MIDI with a software called PocketMIDI in windows

But once I try to connect arduino to the nux (it has USB type, so I'm using o OTG adaptator), it doens't seems to connect and send data

I'm kind of noob in arduino, i've built some things but nothing too complex, I've used Arduino UNO (Not the clone) with mocolufa, Arduino Leonardo And Teensy2.0 bootloader over Arduino Leonardo without success, And i'm not sure if i need the USB host shield or I'm missing something

thanks in Advance!
English is not my main language, if anything is not clear, I could explain again

You probably can't do that.

Did you mean it has a 'B' type ?

That's a Device. It has to be connected to a Host (eg, a PC); the Arduino is another Device - not a Host.

EDIT

Actually, it looks like a USB-C:
image

But it's still most likely a Device - so you won't be able to directly connect a UNO

Sorry, my error, I'm using a USB-type C adaptator...
So, the only way to connect this is through a PC, Is there another way? like the USB host shield?

There was an Arduino that can host USB.. like 10 years ago.
IIRC it was a Mega at heart.
Some other Frankenduinos might as well.

None of that sold well enough to keep making, I guess.

There are several now - mostly the ARM-based ones, I think.

Dunno about the UNO R4 ... ?

EDIT

So it can Host at least HID:

Not sure if that's all it can do - or if MIDI could be added...

2 Likes

You'll need some sort of USB Host - there's a number of Arduinos with native Host support nowadays.

You'd also have to find a library that supports whatever USB Class the pedal uses - presumably USB MIDI Class...

Uno Rev 4? I don't know the Nano past the original!

Yes! as I mention, the code or the library is not the problem because I can control my guitar pedal creating a bridge between Leonardo and the Nux, and I used Leonardo because it supports MIDI over USB Control Surface: MIDI over USB, but yeah, I think I need to find a way to have a USB host

I have used a Arduino Micro as a Midi-usb peripheral, this may work if you use a board that can operate as a USB peripheral, or get FTDI board to transmit midi over USB. I'm not sure if that port on the pedal would receive data from a USB peripheral device though

I very much doubt it - very much suspect it's just a Device itself.

@miguelrock222 is there anything in that pedal's documentation to suggest that it is (or can be) a USB Host?

Not really, the official documentations it's so poor in that aspect MG-30 - NUX, and some forums are quite in the same ways, too doubts NUX - MG-300 Midi implementation guide - Page 2

Instead of Midi, could could control the expression pedal using the exp. Jack

Yeah, that's another option, but solve the expression pedal, And I also want to control scenes and effects

The Teensy boards support USB Host:

1 Like

Hi! after a lot of testing and researching, finally i'm able to send midi to mi NUX MG-30 whitout connection with any computer or software

I used an Arduino UNO (CH340), USB Host Shield 2.0

I suggest to connect the nux to a software like pocket MIDI, to understand what are the exact midi codes because in the spreadsheet rounding in sites is not fully updated (for example it doesn't have midi fo change scenes)

this is an example to modify acording to your needs, this just change the scene of a patch each second

#include <UHS2-MIDI.h>
byte scene1[] = { 0x0B, 0xB0, 0x4F, 0x00 };
byte scene2[] = { 0x0B, 0xB0, 0x4F, 0x01 };
byte scene3[] = { 0x0B, 0xB0, 0x4F, 0x02 };

USB Usb;
UHS2MIDI_CREATE_DEFAULT_INSTANCE(&Usb);

unsigned long t0 = millis();
int step = 0;

void setup()
{
  Serial.begin(115200);
  while (!Serial);

  // Listen for MIDI messages on channel 1
  MIDI.begin(1);

  MIDI.setHandleSystemExclusive(OnMidiSysEx);
 
  if (Usb.Init() == -1) {
    while (1); //halt
  }//if (Usb.Init() == -1...
  delay( 200 );
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void loop()
{
  Usb.Task();
  // Listen to incoming notes
  MIDI.read();
  // send a note every second
  // (dont cáll delay(1000) as it will stall the pipeline)
  if ((millis() - t0) > 1000)
  {
    t0 = millis();
    if(step == 0){
      MIDI.sendSysEx(sizeof(scene1), scene1, true);
      Serial.println("scene 1");
      step = 1;
    }else if(step == 1){
      MIDI.sendSysEx(sizeof(scene2), scene2, true);
      Serial.println("scene 2");
      step = 2;
    }
    else if(step == 2){
      MIDI.sendSysEx(sizeof(scene3), scene3, true);
      Serial.println("scene 3");
      step = 0;
    }
  }

}

void OnMidiSysEx(byte* data, unsigned length) {
  Serial.print("SYSEX: (");
  Serial.print(length);
  Serial.print(" bytes) ");
  for (uint16_t i = 0; i < length; i++)
  {
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}
2 Likes

sorry mister, im newbie and i try to connect NUX mg300 to MIDI with Arduino Uno, can you give me the coding?, cause i try to copy the coding in this page its error
sorry for my bad english

This is the code, is not fully functional, i'm still working on it

but if it help...

#include <UHS2-MIDI.h>
#include <Arduino.h>

/////////////////////////////////////////////
// BUTTONS
const int N_BUTTONS = 3; //*  total numbers of buttons
const int BUTTON_ARDUINO_PIN[N_BUTTONS] = {2, 3, 4}; //* pins of each button connected straight to the Arduino

int buttonCState[N_BUTTONS] = {};        // stores the button current value
int buttonPState[N_BUTTONS] = {};        // stores the button previous value

// debounce
unsigned long lastDebounceTime[N_BUTTONS] = {0};  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    //* the debounce time; increase if the output flickers

/////////////////////////////////////////////
// POTENTIOMETERS
const int N_POTS = 1; //* total numbers of pots (slide & rotary)
const int POT_ARDUINO_PIN[N_POTS] = {A0}; //* pins of each pot connected straight to the Arduino

int potCState[N_POTS] = {0}; // Current state of the pot
int potPState[N_POTS] = {0}; // Previous state of the pot
int potVar = 0; // Difference between the current and previous state of the pot

int midiCState[N_POTS] = {0}; // Current state of the midi value
int midiPState[N_POTS] = {0}; // Previous state of the midi value

const int TIMEOUT = 300; //* Amount of time the potentiometer will be read after it exceeds the varThreshold
const int varThreshold = 10; //* Threshold for the potentiometer signal variation
boolean potMoving = true; // If the potentiometer is moving
unsigned long PTime[N_POTS] = {0}; // Previously stored time
unsigned long timer[N_POTS] = {0}; // Stores the time that has elapsed since the timer was reset

/////////////////////////////////////////////
// LEDS

const int N_LEDS = 3;
const int LED_ARDUINO_PIN[N_LEDS] = {8, 9, 10};

int ledCState[N_LEDS] = {0};        // stores the led current value
int ledPState[N_LEDS] = {0};        // stores the led previous value

//Sc 2 0B B0 4F 01 00 00 92 F5 DA D5 9E F3 26 BB 44 B2 A4 BB 7C DD DB F8 CD F3 9A 1F BE AB 0A 3D 0A 3C 03 30 01 0E 02 2F 0A DE 01 0E 01 03 38 03 38 00 00 03 A3 23 73 00 16 82 9F 56 FD B3 AF 3D 5B 7E
//Sc 3 0B B0 4F 02 00 00 92 F5 DA D5 9E F3 26 BB 44 B2 A4 BB 7C DD DB F8 CD F3 9A 1F BE AB 0A 3D 0A 3C 03 30 01 0E 02 2F 0A DE 01 0E 01 03 38 03 38 00 00 03 A3 23 73 00 16 82 9F 56 FD B3 AF 3D 5B 7E
//Sc 1 0B B0 4F 00 00 00 92 F5 DA D5 9E F3 26 BB 44 B2 A4 BB 7C DD DB F8 CD F3 9A 1F BE AB 0A 3D 0A 3C 03 30 01 0E 02 2F 0A DE 01 0E 01 03 38 03 38 00 00 03 A3 23 73 00 16 82 9F 56 FD B3 AF 3D 5B 7E

//EXP 
//0B B0 4E 60 00 00 92 F5 DA D5 9E F3 26 BB 44 B2 A4 BB 7C DD DB F8 CD F3 9A 1F BE AB 0A 3D 0A 3C 03 30 01 0E 02 2F 0A DE 01 0E 01 03 38 03 38 00 00 03 A3 23 73 00 16 82 9F 56 FD B3 AF 3D 5B 7E
//0B B0 4E 52 00 00 92 F5 DA D5 9E F3 26 BB 44 B2 A4 BB 7C DD DB F8 CD F3 9A 1F BE AB 0A 3D 0A 3C 03 30 01 0E 02 2F 0A DE 01 0E 01 03 38 03 38 00 00 03 A3 23 73 00 16 82 9F 56 FD B3 AF 3D 5B 7E
//          | 
/*byte sysex141[] = { 0x0C, 0xC0, 0x00 };
byte sysex142[] = { 0x0C, 0xC0, 0x01 };
byte sysex143[] = { 0x0C, 0xC0, 0x02 };*/
byte scene1[] = { 0x0B, 0xB0, 0x4F, 0x00 };
byte scene2[] = { 0x0B, 0xB0, 0x4F, 0x01 };
byte scene3[] = { 0x0B, 0xB0, 0x4F, 0x02 };


USB Usb;
UHS2MIDI_CREATE_DEFAULT_INSTANCE(&Usb);

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void setup()
{
  Serial.begin(115200);
  while (!Serial);

  // Listen for MIDI messages on channel 1
  MIDI.begin(1);

  MIDI.setHandleSystemExclusive(OnMidiSysEx);

  // Buttons
  // Initialize buttons with pull up resistors
  for (int i = 0; i < N_BUTTONS; i++) {
    pinMode(BUTTON_ARDUINO_PIN[i], INPUT_PULLUP);
  }

  // Leds
  // Initialize leds
  for (int i = 0; i < N_LEDS; i++) {
    pinMode(LED_ARDUINO_PIN[i], OUTPUT);
  }

  if (Usb.Init() == -1) {
    while (1); //halt
  }//if (Usb.Init() == -1...
  delay( 200 );
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void loop()
{

  Usb.Task();
  // Listen to incoming notes
  MIDI.read();

  buttons();
  //potentiometers();
}

/////////////////////////////////////////////
// BUTTONS
void buttons() {

  for (int i = 0; i < N_BUTTONS; i++) {
    buttonCState[i] = digitalRead(BUTTON_ARDUINO_PIN[i]);  // read pins from arduino

    if ((millis() - lastDebounceTime[i]) > debounceDelay) {
      if (buttonPState[i] != buttonCState[i]) {
        lastDebounceTime[i] = millis();
        if (buttonCState[i] == LOW) {
          Serial.print(i);
          digitalWrite(LED_ARDUINO_PIN[i], HIGH);
          ledCState[i] = 1;
          for(int j = 0; j < N_LEDS; j++){
            if(i != j){
              digitalWrite(LED_ARDUINO_PIN[j], LOW);
              ledCState[j] = 0;
            }
          }
          //send
          switch(i){
            case 0:
              MIDI.sendSysEx(sizeof(scene1), scene1, true);
              break;
            case 1:
              MIDI.sendSysEx(sizeof(scene2), scene2, true);
              break;
            case 2:
              MIDI.sendSysEx(sizeof(scene3), scene3, true);
          }

        }
        buttonPState[i] = buttonCState[i];
        ledPState[i] = ledCState[i];
      }
    }
  }
}


// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void OnMidiSysEx(byte* data, unsigned length) {
  Serial.print("SYSEX: (");
  Serial.print(length);
  Serial.print(" bytes) ");
  for (uint16_t i = 0; i < length; i++)
  {
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.println();
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.