Pro Mico MidiUSB + DIN out

Hello, I just made my first Arduino project. A simple 9 button, 5 potmeter midi controller.
It works perfect via USB.
However, I need to connect it via a DIN-plug to my lighting desk.

What do I need to add to the code so I can connect a Midi - out on DIN?

here's the code so far...

/*
  Based on Sketch built by Gustavo Silveira (aka Music Nerd)
  Modified by Dolce Wang

  This code is only for Arduinos that use ATmega32u4 (like Micro, Pro Micro, Leonardo...)
  Remember to also assign the correct board in the IDE (like Tools / Boards / Sparkfun AVR / Pro Micro...)

*/

// Change any fields with //**


// LIBRARY

#include "MIDIUSB.h"  

// BUTTONS
const int NButtons = 9; //***  total number of buttons
const int buttonPin[NButtons] = {2, 3, 4, 5, 6, 7, 8, 15, 16}; //*** define Digital Pins connected from Buttons to Arduino; (ie {10, 16, 14, 15, 6, 7, 8, 9, 2, 3, 4, 5}; 12 buttons)
                                            
int buttonCState[NButtons] = {};        // stores the button current value
int buttonPState[NButtons] = {};        // stores the button previous value

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


// POTENTIOMETERS
const int NPots = 5; //*** total number of pots (knobs and faders)
const int potPin[NPots] = {A3, A2, A1, A0, A10}; //*** define Analog Pins connected from Pots to Arduino; Leave nothing in the array if 0 pots {}
int potCState[NPots] = {0}; // Current state of the pot; delete 0 if 0 pots
int potPState[NPots] = {0}; // Previous state of the pot; delete 0 if 0 pots
int potVar = 0; // Difference between the current and previous state of the pot

int midiCState[NPots] = {0}; // Current state of the midi value; delete 0 if 0 pots
int midiPState[NPots] = {0}; // Previous state of the midi value; delete 0 if 0 pots

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[NPots] = {0}; // Previously stored time; delete 0 if 0 pots
unsigned long timer[NPots] = {0}; // Stores the time that has elapsed since the timer was reset; delete 0 if 0 pots


// MIDI Assignments 
byte midiCh = 1; //* MIDI channel to be used
byte note = 36; //* Lowest note to be used; 36 = C2; 60 = Middle C
byte cc = 1; //* Lowest MIDI CC to be used


// SETUP
void setup() {

  // Baud Rate
  // 31250 for MIDI class compliant | 115200 for Hairless MIDI

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

}

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

  buttons();
  potentiometers();

}

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

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

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

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

      if (buttonPState[i] != buttonCState[i]) {
        lastDebounceTime[i] = millis();

        if (buttonCState[i] == LOW) {

          // Sends the MIDI note ON 
          
         // use if using with ATmega32U4 (micro, pro micro, leonardo...)
          noteOn(midiCh, note + i, 127);  // channel, note, velocity
          MidiUSB.flush();


        }
        else {

          // Sends the MIDI note OFF accordingly to the chosen board

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

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

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


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

    potCState[i] = analogRead(potPin[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  MIDI CC 
        // Use if using with ATmega32U4 (micro, pro micro, leonardo...)
        controlChange(midiCh, cc + i, midiCState[i]); //  (channel, CC number,  CC value)
        MidiUSB.flush();

        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...)


// Arduino 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);
}

Show a diagram of what it is you are trying to do.
Include parts used and power supplies.

You need to add

#include #include <MIDI.h>

MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);

in setup()

MIDI.begin(MIDI_CHANNEL_OMNI);

and for every function add like this for noteON()

void noteOn(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOn);
  MIDI.send(0x90,  pitch, velocity, channel);
}

Look at the examples in the MIDI.h library for more information.

Is that diagram showing what you actually have?

That is the link on the lower left corner in unsoldered. That means you board is only running at 3V3 and so will not be able to drive a DIN socket.

Short that link for a 5V system.

I also have it unsoldered on my Pro-Micro board, Vcc is at 4.56v when USB is connected, Pretty sure the board is running at the same voltage as Vcc. 4.56v should be enough to power a Din socket.

@sevrien Your schematic is wrong. You need two 220Ohm resistors.
TX must be connected via the resistor to pin5, and +5V must be connected via the resistor to pin 4.
Gnd is connected to pin 3 2.
[Edit] Sorry, I didn't see the resistors at my small screen :roll_eyes:. In the end you only interchanged pin 2 and 4-

And the sketch must be changed as @Deva_Rishi pointed out in #4

Oh yeah i hadn't actually looked at that. Yes 2x 220R resistors, but those are there, couldn't read them at first but clicking on the picture (which is not a schematic !!) enlarges and clarifies it. But yes the pins are incorrectly connected. Also since the plug is not specified with it's view, chances are it may be inverted.

Pin Nrs for DIN plugs are not consistently specified, so let me add my reminding schematic


The extra Schitt-trigger double inverter is optional for direct Midi out. A true digital signal doesn't need it that close to the Source, but for a Midi -thru it isn't optional.

If the supply voltage really end up at 4.5V you could consider reducing the values of the 2 resistors a little.
Now 3x 220R in the circuit on 5v - Opto-Led voltage drop, at 4.5v you may be better off with 2x 180R, but those resistors are there to protect the circuit from accidental short circuits, make sure that you do not exceed GPIO current in case of a short (should be OK on a Micro though, 4.5 / 180 = 0.025A = 25mA

Look at the schematic of the Micro you have and reconsider that statement please.

Look i am just telling youmine is not soldered, i got the multimeter out and measured the voltage between Vcc & GND, what does the schematic have to do with that. Oh ! it can't be according to the schematic ? Maybe, but it is like that though. It's a pro-micro i bought and that is what i found. My statement is the truth, i can reconsider that.

Good luck with any future help........ :zipper_mouth_face:

What does that even mean ? I measured it, if that does not compute with the schematic, then obviously there are boards out there which are made with a different schematic. I can not reconsider what i found, But seriously i was not replying to your question, nor was i asking for help, so get of my cloud.

Guys,

Please, it's Christmas!

I'll check your suggestions when I have the time and keep you informed.

1 Like

You need to measure the voltage between ground and an output pin set HIGH. I think you will find that this only 3V3. What exactly is the Vcc pin you are measuring?

The link shorts out the voltage regulator allowing the processor to run at 5V.

Keep it civil please folks!

1 Like

Sorry i just really felt offended. I measure something i can not just reconsider that, and then to be told 'Good luck with future help.."

Anyway.

Well i am of course willing to do that, but again, The result is 4.48v


Still at 4.56v

Why would it run at 3.3v , Isn't it equipped with a 16MHz resonator ?

That it probably still does, but instead of 4.5v i guess.

I think the confusion is here in the schematic
Screenshot (157)
Of course on most clone boards the markings are not filled, but the resonator does have some writing and mine says 16.000 MHz. The 5v USB power does go through the 5v regulator dropping it to 4.55v Still just above the 4.5v threshold for 16MHz.

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