christophemagnanb
Published © GPL3+

Ondes Martenot Style MIDI Controller

Ondes Martenot Style MIDI controller, Arduino MEGA based. To use with Ondes VST by Soniccouture.

IntermediateShowcase (no instructions)5,076
Ondes Martenot Style MIDI Controller

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×13
Tactile Switch, Top Actuated
Tactile Switch, Top Actuated
×11
10-turn 10k pot
×1
Breadboard (generic)
Breadboard (generic)
×2
Jumper wires (generic)
Jumper wires (generic)
×1
LED (generic)
LED (generic)
×3
pulley
×2
fishing line
×1

Software apps and online services

Arduino IDE
Arduino IDE
Hairless MIDI/Serial Bridge
loopMIDI
Kontakt Player
Soniccouture Ondes

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Multitool, Screwdriver
Multitool, Screwdriver
Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Code

MIDI_Controller_v1-2_CMB.ino

C/C++
the 3 files must be in the same folder.
#include <MIDI.h>
#include "Controller.h"

MIDI_CREATE_DEFAULT_INSTANCE();


//**************************************************************************************************


//serial debug, to change manually:
int DEBUG = false;

//debounce time for buttons (channel and octave shift):
int debouncetime = 100;

//DEFINES:
#define PITCHBEND_POT A1

//midi channel buttons
#define MIDICH_BUTTON_UP 29
#define MIDICH_BUTTON_DOWN 30

//FSR:
#define FSR_PIN A0
#define FSR_LED_PIN 44

//trill buttons:
#define QUARTERTONEUP_BUTTON 8
#define QUARTERTONEDOWN_BUTTON 7
#define SEMITONEUP_BUTTON 9
#define TONEUP_BUTTON 10
#define THIRDUP_BUTTON 11
#define FIFTHUP_BUTTON 12

//octave buttons:
#define OCTAVEDOWN_BUTTON 3
#define OCTAVEUP_BUTTON 2
#define OCTAVE_LED_UP 46          
#define OCTAVE_LED_DOWN 45        

//VARIABLES:
//trill buttons:
int QUARTERTONEUPCOUNTER = 0;
int QUARTERTONEDOWNCOUNTER = 0;
int SEMITONEUPCOUNTER = 0;
int TONEUPCOUNTER = 0;
int THIRDUPCOUNTER = 0;
int FIFTHUPCOUNTER = 0;

int QUARTERTONEVALUE = 170;           //a semi-tone = 16384/48 = 341.
int SEMITONEVALUE = 341;
int TONEVALUE = 682;
int THIRDVALUE = 1023;
int FIFTHVALUE = 2387;

int trillvalue;

//midi channel buttons:
int MIDICH = 1;
int midich_plus;
int midich_moins;

//pitchbend:
int PB_INPUT_CURRENT = 0;
int PB_INPUT_ADJUST;      
int PB_INPUT_LAST = 0;
int PB_MAP;
int PB_INVERT;
int PB_ADJUST;
int PB_TOTAL;
int PB;
int PB_INPUT_CURRENT_LED_MAP;

//FSR LED:
int FSR_INPUT;
int FSR_INPUT_LED_MAP;

//ajustements:
float PBmultiplier = 1.25;         
int middleCadjust = 15;            

//octaves buttons:
int OCTAVECOUNTER = 0;
int OCTAVECOUNTERX;
int OCTAVE_COUNTER_LAST = 0;
int OCTAVE_COUNTER_CURRENT = 0;

//FSR notetrigger:
int currentNoteTriggerState = 0;
int lastNoteTriggerState = 0;


//NOTES AND VOLTS:
//************************************************************
//***SET THE NUMBER OF CONTROLS USED**************************
//************************************************************
//combien de TrillButtons:
//byte NUMBER_TRILLBUTTONS = 6;
//---How many buttons are connected directly to pins?---------
byte NUMBER_BUTTONS = 1;
//---How many potentiometers are connected directly to pins?--
byte NUMBER_POTS = 13;
//---How many buttons are connected to a multiplexer?---------
byte NUMBER_MUX_BUTTONS = 0;
//---How many potentiometers are connected to a multiplexer?--
byte NUMBER_MUX_POTS = 0;

