Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Código feito através de modificações de códigos pertencentes ao Gustavo Silveira (http://www.musiconerd.com)
- e código encontrado no GitHub (https://github.com/romix123/Seeeduino_XIAO_MIDI_drumpad/blob/main/XiaoDrum/XiaoDrum.ino).
- Os códigos possuem parte autoral e alterações dos códigos mencionados feitas por: Marjorie Macário Maximiano.
- Feito para funcionar em arduino com ATmega 328 (Uno, Mega, Nano,...)
- Fatec - Tatuí
- Produção Fonográfica
- Trabalho de Graduação 2021.1
- MaxControl: Desenvolvimento de controlador MIDI de baixo custo.
- //Membros do Grupo:
- -Augusto Cesar Mendes Gomes;
- -Guilherme Luis Lima Furlan;
- -Leonardo Alan Kirchner;
- -Marjorie Macário Maximiano;
- -Rayla Aparecida Manoel.
- //Orientador:
- -Lucas Correia Meneguette.
- //Coorientador:
- -Otávio dos Santos Gaijuts.
- */
- #define ATMEGA328 1//* coloque aqui o uC que você está usando, como nas linhas acima seguido por "1", como "ATMEGA328 1", "DEBUG 1", etc.
- ////////////////////////////////////////////////////////////////////////////////////////M A X C T R L 1////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////
- // BIBLIOTECAS
- // -- Define a biblioteca MIDI -- //
- // se estiver usando com ATmega328 - Uno, Mega, Nano ...
- #include <MIDI.h>
- MIDI_CREATE_DEFAULT_INSTANCE();
- ////////////////////////////////////////////////////////////////////////////////////////////BOTOES/////////////////////////////////////////////////////////////////////////////////////////////
- const int N_BUTTONS = 16; //número total de botões usados.
- const int BUTTON_ARDUINO_PIN[N_BUTTONS] = {4, 5, 6, 7, 8, 9, 14, 15, 16, 17, 18, 19, 22, 23, 24, 25}; //pinagem de todos os botões.
- ////Botões DAW = 4,5, 6, 7, 8, 9, 14;
- ////Botão Joystick = 16;
- ////Botões Encoders = 17, 18, 19, 22;
- ///Pedal = 23;
- ////Botões Transpose = 24, 25;
- int buttonCState [N_BUTTONS] = {0};
- int buttonPState [N_BUTTONS] = {0};
- //debounce
- unsigned long lastDebounceTime[N_BUTTONS] = {0};
- unsigned long debounceDelay = 5;
- ///////////////////////////////////////////////////////////////////////////////////////////PIEZOS//////////////////////////////////////////////////////////////////////////////////////////////
- const int N_PIEZO = 13;
- const int PIEZO_ARDUINO_PIN[N_PIEZO] = {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12};
- boolean piezo = false;
- ///////////////////////////////////////////////////////////////////////////////////////LEDS TRANSPOSE//////////////////////////////////////////////////////////////////////////////////////////
- const int N_LEDS = 6;
- const int LEDS_ARDUINO_PIN [N_LEDS] = {26, 27, 28, 29, 30, 31};
- //int pinoR1 = 26;
- //int pinoG1 = 27;
- //int pinoB1 = 28;
- //int pinoR2 = 29;
- //int pinoG2 = 30;
- //int pinoB2 = 31;
- #define COMMOM_ANODE // Caso esteja usando o LED RGB com catodo comum, comente essa linha.
- bool estadoLed = 0;
- //////////////////////////////////////////////////////////////////////////////////////////JOYSTICK/////////////////////////////////////////////////////////////////////////////////////////////
- const int N_POTS = 2; //* total numbers of pots (slide & rotary)
- const int POT_ARDUINO_PIN[N_POTS] = {A13, A14}; //* pins of each pot connected straight to the Arduino
- int potCState[N_POTS] = {0}; // Current state of the pot
- int potPState[N_POTS] = {0}; // Previous state of the pot
- int potVar = 0; // Difference between the current and previous state of the pot
- int midiCState[N_POTS] = {0}; // Current state of the midi value
- int midiPState[N_POTS] = {0}; // Previous state of the midi value
- const int TIMEOUT = 1000; //* Amount of time the potentiometer will be read after it exceeds the varThreshold
- const int varThreshold = 5; //* Threshold for the potentiometer signal variation
- boolean potMoving = true; // If the potentiometer is moving
- unsigned long PTime[N_POTS] = {0}; // Previously stored time
- unsigned long timer[N_POTS] = {0}; // Stores the time that has elapsed since the timer was reset
- /////////////////////////////////
- // MIDI IN
- byte midiCh = 1;
- byte note = 60;
- byte cc = 1;
- byte ENCODER_MIDI_CH = 0;
- ////////////////////////////////////////////////////////////////////////////////////////PITCH BEND/////////////////////////////////////////////////////////////////////////////////////////////
- //multiMap(int value, int fromMap[], int fromMapSize, int toMap[], int toMapSize)
- int PBVal = 0;
- int PBFromMap [] {0, 532, 1023};
- int PBToMpas [] {0, 16383};
- byte PBFromMapSize = 14;
- byte PBToMapSize = 13;
- byte shiftVal = 19;
- ////////////////////////////////////////////////////////////////////////////////////////ENCODERS/////////////////////////////////////////////////////////////////////////////////////////////
- #include <Encoder.h>
- const byte N_ENCODERS = 4; //* número de encoders
- const byte N_ENCODER_PINS = N_ENCODERS * 2; // número de pinos usados pelos codificadores
- const byte N_ENCODER_MIDI_CHANNELS = 16; // número de ENCODER_MIDI_CHs
- byte ENCODER_CC_N[N_ENCODERS] = {16, 17, 18, 19}; //* Adicione o CC NUMBER de cada encoder que você deseja
- Encoder encoder[N_ENCODERS] = {{2, 3}, {10, 11}, {12, 13} , {20, 21}}; //* os dois pinos de cada encoder - Use pinos com interrupts!
- byte encoderMinVal = 0; //* valor mínimo do encoder
- byte encoderMaxVal = 127; //* vamor máximo do encoder
- byte preset[N_ENCODER_MIDI_CHANNELS][N_ENCODERS] = { //* armazena presets para o seu encoder
- // {64, 64}, // ch 1
- // {64, 64}, // ch 2
- // {64, 64}, // ch 3
- // {64, 64}, // ch 4
- // {64, 64}, // ch 5
- // {64, 64}, // ch 6
- // {64, 64}, // ch 7
- // {64, 64}, // ch 8
- // {64, 64}, // ch 9
- // {64, 64}, // ch 10
- // {64, 64}, // ch 11
- // {64, 64}, // ch 12
- // {64, 64}, // ch 13
- // {64, 64}, // ch 14
- // {64, 64}, // ch 15
- // {64, 64} // ch 16
- };
- byte lastEncoderValue[N_ENCODER_MIDI_CHANNELS][N_ENCODERS] = {127};
- byte encoderValue[N_ENCODER_MIDI_CHANNELS][N_ENCODERS] = {127};
- // para os canais dos encoders - Usado para bancos diferentes
- byte lastEncoderChannel = 0;
- unsigned long encPTime[N_ENCODERS] = {0};
- unsigned long encTimer[N_ENCODERS] = {0};
- boolean encMoving[N_ENCODERS] = {false};
- boolean encMoved[N_ENCODERS] = {false};
- byte encTIMEOUT = 50;
- byte encoder_n;
- byte encTempVal = 0;
- void setup () {
- Serial.begin (115200);
- delay(1000);
- for (int i = 0; i < N_LEDS; i++) {
- pinMode (LEDS_ARDUINO_PIN[i], OUTPUT);
- }
- for (int i = 0; i < N_BUTTONS; i++) {
- pinMode (BUTTON_ARDUINO_PIN[i], INPUT_PULLUP);
- }
- for (int i = 0; i < N_ENCODERS; i++) {
- encoder [i].write(preset[0][i]);
- }
- for (int z = 0; z < N_ENCODER_MIDI_CHANNELS; z++) {
- for (int i = 0; i < N_ENCODERS; i++) {
- lastEncoderValue[z][i] = preset[z][i];
- }
- }
- ENCODER_MIDI_CH++;
- /////////////////////////////////////////////
- // Midi in
- MIDI.turnThruOff();
- // MIDI.setHandleControlChange(handleControlChange);
- // MIDI.setHandleNoteOn(handleNoteOn);
- // MIDI.setHandleNoteOff(handleNoteOff);
- }
- void loop () {
- MIDI.read();
- encoders();
- isEncoderMoving();
- buttons();
- leds();
- joystick();
- piezos();
- }
- //////////////////////////////////////
- //////// BOTÕES
- void buttons() {
- for (int i = 0; i < N_BUTTONS; i++) {
- buttonCState [i] = digitalRead(BUTTON_ARDUINO_PIN[i]);
- if ((millis() - lastDebounceTime[i]) > debounceDelay) {
- if (buttonPState [i] != buttonCState [i]) {
- lastDebounceTime [i] = millis();
- if (buttonCState [14] == LOW) {
- //decrease midi transpose
- note -= 12; // TRANSPOSE DOWN
- if (note < 24) {
- note = 24;
- }
- } else if (buttonCState [15] == LOW) {
- //increase midi transpose
- note += 12; //TRANSPOSE UP
- if (note > 96) {
- note = 96;
- }
- }
- if (buttonCState[i] == LOW) {
- }
- ///////////////////////////////////
- ///////BOTÕES DAW - JOYSTICK - ENCODERS - PEDAL (ADICIONAR OS BOTÕES DOS ENCODERS COM MUDANÇA DE BANCOS)
- if (buttonCState [0] == LOW) {
- MIDI.sendControlChange (20, 127, 1); //Botão DAW 1
- }
- if (buttonCState [1] == LOW) {
- MIDI.sendControlChange (21, 127, 1); //Botão DAW 2
- }
- if (buttonCState [2] == LOW) {
- MIDI.sendControlChange (22, 127, 1); //Botão DAW 3
- }
- if (buttonCState [3] == LOW) {
- MIDI.sendControlChange (23, 127, 1); //Botão DAW 4
- }
- if (buttonCState [4] == LOW) {
- MIDI.sendControlChange (24, 127, 1); //Botão DAW 5
- }
- if (buttonCState [5] == LOW) {
- MIDI.sendControlChange (25, 127, 1); //Botão DAW 6
- }
- if (buttonCState [6] == LOW) {
- MIDI.sendControlChange (26, 127, 1); //Botão DAW 7
- }
- if (buttonCState [7] == LOW) {
- MIDI.sendControlChange (27, 127, 1); //Botão DAW 8
- }
- if (buttonCState [8] == LOW) {
- MIDI.sendControlChange (28, 127, 1); //Botão Joystick
- }
- if (buttonCState [9] == LOW) {
- MIDI.sendControlChange (29, 127, 1); //Botão Encoder 1
- }
- if (buttonCState [10] == LOW) {
- MIDI.sendControlChange (30, 127, 1); //Botão Encoder 2
- }
- if (buttonCState [11] == LOW) {
- MIDI.sendControlChange (31, 127, 1); //Botão Encoder 3
- }
- if (buttonCState [12] == LOW) {
- MIDI.sendControlChange (85, 127, 1); //Botão Encoder 4
- }
- if (buttonCState [13] == HIGH) {
- MIDI.sendControlChange (64, 127, 1); //Pedal
- }
- }
- buttonPState [i] = buttonCState [i];
- }
- }
- }
- ///////////////////////////
- ///////LEDS INDICADORES DE TRANSPOSE
- void leds() {
- for (int i = 0; i < N_LEDS; i++) {
- if (note == 24) {
- digitalWrite (LEDS_ARDUINO_PIN[0], HIGH);
- }
- if (note != 24) {
- digitalWrite (LEDS_ARDUINO_PIN[0], LOW);
- }
- if (note == 36) {
- digitalWrite (LEDS_ARDUINO_PIN[1], HIGH);
- }
- if (note != 36) {
- digitalWrite (LEDS_ARDUINO_PIN[1], LOW);
- }
- if (note == 48) {
- digitalWrite (LEDS_ARDUINO_PIN[2], HIGH);
- }
- if (note != 48) {
- digitalWrite (LEDS_ARDUINO_PIN[2], LOW);
- }
- if (note == 72) {
- digitalWrite (LEDS_ARDUINO_PIN[3], HIGH);
- }
- if (note != 72) {
- digitalWrite (LEDS_ARDUINO_PIN[3], LOW);
- }
- if (note == 84) {
- digitalWrite (LEDS_ARDUINO_PIN[4], HIGH);
- }
- if (note != 84) {
- digitalWrite (LEDS_ARDUINO_PIN[4], LOW);
- }
- if (note == 96) {
- digitalWrite (LEDS_ARDUINO_PIN[5], HIGH);
- }
- if (note != 96) {
- digitalWrite (LEDS_ARDUINO_PIN[5], LOW);
- }
- }
- }
- /////////////////////////////
- ////////////JOYSTICK
- void joystick() {
- for (int i = 0; i < N_POTS; i++) { // Loops through all the potentiometers
- potCState[i] = analogRead(POT_ARDUINO_PIN[i]); // reads the pins from arduino
- midiCState[i] = map(potCState[i], 0, 1023, 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 accordingly to the chosen board
- //#ifdef ATMEGA328
- // use if using with ATmega328 (uno, mega, nano...)
- MIDI.sendControlChange(cc + i, midiCState[i], midiCh); // cc number, cc value, midi channel
- potPState[i] = potCState[i]; // Stores the current reading of the potentiometer to compare with the next
- midiPState[i] = midiCState[i];
- }
- }
- }
- }
- /////////////////////////////
- ///////////PIEZOS
- void piezos() {
- for (int i = 0; i < N_PIEZO; i++) {
- int sensorValue = analogRead(PIEZO_ARDUINO_PIN[i]);
- int MAX;
- if (sensorValue > 20 && piezo == false) {
- int peak1 = analogRead(PIEZO_ARDUINO_PIN[i]);
- MAX = peak1;
- delay(1);
- int peak2 = analogRead(PIEZO_ARDUINO_PIN[i]);
- if (peak2 > MAX) {
- MAX = peak2;
- }
- delay(1);
- int peak3 = analogRead(PIEZO_ARDUINO_PIN[i]);
- if (peak3 > MAX) {
- MAX = peak3;
- }
- delay(1);
- int peak4 = analogRead(PIEZO_ARDUINO_PIN[i]);
- if (peak4 > MAX) {
- MAX = peak4;
- }
- delay(1);
- int peak5 = analogRead(PIEZO_ARDUINO_PIN[i]);
- if (peak5 > MAX) {
- MAX = peak5;
- }
- delay(1);
- int peak6 = analogRead(PIEZO_ARDUINO_PIN[i]);
- if (peak6 > MAX) {
- MAX = peak6;
- }
- MAX = map(MAX, 20, 800, 1, 127);
- if (MAX <= 1) {
- MAX = 1;
- }
- if (MAX >= 127) {
- MAX = 127;
- }
- MIDI.sendNoteOn(note + i, MAX, 1);
- MIDI.sendNoteOff(note + i, 0, 1);
- delay(20);
- // Serial.println(MAX);
- piezo = true;
- delay(30); //mask time
- }
- if (sensorValue <= 0 && piezo == true) {
- piezo = false;
- }
- }
- }
- /////////////////////////////
- ///////////ENCODERS
- void encoders() {
- for (int i = 0; i < N_ENCODERS; i++) {
- encoderValue[ENCODER_MIDI_CH][i] = encoder[i].read(); // reads each encoder and stores the value
- }
- for (int i = 0; i < N_ENCODERS; i++) {
- if (encoderValue[ENCODER_MIDI_CH][i] != lastEncoderValue[ENCODER_MIDI_CH][i]) {
- //#ifdef TRAKTOR // to use with Traktor
- //if (encoderValue[ENCODER_MIDI_CH][i] > lastEncoderValue[ENCODER_MIDI_CH][i]) {
- //encoderValue[ENCODER_MIDI_CH][i] = 127;
- //} else {
- //encoderValue[ENCODER_MIDI_CH][i] = 0;
- //}
- clipEncoderValue(i, encoderMinVal, encoderMaxVal); // checks if it's greater than the max value or less than the min value
- // Sends the MIDI CC accordingly to the chosen board
- MIDI.sendControlChange(ENCODER_CC_N[i], encoderValue[ENCODER_MIDI_CH][i], ENCODER_MIDI_CH);
- lastEncoderValue[ENCODER_MIDI_CH][i] = encoderValue[ENCODER_MIDI_CH][i];
- }
- }
- }
- ////////////////////////////////////////////
- // checks if it's greater than maximum value or less than then the minimum value
- void clipEncoderValue(int i, int minVal, int maxVal) {
- if (encoderValue[ENCODER_MIDI_CH][i] > maxVal - 1) {
- encoderValue[ENCODER_MIDI_CH][i] = maxVal;
- encoder[i].write(maxVal);
- }
- if (encoderValue[ENCODER_MIDI_CH][i] < minVal + 1) {
- encoderValue[ENCODER_MIDI_CH][i] = minVal;
- encoder[i].write(minVal);
- }
- }
- /* When receiving MIDI from the daw the encoder updates itself and send midi back
- this causes some sort of feedack. This function prevents the encoder to update itself
- unti it stopped receiving midi from the daw.
- */
- void isEncoderMoving() {
- for (int i = 0; i < N_ENCODERS; i++) {
- if (encMoved[i] == true) {
- encPTime[i] = millis(); // Stores the previous time
- }
- encTimer[i] = millis() - encPTime[i]; // Resets the encTimer 11000 - 11000 = 0ms
- if (encTimer[i] < encTIMEOUT) { // If the encTimer is less than the maximum allowed time it means that the encoder is still moving
- encMoving[i] = true;
- encMoved[i] = false;
- }
- else {
- if (encMoving[i] == true) {
- encoder[encoder_n].write(encTempVal);
- encMoving[i] = false;
- }
- }
- }
- }
- ////////////////////////////////////////////
- // checks if it's greater than maximum value or less than then the minimum value
- int clipValue(int in, int minVal, int maxVal) {
- int out;
- minVal++;
- if (in > maxVal) {
- out = maxVal;
- }
- else if (in < minVal) {
- out = minVal - 1;
- }
- else {
- out = in;
- }
- return out;
- }
- //Linear interpolates a value in fromMap to toMap
- int multiMap(int value, int fromMap[], int fromMapSize, int toMap[], int toMapSize)
- {
- //Boundary cases
- if (value <= fromMap[0]) return toMap[0];
- if (value >= fromMap[fromMapSize - 1]) return toMap[toMapSize - 1];
- //Find the fromMap interval that value lies in
- byte fromInterval = 0;
- while (value > fromMap[fromInterval + 1])
- fromInterval++;
- //Find the percentage of the interval that value lies in
- float fromIntervalPercentage = (float)(value - fromMap[fromInterval]) / (fromMap[fromInterval + 1] - fromMap[fromInterval]);
- //Map it to the toMap interval and percentage of that interval
- float toIntervalPercentage = ((fromInterval + fromIntervalPercentage) / (fromMapSize - 1)) * (toMapSize - 1);
- byte toInterval = (byte)toIntervalPercentage;
- toIntervalPercentage = toIntervalPercentage - toInterval;
- //Linear interpolate
- return toMap[toInterval] + toIntervalPercentage * (toMap[toInterval + 1] - toMap[toInterval]);
- }
- void setColor (int vermelho, int verde, int azul) {
- #ifdef COMMON_ANODE
- vermelho = 255 - vermelho;
- verde = 255 - verde;
- azul = 255 - azul;
- #endif
- analogWrite (26, vermelho);
- analogWrite (27, verde);
- analogWrite (28, azul);
- analogWrite (29, vermelho);
- analogWrite (30, verde);
- analogWrite (31, azul);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement