MIDIFOX

midifoxdomi.jpg

4x4 arcade button MIDI controller with 4 channels

To-DO

  • digitalize schematic from notebook ✅ 2024-09-11
  • redoo code, add math to the datatypes, bit operators ✅ 2024-09-11

Code for the Arduino Nano

/* Nuvhandra
 * 2017
 *
 * MIDI Controller
 * This version uses a multiplexer and normal digital inputs are used from 5 to 13
 * 
 * Version 3:
 * 4 analog inputs used as 'page' buttons
 */

#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

//pin number 13 will be an extra button, but it must be connected differently with a resistor
//pin 13 is reversed
const int ledpin=13;
int b = 0;
const int v=5;//where the digital pins start, in this case is 5 because control pins take 2,3 and 4
const int numBut=8;//max number 8, digital pins, left one for multiplexer, counting led pin
const int numAn=3;//number of potentiometers
//const int anf=8;
const int numMuxBut=8;//number of button connected to multiplexer
const int muxpin=10;//Which pin is connected to the multipexer
/*byte nx=144;
byte vel=127;*/
byte cc=0;
int actualpin;
int channel=1;
int actual[numBut];
int before[numBut];
int actualAn[numAn];
int beforeAn[numAn];
int actualMux[numMuxBut];
int beforeMux[numMuxBut];

int thre = 800;
int val;

//multiplexer control pins
const int s0 = 2;
const int s1 = 3;
const int s2 = 4;

const int select[] = {s0,s1,s2};

//Adding pages to the analog pins, this buttons(analog) changes the CC note in the 4x4 buttons
//by default is on page 1
const int pgOne=48;
const int pgTwo=pgOne+18;
const int pgThree=pgTwo+18;
const int pgFour=pgThree+18;

const int pgs

int actualPage;

void setup(){
  MIDI.begin();
  //Serial.begin(9600);
  Serial.begin(115200);
	//MIDI.begin(MIDI_CHANNEL_OMNI); //it listen to all incomming message

  pinMode(ledpin,INPUT);
 
  for(int i=0;i<numBut;i++){
    actualpin=i+v;
    pinMode(actualpin,INPUT_PULLUP);
	  before[i]=1; //set 1 as button is not pressed
	}

  //set analog inputs as false
  for(int i=0;i<numAn;i++){
    actualAn[i]=0;
    beforeAn[i]=0;
  }

  //setting default page one
  actualPage=pgOne;
 
	//Adding multiplexer
	//control pins from multiplexer as outputs
	pinMode(s0,OUTPUT);
	pinMode(s1,OUTPUT);
	pinMode(s2,OUTPUT);
}

void loop(){
  //Serial.println(analogRead(0));
	if(numBut!=0){updateDigitalBut();}
  if(numAn!=0){updateAnalog();}
	if(numMuxBut!=0){updateDigitalMuxBut();}
  //Ledpin input
  int ledNote=0;
  int vi = digitalRead(ledpin);
  if(actualPage==pgOne){
    ledNote=56;
  }else if(actualPage==pgTwo){
    ledNote=74;
  }else if(actualPage==pgThree){
    ledNote=92;
  }else if(actualPage==pgFour){
    ledNote=110;
  }
  if(vi==1 && vi!=b){
    MIDI.sendNoteOn(ledNote,127,channel);
  }else if(vi==0 && vi!=b){
    MIDI.sendNoteOff(ledNote,127,channel);
    /*MIDI.sendNoteOff(56,127,channel);
    MIDI.sendNoteOff(74,127,channel);
    MIDI.sendNoteOff(92,127,channel);
    MIDI.sendNoteOff(110,127,channel);*/
  }
  b=vi;
	//MIDI.read();  
}

void updateDigitalBut(){
	for(int i=0;i<numBut;i++){
		actualpin = i+v;
		actual[i]=digitalRead(actualpin); //reading actual button state
		//It only sends data if the state has changed
		/*button is pressed
    if(actualpin == ledpin){
      if((actual[i]==1) && (actual[i]!=before[i])){
        //MIDI.sendNoteOn(48+i,127,channel);
        MIDI.sendNoteOn(actualPage+i,127,channel);
      }else if((actual[i]==0) && (actual[i]!=before[i])){
        //MIDI.sendNoteOff(48+i,127,channel);
        //MIDI.sendNoteOff(pgOne+i,127,channel);
        //MIDI.sendNoteOff(pgTwo+i,127,channel);
        //MIDI.sendNoteOff(pgThree+i,127,channel);
        //MIDI.sendNoteOff(pgFour+i,127,channel);
        MIDI.sendNoteOff(actualPage+i,127,channel);
      }
    }*/
    if(actualpin != muxpin){
  		if((actual[i]==0) && (actual[i]!=before[i])){
        //MIDI.sendNoteOn(48+i,127,channel);
        MIDI.sendNoteOn(actualPage+i,127,channel);
  		}else if((actual[i]==1) && (actual[i]!=before[i])){
        //MIDI.sendNoteOff(48+i,0,channel);
        MIDI.sendNoteOff(actualPage+i,0,channel);
  		}
    }
		before[i]=actual[i];//setting before value as the current because its ending the for
	}
}

void updateAnalog(){
  for(int i=0;i<numAn;i++){
    actualAn[i]=digitalRead(14+i);
    if((actualAn[i] == HIGH) && (actualAn[i]!=beforeAn[i])){
      switch(i){
        case 0:
        actualPage=pgOne;
        Serial.println("p1");
        break;
        case 1:
        actualPage=pgTwo;
        Serial.println("p2");
        break;
        case 2:
        actualPage=pgThree;
        Serial.println("p3");
        break;
        case 3:
        actualPage=pgFour;
        Serial.println("p4");
        break;
      }
      //MIDI.sendNoteOn(66+i,127,channel);
    }else if((actualAn[i] == LOW) && (actualAn[i]!=beforeAn[i])){
      //I guess nothing
      //MIDI.sendNoteOff(66+i,0,channel);
    }
    beforeAn[i]=actualAn[i];
  }
}

void updateDigitalMuxBut(){
	for(int i=0;i<numMuxBut;i++){//multiplexer
		actualMux[i]=getValue(i);
		if((actualMux[i]==0) && (actualMux[i]!=beforeMux[i])){
			//MIDI.sendNoteOn(57+i,127,channel);
      MIDI.sendNoteOn(actualPage+9+i,127,channel);
		}else if((actualMux[i]==1) && (actualMux[i]!=beforeMux[i])){
			//MIDI.sendNoteOff(57+i,0,channel);
     MIDI.sendNoteOff(actualPage+9+i,0,channel);
		}
		beforeMux[i]=actualMux[i];
	}

}

int getValue(int c){
	for(int bit=0;bit<3;bit++){
		int pin=select[bit];
		int bitset = bitRead(c,bit);
		digitalWrite(pin,bitset);
	}
	return digitalRead(muxpin);
}