//************************************************************

//***ANY MULTIPLEXERS? (74HC4067)************************************
//MUX address pins must be connected to Arduino UNO pins 2,3,4,5
//A0 = PIN2, A1 = PIN3, A2 = PIN4, A3 = PIN5
//*******************************************************************
//Mux NAME (OUTPUT PIN, , How Many Mux Pins?(8 or 16) , Is It Analog?);

//Mux M1(10, 16, false); //Digital multiplexer on Arduino pin 10
//Mux M2(A5, 8, true); //Analog multiplexer on Arduino analog pin A5
//*******************************************************************

//***DEFINE DIRECTLY CONNECTED POTENTIOMETERS************************
//Pot (Pin Number, Command, CC Control, Channel Number)
//**Command parameter is for future use**

Pot PO1(A3, 0, 85, MIDICH);        //BRIGHT
Pot PO2(A5, 0, 20, MIDICH);        //D3
Pot PO3(A6, 0, 22, MIDICH);        //D2
Pot PO4(A7, 0, 23, MIDICH);        //D1
Pot PO5(A8, 0, 24, MIDICH);        //LINE
Pot PO6(A9, 0, 25, MIDICH);        //8
Pot PO7(A10, 0, 26, MIDICH);       //N
Pot PO8(A11, 0, 27, MIDICH);       //C
Pot PO9(A12, 0, 28, MIDICH);      //O
Pot PO10(A13, 0, 29, MIDICH);      //G
Pot PO11(A14, 0, 30, MIDICH);      //g
Pot PO12(A15, 0, 31, MIDICH);      //S
Pot PO13(A0, 0, 11, MIDICH);         //FSR
//Pot PO14(A5, 0, 31, 1);

//*******************************************************************
//Add pots used to array below like this->  Pot *POTS[] {&PO1, &PO2, &PO3, &PO4, &PO5, &PO6};
Pot *POTS[] {&PO1, &PO2, &PO3, &PO4, &PO5, &PO6, &PO7, &PO8, &PO9, &PO10, &PO11, &PO12, &PO13};
//*******************************************************************

//***DEFINE DIRECTLY CONNECTED BUTTONS*******************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
//** Command parameter 0=NOTE  1=CC  2=Toggle CC **

Button BU1(6, 2, 86, MIDICH, 5 );          //TUTTI toggle
//Button BU2(x, x, x, x, x);          
//Button BU3(4, 1, 64, 1, 5 );
//Button BU4(5, 2, 63, 1, 5 );
//Button BU5(6, 0, 64, 1, 5 );
//Button BU6(7, 0, 65, 1, 5 );
//Button BU7(8, 1, 64, 1, 5 );
//Button BU8(9, 2, 64, 1, 5 );
//*******************************************************************
//Add buttons used to array below like this->  Button *BUTTONS[] {&BU1, &BU2, &BU3, &BU4, &BU5, &BU6, &BU7, &BU8};
Button *BUTTONS[] {&BU1};
//*******************************************************************

//***DEFINE BUTTONS CONNECTED TO MULTIPLEXER*************************
//Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce)
//** Command parameter 0=NOTE  1=CC  2=Toggle CC **

//Button MBU1(M1, 0, 0, 70, 1, 5);
//Button MBU2(M1, 1, 1, 71, 1, 5);
//Button MBU3(M1, 2, 2, 72, 1, 5);
//Button MBU4(M1, 3, 0, 73, 1, 5);
//Button MBU5(M1, 4, 0, 74, 1, 5);
//Button MBU6(M1, 5, 0, 75, 1, 5);
//Button MBU7(M1, 6, 0, 76, 1, 5);
//Button MBU8(M1, 7, 0, 77, 1, 5);
//Button MBU9(M1, 8, 0, 78, 1, 5);
//Button MBU10(M1, 9, 0, 79, 1, 5);
//Button MBU11(M1, 10, 0, 80, 1, 5);
//Button MBU12(M1, 11, 0, 81, 1, 5);
//Button MBU13(M1, 12, 0, 82, 1, 5);
//Button MBU14(M1, 13, 0, 83, 1, 5);
//Button MBU15(M1, 14, 0, 84, 1, 5);
//Button MBU16(M1, 15, 0, 85, 1, 5);
//*******************************************************************
////Add multiplexed buttons used to array below like this->  Button *MUXBUTTONS[] {&MBU1, &MBU2, &MBU3, &MBU4, &MBU5, &MBU6.....};
Button *MUXBUTTONS[] {};

