Midi controller

Hi everyone.

Beginner here.

I have an Arduino uno and have build 4 buttons in a chassi.

Long story short...
I want to press button 1

  • LED 1 lights up
  • midi "program 1" is sent to midi device.

press button 2

  • LED 1 turns off
  • LED 2 lights up
  • midi "program 2" is sent to midi device.

.... and so forth.

Midi out (via 5v and 220ohm, ground and tx is connected.

Does anyone have the time to help me with this... tried some stuff and I can get the LEDs to work but not the midi...

Thanks

Rob "rocker"

tried some stuff and I can get the LEDs to work but not the midi...

Posting your code was apparently not one of the things you tried. Read the stickies at the top of the forum first, so you post your code properly.

A schematic or wiring diagram will be helpful as well.

For the midi i have tried this (which I found on Arduinos playground)
I modified to Serial.Write

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


// midi.controller
// Originally written by The Cat Herder
// Sends midi program change and control change messages based on foot pedal pressed

// Constants
#define SWITCH1 2
#define SWITCH2 3
#define SWITCH3 4
#define SWITCH4 5
#define SWITCH5 6
#define LED1 7
#define LED2 8
#define LED3 9
#define LED4 10
#define LED5 11
#define BOUNCEDELAY 25

// Variables:
int switches[5] = { SWITCH1, SWITCH2, SWITCH3, SWITCH4, SWITCH5 };
int switchState[5] = { HIGH, HIGH, HIGH, HIGH, HIGH };
// Initial state of switch is high due to internal pullup
int leds[5] = { LED1, LED2, LED3, LED4, LED5 };
int currentSwitch = 0;
int currentProgram = 22;   // current program - sent to the output
int bypassState = LOW;     // state of bypass pedal
int pedalActiveFlash = 50; // Delay for flash when pedal is pressed

void setup() {
  //  Set MIDI baud rate:
  Serial.begin(31250);

  // Setup Switches and activation LEDs
  for ( currentSwitch = 0; currentSwitch < 5; currentSwitch++ ) {
    pinMode( switches[currentSwitch], INPUT );          // Set pin for switch
    digitalWrite( switches[currentSwitch], HIGH );      // Turn on internal pullup
    pinMode( leds[currentSwitch], OUTPUT );             // Set pin for LED
    flashPin( leds[currentSwitch], 100 ); // Flash LED
  }
}

void loop() {
  for ( currentSwitch = 0; currentSwitch < 5; currentSwitch++ ) {
    if ((digitalRead(switches[currentSwitch]) != switchState[currentSwitch] ) && (switchState[currentSwitch] == HIGH)) {
      switch ( currentSwitch ) {
 //       case 0:
          //Bypass
          if ( bypassState == LOW ) {
            bypassState = HIGH;
            midiSend( 0xB0, 0x5B, 0x00 ); // bypass off
            digitalWrite( leds[currentSwitch], LOW );
          }
          else {
            bypassState = LOW;
            midiSend( 0xB0, 0x5B, 0x7F ); // bypass on
            digitalWrite( leds[currentSwitch], HIGH );
          }
          break;
 //       case 1:
          //Prev Program
          currentProgram = currentProgram--;
          if ( currentProgram < 1 )
            currentProgram = 0; // Don't go lower than 0
          midiProg( 0xC0, currentProgram );
          flashPin( leds[currentSwitch], pedalActiveFlash );
          break;
        case 2:
          // Next Program
          currentProgram = currentProgram++;
          if ( currentProgram > 96 )
            currentProgram = 97; // Don't go lower than 97
          midiProg( 0xC0, currentProgram );
          flashPin( leds[currentSwitch], pedalActiveFlash );
          break;
        case 3:
          // Favourite 1
          currentProgram = 01;
          midiProg( 0xC0, currentProgram );
          flashPin( leds[currentSwitch], pedalActiveFlash );
          break;
        case 4:
          // Favourite 2
          currentProgram = 02;
          midiProg( 0xC0,  currentProgram );
          flashPin( leds[currentSwitch], pedalActiveFlash );
          break;
      }
      delay( BOUNCEDELAY );
    }
    switchState[currentSwitch] = digitalRead( switches[currentSwitch] );
  }
}

//  Send a three byte midi message
void midiSend(char status, char data1, char data2) {
  Serial.write(status);
  Serial.write(data1);
  Serial.write(data2);
}

//  Send a two byte midi message
void midiProg(char status, int data ) {
  Serial.write (status);
  Serial.write (data);
}

void flashPin( int ledPin, int flashDelay ) {
  digitalWrite( ledPin, HIGH );
  delay( flashDelay );
  digitalWrite( ledPin, LOW );
}
  for ( currentSwitch = 0; currentSwitch < 5; currentSwitch++ ) {
    pinMode( switches[currentSwitch], INPUT );          // Set pin for switch
    digitalWrite( switches[currentSwitch], HIGH );      // Turn on internal pullup
    pinMode( leds[currentSwitch], OUTPUT );             // Set pin for LED
    flashPin( leds[currentSwitch], 100 ); // Flash LED
  }

currentSwitch looks like a pretty sill name when it means the index into an array of pins that LEDs are attached to. Loop variables usually have short names, like i.

void flashPin( int ledPin, int flashDelay ) {
  digitalWrite( ledPin, HIGH );
  delay( flashDelay );
  digitalWrite( ledPin, LOW );
}

Turn the pin on. Wait a while. Turn the pin off. Immediately, do that again.

Your LEDs aren’t flashing, are they?

  for ( currentSwitch = 0; currentSwitch < 5; currentSwitch++ ) {
    if ((digitalRead(switches[currentSwitch]) != switchState[currentSwitch] ) && (switchState[currentSwitch] == HIGH)) {
      switch ( currentSwitch ) {

A for loop that does something different every iteration is pointless. Sometimes you just have to repeat code.

Regardless, the code you posted does something. You expect it to something. All we know now is that the two somethings aren’t the same thing.

Thank you for the reply.

The LEDs aren't flashing other than when I close the circuit.

This is the closest thing I have found to what I need to do but like you said.... it doesn't do what I want.

I really understand if you don't want to bother with this but i can't figure out how to get a digital closed to ground to send serial info (midi) and get that corresponding LED to light up... stay lit until I press another switch....

I have a history programming Crestron and AMX but have really forgotten alla about it....

The LEDs aren't flashing other than when I close the circuit.

Is that what you want? If so, flashLED() is a pretty dumb name for the turnThePinOnRepeatedly() function.

This is the closest thing I have found to what I need to do but like you said.... it doesn't do what I want.

Still nothing about what it actually does or what you expect it to do...

I really understand if you don't want to bother with this

So, when I quit replying because you don't answer my questions, you'll be fine with that. Good.

i can't figure out how to get a digital closed to ground to send serial info

What does "digital closed to ground" mean?

I suspect that you need to shitcan 90% of that code. Turn an LED on when a switch is pressed. Turn it off when the switch is released. If that doesn't work, your switch or your LED is wired incorrectly.

Then, you can expand that working sketch to turn the LED on when the switch BECOMES pressed once, and off when it becomes pressed again.

That way, you'll learn about how to do things at state changes.

Next, you can make the Arduino send serial data when the switch becomes pressed and when it becomes released. Learn about serial communication that way.

Then, you can add all the MIDI crap in.

Right now, it seems like you are trying to build a house without a clue as to how, doing the foundation and the walls and the wiring and the plumbing all at the same time, and not understanding why the toilet flushes when you open the garage door.

I think you’re not sending correct MIDI codes.

You define the arguments to midiSend() as type char, which is a signed type. They should be type byte, which is unsigned.

Paul,

I asked for help. That doesn’t mean you copying rows of code and then telling me it’s wrong.
I know it’s wrong. I already wrote that this was the closest thing I could find.

I don’t know you and you don’t know who I am and that’s cool. I try to keep things civil.
I can tell that you have skills in programming. I do not.
Ambition my friend, I have loads.

This code is for just the LEDs that I’m trying to incorporate MIDI commands to.
This is also based on something I find but I can understand this more (but not fully)

//Number of LEDs
const int numberLeds=4;
//Pins for each LED
int led[numberLeds] = {6,7,8,9};
//State of each LED
int ledState[numberLeds];



//Number of buttons
const int numberButtons=4;

//Set the pins used for each button
int button[numberButtons] = {2,3,4,5};

//Start state of the LEDs off (HIGH=off when INPUT_PULLUP used)
//No need for pullup/down resistors
int lastButtonState[numberButtons];

//Bools used for when buttons currently pressed (used for long press detection)
bool buttonActive[numberButtons];

//Debounce timer for each button
unsigned long lastDebounceTime[numberButtons];


//Set the debounce delay
int debounceDelay=25;


void setup() {
  // setup code, to run once:
  buttonSetup();
  ledSetup();

}

void loop() {
  
  //Loop through each button and get the state
  //0=not pressed
  //1=short press

  for (int x=0; x<numberButtons; x++)
  {
    int state=buttonHandler(x);

    if ( state== 1)
    {
      ledState[x]=!ledState[x];
      digitalWrite(led[x], ledState[x]);
    }

    if (state == 2)
    {
      ledState[2]=!ledState[2];
      digitalWrite(led[2], ledState[2]);
    }
  }
}

int buttonHandler(int number)
{
  //Handle presses for each button
  int reading = digitalRead(button[number]);

  //Check if button state has changed since last check
  if (reading != lastButtonState[number])
  {
    if (reading==HIGH && !buttonActive[number])
    {
      lastButtonState[number] = reading;
      
      //Return 0 (not pressed)
      return 0;
    }
    
    //if reading is high (open)
    if (reading==HIGH && buttonActive[number])
    {
      if (millis() - lastDebounceTime[number] > debounceDelay)
      {
        lastButtonState[number] = reading;

        buttonActive[number]=true;

        //Return 1 (short press)
        return 1;
      }

      lastButtonState[number] = reading;

      buttonActive[number]=false;
      
      //Return 0 (not pressed)
      return 0;
    }
    
    //if reading is low (closed)
    else if (reading==LOW)
    {
      if (!buttonActive[number])
      {
        //Start debounce timer
        lastDebounceTime[number]=millis();
        
        lastButtonState[number] = reading;

        buttonActive[number]=true;

        //Return 0 (not pressed)
        return 0;
      }
      //Return 0 (not pressed)
      return 0;
    }
  }

  //Check if reading still high (open)
  if (reading==HIGH)
  {
    lastButtonState[number] = reading;
    buttonActive[number]=false;

    //Return 0 (not pressed)
    return 0;
  }

  
  }

void ledSetup()
{
  for (int x=0; x<numberLeds; x++)
  {
    pinMode(led[x], OUTPUT);
    ledState[x]=LOW;
  }
}

void buttonSetup()
{
  for (int x=0; x<numberButtons; x++)
  {
    lastButtonState[x]=HIGH;
    buttonActive[x]=false;
    lastDebounceTime[x]=0;
   // buttonState[x]=HIGH;
    pinMode(button[x], INPUT_PULLUP);
    
  }
}

Thanks Blue Eyes,

i suspected that.

Any tips for how i could send the codes in a simple way?
I think that the codes are:

ch1: 0xC0
ch2: 0xC1
ch3: 0xC2
ch4: 0xC3

It should be OMNI as well: 0x7D
Serial Baud 31250

Thanks a lot!

My advice is to simplify. Try just playing MIDI notes, once that is working you can add the switch code. I pulled some code from a sketch to use as a starting point. It changes the program randomly and plays a note every few seconds on a given channel.

It works with my MIDI module connected to an Arduino, see if this works with your hardware.

/*
  MIDI test
  
*/

const byte midiChannel = 1;    // channel to play midi data

byte noteON = (byte)(0x90 + (midiChannel-1)); //note on command

byte noteToPlay = 60;  // only playing one note

void setup() {
  Serial.begin(31250);   
}

void loop() {

    // change program
    midiProgram(random(0,127), midiChannel);
    
    byte velocity =  60;

    // play note
    MIDImessage(noteON, noteToPlay, velocity);

    delay(3000); // Wait  between notes

}

//send MIDI message
void MIDImessage(byte command, byte data1, byte data2) {
  Serial.write(command);
  Serial.write(data1);
  Serial.write(data2);
}

// send program change message
void midiProgram(byte prog, byte chan)
{
   Serial.write((byte)(0xc0 + (chan-1)));
   Serial.write(prog); 
}

Thanx!

My device is a Guitar processor so it won't play midi notes but maybe I can see if I can get it to respond.

Exciting. :slight_smile: