Midi Controller with Uno R3

Hi everyone !

I'm new in this big community and i need a little help for my project.

I'm using Arduino Uno R3 as a midi controller for Ableton Live 11 and something doesn't work :sunny:

So I'm using Hairless midi serial and loop midi for the connection between arduino and ableton and my sensors are 1 light grove and 1 infrared (+ some buttons who are working).
The thing is hairlessmidi doesn't recognise the data from the sensors.

The sensors are on the pin A0 and A5 nothing more. I put the code here :

// LIBRARIES

#include <MIDI.h> // by Francois Best
MIDI_CREATE_DEFAULT_INSTANCE(); 


// BUTTONS
const int NButtons = 1; //  total number of push buttons
const int buttonPin[NButtons] = {2}; 
                                   
int buttonCState[NButtons] = {};        // stores the button current value
int buttonPState[NButtons] = {};        // stores the button previous value
//int previousstate = 0;


// 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 = 2; //*** total numbers of pots
const int potPin[NPots] = {A4, A1}; 

                                          // have 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
byte midiCh = 1; //** MIDI channel to be used; You can add more if you need to reorganize or have a billion buttons/pots
byte note = 36; //** First note to be used for digital buttons, then go up chromatically in scale according to the sequence in your "buttonPin" array
                // you can look up on a Midi Note chart; 36=C2; 60=Middle C
byte cc = 1; //** First MIDI CC to be used for pots on Analog Pins in order of the "potPin" array; then goes up by 1

// SETUP
void setup() { 

  Serial.begin(115200); //**  Baud Rate 31250 for MIDI class compliant jack | 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) {

          //if(previousstate = 0){

            // Sends the MIDI note ON accordingly to the chosen board
            MIDI.sendNoteOn(note + i, 127, midiCh + i); // note, velocity, channel
            //MIDI.sendControlChange(cc + i, 127, midiCh + i);
            //previousstate = 1;

          //}
          //else{

            //MIDI.sendControlChange(cc + i, 0, midiCh + i);
            //MIDI.sendNoteOn(note + i, 0, midiCh + i); // note, velocity, channel
            //previousstate = 0;

          //}

        }
        else {

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

          MIDI.sendNoteOn(note + i, 0, midiCh + i); // note, velocity, channel

        }
        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

  if (i=0){

      midiCState[i] = map(potCState[i], 0, 814, 0, 127); // Maps the reading of the potCState to a value usable in midi
        Serial.println(analogRead(potPin[i]));
    }
    
    if (i=1){

      midiCState[i] = map(potCState[i], 40, 700, 0, 127); // Maps the reading of the potCState to a value usable in midi
      //Serial.println(analogRead(potPin[i]));

    }
    //midiCState[i] = map(potCState[i], 0, 700, 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 
        MIDI.sendControlChange(cc + i, midiCState[i], midiCh + i); // cc number, cc value, midi channel
        //MIDI.sendNoteOn(note + i, 127, midiCh + i);  

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

  }
}

That doesn't look alright.

Single = is assignment, you want == to check for equality.

You cannot use Serial.println() while using the MIDI library on the same serial port.

I use this "Serial.println()" only to check if i can read the data of the sensor here and that's was working.
Is there something special to know about hairless or loopmidi ?
Hairless close when i want to start the connexion...

Hairless is very old and hasn't been updated since 2014. It no longer runs on Macs past Os 10.14, and I don't know about PCs but I suppose it depends on what OS you are running.

Hi! I'd like to build a midi device using arduino, are there modern/updated alternatives for non-usb based boards such as Uno, or MEGA? thanks :smiley:

Since I last posted I have found a replacement for Hairless that will work.

I have tested it on a Mac, I do not have Windows. However one user has got it to work with windows.

serial MIDI bridge on windows

See the other posts in this thread for information about installing Python.

1 Like

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