//*******************************************************************

//***DEFINE POTENTIOMETERS CONNECTED TO MULTIPLEXER*******************
//Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel)
//**Command parameter is for future use**
//assigns au cc 20  27 inclusivement (midi cc qui sont de base unasigned...)
//Pot MPO1(M2, 0, 0, 20, 1);
//Pot MPO2(M2, 1, 0, 21, 1);
//Pot MPO3(M2, 2, 0, 22, 1);
//Pot MPO4(M2, 3, 0, 23, 1);
//Pot MPO5(M2, 4, 0, 24, 1);
//Pot MPO6(M2, 5, 0, 25, 1);
//Pot MPO7(M2, 6, 0, 26, 1);
//Pot MPO8(M2, 7, 0, 27, 1);
//Pot MPO9(M2, 8, 0, 50, 1);
//Pot MPO10(M2, 9, 0, 55, 2);
//Pot MPO11(M2, 10, 0, 50, 1);
//Pot MPO12(M2, 11, 0, 55, 2);
//Pot MPO13(M2, 12, 0, 50, 1);
//Pot MPO14(M2, 13, 0, 55, 2);
//Pot MPO15(M2, 14, 0, 50, 1);
//Pot MPO16(M2, 15, 0, 55, 2);
//*******************************************************************
//Add multiplexed pots used to array below like this->  Pot *MUXPOTS[] {&MPO1, &MPO2, &MPO3, &MPO4, &MPO5, &MPO6.....};
Pot *MUXPOTS[] {};

//*******************************************************************

void setup() {

  //pinModes pour octave buttons:
  pinMode(OCTAVEDOWN_BUTTON, INPUT);
  pinMode(OCTAVEUP_BUTTON, INPUT);

  //pinModes pour trillbuttons:
  pinMode(QUARTERTONEUP_BUTTON, INPUT);
  pinMode(QUARTERTONEDOWN_BUTTON, INPUT);
  pinMode(SEMITONEUP_BUTTON, INPUT);
  pinMode(TONEUP_BUTTON, INPUT);
  pinMode(THIRDUP_BUTTON, INPUT);
  pinMode(FIFTHUP_BUTTON, INPUT);

  //MIDICH buttons:
  pinMode(MIDICH_BUTTON_DOWN, INPUT);
  pinMode(MIDICH_BUTTON_UP, INPUT);

  //leds:
  pinMode(OCTAVE_LED_DOWN, OUTPUT);
  pinMode(OCTAVE_LED_UP, OUTPUT);

  pinMode(FSR_LED_PIN, OUTPUT);


    //MIDI.begin();
    Serial.begin(115200);       //115200 = default rate of Hairless MIDI/serial bridge software.

}

//*************************************************************************************************************

void loop() {

  //added:
  MIDIChannel();
  PBVOID();
  NoteTrigger();
  LEDs();

  //original:
  if (NUMBER_BUTTONS != 0) updateButtons();
  if (NUMBER_POTS != 0) updatePots();
  if (NUMBER_MUX_BUTTONS != 0) updateMuxButtons();              
  if (NUMBER_MUX_POTS != 0) updateMuxPots();

  //added, serial debug:
  if (DEBUG == true) {
    Serial.print(PB_INPUT_CURRENT);
    Serial.print(", "); Serial.print(PB_INPUT_ADJUST);
    Serial.print(", "); Serial.print(PB_TOTAL);
    Serial.print(", "); Serial.print(MIDICH);
    Serial.print(", "); Serial.print(currentNoteTriggerState);
    Serial.print(", "); Serial.print(OCTAVECOUNTER);
    //Serial.print(", "); Serial.print();
    //Serial.print(", "); Serial.print();
    //Serial.print(", "); Serial.print();
    //Serial.print(", "); Serial.print();
    //Serial.print(", "); Serial.print();
    //Serial.print(", "); Serial.print();
    Serial.println();
  }
}

