FortySevenEffects / arduino_midi_library

MIDI for Arduino
MIT License
1.59k stars 257 forks source link

Ableton Live Overflows when sending MIDI through hairless MIDI #25

Closed rogervila closed 8 years ago

rogervila commented 10 years ago

Hello,

I'm creating my own MIDI Controller using the Arduino MIDI library. I succeed sending notes into Ableton Live, but I have some problems sending MIDI controls. I want to trigger a loop with a button but Ableton Live overflows and I have to close it. Maybe should I use another CC number? or another Arduino input? I selected cc 16 because it's for general purpose (i read it here: http://nickfever.com/402/production-tips-and-resources/midi-cc-list/)

Here is my code:

/*
* Roger Vilà - Midi  Controler Project
*/

#include <MIDI.h>

//Starting MIDI
MIDI_CREATE_DEFAULT_INSTANCE();

//VARIABLES

//the Led will shine while the button is pressed
int led = 13;

//button1 sends note, button2 sends Control Change
int button1 = 2;
int button2 = 4;

//last button state counter
int lastB1State = 0;
int lastB2State = 0; 

//curent button state counter
int currentB1State = 0;
int currentB2State = 0;

//Note 60 = C
int note = 60;

//Control 16 = general purpose 
int cc = 16;

//last control sent with B2
int lastControlSent = 0;

//Setup:
void setup(){

  //Start midi connection
  MIDI.begin();

  //Serial connection 115200 for Hairless MIDI
  Serial.begin(115200);

  //input button, output led
  pinMode(led, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
}

//Loop:
void loop(){

  //FIRST BUTTON WORKING PERFECT

  //BUTTON1 = B1 = piano key
  currentB1State = digitalRead(button1);

  if( currentB1State == 1 && lastB1State == 0){
    MIDI.sendNoteOn(note,127,1); 
    digitalWrite(led, HIGH);
  }  
  if (currentB1State == 0 && lastB1State == 1) {
    MIDI.sendNoteOff(note,0,1);
    digitalWrite(led, LOW);
  }

  lastB1State = currentB1State;

  /*
  currentB1State = digitalRead(button1);

  if( currentB1State == 1){

    if (lastB1State == 0) {
      MIDI.sendNoteOn(note,127,1);
      digitalWrite(led, HIGH);
    }

    lastB1State = 1;

  }else{

    if(currentB1State == 0){

      if (lastB1State == 1) {
        MIDI.sendNoteOff(note,0,1);
        digitalWrite(led, LOW);
      }

      lastB1State = 0;
    }
  }
  */
  //HERE I HAVE PROBLEMS

  //BUTTON2 = B2 = CC

  currentB2State = digitalRead(button2);

  if( currentB2State == 1 && lastB2State == 0){
    MIDI.sendControlChange(cc,127,1); 
    digitalWrite(led, HIGH);
  } 

  lastB2State = currentB2State;

  if( currentB2State == 0){
    digitalWrite(led, LOW);
  }
  /*
  currentB2State = digitalRead(button2);

  if( currentB2State == 1 && lastControlSent == 0){
    MIDI.sendControlChange(cc,127,1); 
    digitalWrite(led, HIGH);
    lastControlSent = 1;
    //100ms space
    delay(100);
  }

  if (currentB2State == 1 && lastControlSent == 1) {
    MIDI.sendControlChange(cc,0,1);
    digitalWrite(led, HIGH);
    lastControlSent = 0;
    //100ms space
    delay(100);
  }

  if( currentB2State == 0){
    digitalWrite(led, LOW);
  }
  */

  //50ms space
  delay(50);
}

Thank you very much.

franky47 commented 10 years ago

Sorry for the delay, I'm going to have a look.

franky47 commented 10 years ago

Ok, there are several issues there:

Here's an edited version, let me know if it works for you:

/*
* Roger Vilà - Midi  Controler Project
* Francois Best - Edited 19/09/2014
*/

#include <MIDI.h>

//Starting MIDI
MIDI_CREATE_DEFAULT_INSTANCE();

//VARIABLES --------------------------------------------------------------------

// The Led will shine while the button is pressed
static const int led = 13;

// Button1 sends note, button2 sends Control Change
static const int button1 = 2;
static const int button2 = 4;

// Last button state counter
int lastB1State = 0;
int lastB2State = 0;

// Curent button state counter
int currentB1State = 0;
int currentB2State = 0;

// Note 60 = C
static const int note = 60;

// Control 16 = general purpose
static const int cc = 16;

// -----------------------------------------------------------------------------

inline void readB1()
{
    //BUTTON1 = B1 = piano key
    currentB1State = digitalRead(button1);

    if (currentB1State != lastB1State)
    {
        // Take advantage of 0 velocity = note off.
        MIDI.sendNoteOn(note, currentB1State == LOW ? 0 : 127, 1);
        digitalWrite(led, currentB1State);
        lastB1State = currentB1State;
    }
}

inline void readB2()
{
    currentB2State = digitalRead(button2);
    if (currentB2State != lastB2State)
    {
        MIDI.sendControlChange(cc, currentB1State == LOW ? 0 : 127, 1);
        digitalWrite(led, currentB1State);
        lastB2State = currentB2State;
    }
}

// -----------------------------------------------------------------------------

void setup()
{
    MIDI.begin();
    Serial.begin(115200);

    pinMode(led, OUTPUT);
    pinMode(button1, INPUT);
    pinMode(button2, INPUT);

    // Initialize last button states with current pin values
    // (in case program starts with one button already pressed)
    lastB1State = digitalRead(button1);
    lastB2State = digitalRead(button2);
}

void loop()
{
    readB1();
    readB2();
    delay(50);
}
gretel commented 10 years ago

may i in addition suggest to use digitalIOPerformance - regards

gretel commented 9 years ago

or https://github.com/mmarchetti/DirectIO