//*************************************************************************************************************************************

void MIDIChannel() {

  MIDICH = constrain(MIDICH, 1, 16);

  midich_plus = digitalRead(MIDICH_BUTTON_UP);
  midich_moins = digitalRead(MIDICH_BUTTON_DOWN);

  //+:
  if (midich_plus == HIGH) {
    MIDICH++;
    delay(debouncetime);
  }
  //-:
  if (midich_moins == HIGH) {
    MIDICH--;
    delay(debouncetime);
  }

}

//***********************************************************************

void NoteTrigger() {

  OCTAVECOUNTER = constrain(OCTAVECOUNTER, -3, 3);      //+- 3 octaves max shift
  
  //octave buttons:
  if (digitalRead(OCTAVEUP_BUTTON) == HIGH) {
    OCTAVECOUNTER++;
    delay(debouncetime);
    }
  if (digitalRead(OCTAVEDOWN_BUTTON) == HIGH) {
    OCTAVECOUNTER--;
    delay(debouncetime);
    }

    OCTAVECOUNTERX = OCTAVECOUNTER * 12;


    currentNoteTriggerState = analogRead(FSR_PIN);

        if (currentNoteTriggerState > 0 && lastNoteTriggerState == 0) {
          MIDI.sendNoteOn(60 + OCTAVECOUNTERX, 127, MIDICH);         
          }
        if (currentNoteTriggerState == 0 && lastNoteTriggerState > 0) {
          MIDI.sendNoteOff(60 + OCTAVECOUNTERX, 127, MIDICH);
          }

    lastNoteTriggerState = currentNoteTriggerState;

}

//************************************************************************
      
void PBVOID() {
       
   //quarter tone up:
   if (digitalRead(QUARTERTONEUP_BUTTON) == HIGH) {
      QUARTERTONEUPCOUNTER = QUARTERTONEVALUE;
   }
   if (digitalRead(QUARTERTONEUP_BUTTON) == LOW) {
      QUARTERTONEUPCOUNTER = 0;
   }
   //quarter tone down:
   if (digitalRead(QUARTERTONEDOWN_BUTTON) == HIGH) {
      QUARTERTONEDOWNCOUNTER = -QUARTERTONEVALUE;
   }
   if (digitalRead(QUARTERTONEDOWN_BUTTON) == LOW) {
      QUARTERTONEDOWNCOUNTER = 0;
   }
   //semi-tone up:
   if (digitalRead(SEMITONEUP_BUTTON) == HIGH) {
     SEMITONEUPCOUNTER = SEMITONEVALUE;
   }
   if (digitalRead(SEMITONEUP_BUTTON) == LOW) {
     SEMITONEUPCOUNTER = 0;
   }
   //tone up:
   if (digitalRead(TONEUP_BUTTON) == HIGH) {
     TONEUPCOUNTER = TONEVALUE;
   }
   if (digitalRead(TONEUP_BUTTON) == LOW) {
     TONEUPCOUNTER = 0;
   }
   //third up:
   if (digitalRead(THIRDUP_BUTTON) == HIGH) {
     THIRDUPCOUNTER = THIRDVALUE;
   }
   if (digitalRead(THIRDUP_BUTTON) == LOW) {
     THIRDUPCOUNTER = 0;
   }
   //fifth up:
   if (digitalRead(FIFTHUP_BUTTON) == HIGH) {
     FIFTHUPCOUNTER = FIFTHVALUE;
   }
   if (digitalRead(FIFTHUP_BUTTON) == LOW) {
     FIFTHUPCOUNTER = 0;
   }

   trillvalue = QUARTERTONEUPCOUNTER + QUARTERTONEDOWNCOUNTER + SEMITONEUPCOUNTER + TONEUPCOUNTER + THIRDUPCOUNTER + FIFTHUPCOUNTER;

    //pitch bend pot:
    PB_INPUT_CURRENT = analogRead(PITCHBEND_POT);
    PB_INPUT_CURRENT_LED_MAP = map(PB_INPUT_CURRENT, -8192, 8191, 0, 255);
    PB_INPUT_ADJUST = PB_INPUT_CURRENT + middleCadjust;
    PB_INPUT_ADJUST = constrain(PB_INPUT_ADJUST, 0, 1023);
    PB_MAP = map(PB_INPUT_ADJUST, 1023, 0, -8192, 8191);       //signed integer value.
    PB_ADJUST = PB_MAP * PBmultiplier;
    PB_TOTAL = PB_ADJUST + trillvalue;
    PB_TOTAL = constrain(PB_TOTAL, -8192, 8191);

  //send pitchbend continuoulsy:
  MIDI.sendPitchBend(PB_TOTAL, MIDICH); 
  delay(2); //for stability     
       
}

//*******************************************************************

void LEDs() {
  
  OCTAVE_COUNTER_CURRENT = OCTAVECOUNTER;

  if(OCTAVE_COUNTER_CURRENT != OCTAVE_COUNTER_LAST) {
      if (OCTAVECOUNTER == -3) {
        analogWrite(OCTAVE_LED_DOWN, 255);
        digitalWrite(OCTAVE_LED_UP, LOW);
        }
      if (OCTAVECOUNTER == -2) {
        analogWrite(OCTAVE_LED_DOWN, 170);
        digitalWrite(OCTAVE_LED_UP, LOW);
        }
      if (OCTAVECOUNTER == -1) {
        analogWrite(OCTAVE_LED_DOWN, 85);
        digitalWrite(OCTAVE_LED_UP, LOW);
        }
      if (OCTAVECOUNTER == 0) {
        digitalWrite(OCTAVE_LED_DOWN, LOW);
        digitalWrite(OCTAVE_LED_UP, LOW);
        }
      if (OCTAVECOUNTER == 1) {
        digitalWrite(OCTAVE_LED_DOWN, LOW);
        analogWrite(OCTAVE_LED_UP, 85);
        }
      if (OCTAVECOUNTER == 2) {
        digitalWrite(OCTAVE_LED_DOWN, LOW);
        analogWrite(OCTAVE_LED_UP, 170);
        }
      if (OCTAVECOUNTER == 3) {
        digitalWrite(OCTAVE_LED_DOWN, LOW);
        analogWrite(OCTAVE_LED_UP, 255);
        }
    }
        
  OCTAVE_COUNTER_LAST = OCTAVE_COUNTER_CURRENT;

  FSR_INPUT = analogRead(FSR_PIN);
  FSR_INPUT_LED_MAP = map(FSR_INPUT, 0, 1024, 0, 255);
  
    //FSR LED:
    if(analogRead(FSR_PIN) > 0) {
      analogWrite(FSR_LED_PIN, FSR_INPUT_LED_MAP);
      }
    if(analogRead(FSR_PIN) == 0) {
      digitalWrite(FSR_LED_PIN, LOW);
      }
          
}

//**********************************************************************************************

void updateButtons() {

        // Cycle through Button array
        for (int i = 0; i < NUMBER_BUTTONS; i = i + 1) {
          byte message = BUTTONS[i]->getValue();

          //  Button is pressed
          if (message == 0) {
            switch (BUTTONS[i]->Bcommand) {
              case 0: //Note
                MIDI.sendNoteOn(BUTTONS[i]->Bvalue + OCTAVECOUNTER * 12, 127, BUTTONS[i]->Bchannel);
                break;
              case 1: //CC
                MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
                break;
              case 2: //Toggle
                if (BUTTONS[i]->Btoggle == 0) {
                  MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, MIDICH);      //origine: BUTTONS[i]->Bchannel
                  BUTTONS[i]->Btoggle = 1;
                }
                else if (BUTTONS[i]->Btoggle == 1) {
                  MIDI.sendControlChange(BUTTONS[i]->Bvalue, 0, MIDICH);        //origine: BUTTONS[i]->Bchannel
                  BUTTONS[i]->Btoggle = 0;
                }
                break;
            }
          }

          //  Button is not pressed
          if (message == 1) {
            switch (BUTTONS[i]->Bcommand) {
              case 0:
                MIDI.sendNoteOff(BUTTONS[i]->Bvalue + OCTAVECOUNTER * 12, 0, BUTTONS[i]->Bchannel);
                break;
              case 1:
                MIDI.sendControlChange(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
                break;
            }
          }
        }
}
     
//*******************************************************************

void updateMuxButtons() {

        // Cycle through Mux Button array
        for (int i = 0; i < NUMBER_MUX_BUTTONS; i = i + 1) {

          MUXBUTTONS[i]->muxUpdate();
          byte message = MUXBUTTONS[i]->getValue();

          //  Button is pressed
          if (message == 0) {
            switch (MUXBUTTONS[i]->Bcommand) {
              case 0: //Note
                MIDI.sendNoteOn(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
                break;
              case 1: //CC
                MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
                break;
              case 2: //Toggle
                if (MUXBUTTONS[i]->Btoggle == 0) {
                  MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 127, MUXBUTTONS[i]->Bchannel);
                  MUXBUTTONS[i]->Btoggle = 1;
                }
                else if (MUXBUTTONS[i]->Btoggle == 1) {
                  MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
                  MUXBUTTONS[i]->Btoggle = 0;
                }
                break;
            }
          }
          //  Button is not pressed
          if (message == 1) {
            switch (MUXBUTTONS[i]->Bcommand) {
              case 0:
                MIDI.sendNoteOff(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
                break;
              case 1:
                MIDI.sendControlChange(MUXBUTTONS[i]->Bvalue, 0, MUXBUTTONS[i]->Bchannel);
                break;
            }
          }
        }
}
      
//***********************************************************************

void updatePots() {
        for (int i = 0; i < NUMBER_POTS; i = i + 1) {
          byte potmessage = POTS[i]->getValue();
          if (potmessage != 255) MIDI.sendControlChange(POTS[i]->Pcontrol, potmessage, MIDICH);        //origine: POTS[i]->Pchannel
        }
}
      
//***********************************************************************

void updateMuxPots() {
        for (int i = 0; i < NUMBER_MUX_POTS; i = i + 1) {
          MUXPOTS[i]->muxUpdate();
          byte potmessage = MUXPOTS[i]->getValue();
          if (potmessage != 255) MIDI.sendControlChange(MUXPOTS[i]->Pcontrol, potmessage, MUXPOTS[i]->Pchannel);
        }
}

// ********************   END   ***************************** //

Controller.h

C/C++
#ifndef Controller_h
#define Controller_h

#include <Arduino.h>

//***********************************************************************
class Mux
{
  public:
    Mux(byte outpin_, byte numPins_, bool analog_);
    byte outpin;
    byte numPins;
    bool analog;
};
//************************************************************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
class Button
{
  public:
    Button(byte pin, byte command, byte value, byte channel, byte debounce);
    Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce);
    byte getValue();
    void muxUpdate();
    void newValue(byte command, byte value, byte channel);
    byte Bcommand;
    byte Bvalue;
    byte Bchannel;
    byte Btoggle;

  private:
    byte _previous;
    byte _current;
    unsigned long _time;
    int _debounce;
    byte _pin;
    byte _muxpin;
    byte _numMuxPins;
    byte _value;
    byte _command;
    bool _busy;
    byte _status;
    byte _last;
    byte _enablepin;
};
//*************************************************************************
class Pot
{
  public:
    Pot(byte pin, byte command, byte control, byte channel);
    Pot(Mux mux, byte muxpin ,byte command, byte control, byte channel);
    void muxUpdate();
    void newValue(byte command, byte value, byte channel);
    byte getValue();
    byte Pcommand;
    byte Pcontrol;
    byte Pchannel;

  private:
    byte _pin;
    byte _muxpin;
    byte _numMuxPins;
    byte _control;
    int _value;
    int _oldValue;
    bool _changed;
    byte _enablepin;
};
//*************************************************************************
#endif

Controller.cpp

C/C++
#include "Controller.h"

//****************************************************************************************
Mux::Mux(byte outpin_, byte numPins_, bool analog_)
{
  outpin = outpin_;
  //enablepin = enablepin_;
  numPins = numPins_;
  analog = analog_;
  if (analog == false) pinMode(outpin, INPUT_PULLUP);
  //pinMode(enablepin, OUTPUT);
  pinMode(24, OUTPUT);
  pinMode(25, OUTPUT);
  pinMode(26, OUTPUT);
  if (numPins > 8) pinMode(27, OUTPUT);
}
//****************************************************************************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
Button::Button(byte pin, byte command, byte value, byte channel, byte debounce)
{
  _pin = pin;
  pinMode(_pin, INPUT_PULLUP);
  _value = value;
  _command = command;
  _debounce = debounce;
  _time = 0;
  _busy = false;
  _status = 0b00000010;
  _last = 1;
  Bcommand = command;
  Bvalue = value;
  Bchannel = channel;
  Btoggle = 0;
}

Button::Button(Mux mux, byte muxpin, byte command, byte value, byte channel, byte debounce)
{
  _pin = mux.outpin;
  _numMuxPins = mux.numPins;
  _muxpin = muxpin;
  _value = value;
  _command = command;
  _debounce = debounce;
  _time = 0;
  _busy = false;
  _status = 0b00000010;
  _last = 1;
  Bcommand = command;
  Bvalue = value;
  Bchannel = channel;
  Btoggle = 0;
}

void Button::muxUpdate()
{
  byte temp = _muxpin;
  temp = temp << 2;
  if (_numMuxPins > 8) PORTA = PORTA & B11000011;
  else PORTA = PORTA & B11100011;
  PORTA = PORTA | temp;
}

byte Button::getValue()
{
  // If BUSY bit not set - read button
  if (bitRead(_status, 0) == false) { // If busy false
    if (digitalRead(_pin) == _last) return 2; // If same as last state - exit
  }

  // If NEW Bit set - Key just pressed, record time
  if (bitRead(_status, 1) == true) { // If new is true
    bitSet(_status, 0); // Set busy TRUE
    bitClear(_status, 1); // Set New FALSE
    _time = millis();
    return 255;
  }

  // Check if debounce time has passed - If no, exit
  if (millis() - _time < _debounce) return 255;

  // Debounce time has passed. Read pin to see if still set the same
  // If it has changed back - assume false alarm
  if (digitalRead(_pin) == _last) {
    bitClear(_status, 0); // Set busy false
    bitSet(_status, 1); // Set new true
    return 255;
  }

  // If this point is reached, event is valid. return event type
  else {
    bitClear(_status, 0); // Set busy false
    bitSet(_status, 1); // Set new true
    _last = ((~_last) & 0b00000001); // invert _last
    return _last;
  }
}

void Button::newValue(byte command, byte value, byte channel)
{
  Bvalue = value;
  Bcommand = command;
  Bchannel = channel;
}

//********************************************************************
Pot::Pot(byte pin, byte command, byte control, byte channel)
{
  _pin = pin;
  _control = control;
  _value = analogRead(_pin);
  _value = _value >> 3;
  _oldValue = _value << 3;
  _value = _value << 3;
  Pcommand = command;
  Pcontrol = control;
  Pchannel = channel;
}

void Pot::muxUpdate()
{
  byte temp = _muxpin;
  temp = temp << 2;
  if (_numMuxPins > 8) PORTA = PORTA & B11000011;
  else PORTA = PORTA & B11100011;
  //PORTA = PORTA & B11000011;
  PORTA = PORTA | temp;
}

Pot::Pot(Mux mux, byte muxpin, byte command, byte control, byte channel)
{
  _pin = mux.outpin;
  _numMuxPins = mux.numPins;
  _muxpin = muxpin;
  _control = control;
  muxUpdate();
  _value = analogRead(_pin);
  _value = _value >> 3;
  _oldValue = _value << 3;
  _value = _value << 3;
  Pcommand = command;
  Pcontrol = control;
  Pchannel = channel;
}

byte Pot::getValue()
{
  _value = analogRead(_pin);
  int tmp = (_oldValue - _value);
  if (tmp >= 8 || tmp <= -8) {
    _oldValue = _value >> 3;
    _oldValue = _oldValue << 3;
    return _value >> 3;
  }
  return 255;
}

void Pot::newValue(byte command, byte value, byte channel) {
  Pcommand = command;
  Pcontrol = value;
  Pchannel = channel;
}

Credits

christophemagnanb
0 projects • 2 followers
Contact

Comments

Please log in or sign up to comment.