luseira
Published © CC BY-NC

CL-12 Expansion

USB controller for 8 series Sound Devices mixer/recorders

IntermediateShowcase (no instructions)83
CL-12 Expansion

Things used in this project

Hardware components

Pro Micro - 5V/16MHz
SparkFun Pro Micro - 5V/16MHz
×1
Rotary Encoder with Push-Button
Rotary Encoder with Push-Button
I used the KY-040 rotary encoder
×2
Tactile Switch, Top Actuated
Tactile Switch, Top Actuated
×9
3 mm LED: Green
3 mm LED: Green
I only had a high brightness green LED, but it's way too bright
×1
LED, Blue
LED, Blue
I used a 3mm blue LED
×1
Resistor 1k ohm
Resistor 1k ohm
for the blue LED
×1
Resistor 10k ohm
Resistor 10k ohm
for the green LED, high brightness (resistor value can be even higher)
×1

Story

Read more

Schematics

Main board

This is just the way I made it. You can create your own design.

Code

CL-12 Expansion

C/C++
To be used with Arduino Pro Micro boards
/*

  DISCLAIMER:

  This project is licensed under Creative Commons CC BY-NC 4.0
  https://creativecommons.org/licenses/by-nc/4.0/

  You are free to:

  Share — copy and redistribute the material in any medium or format
  Adapt — remix, transform, and build upon the material

  *You may NOT use the material for commercial purposes*

  You must give appropriate credit and provide a link to the license.
  
  It also utilizes libraries from third party developers:

  >> NicoHood Arduino HID Project:

  Copyright (c) 2014-2015 NicoHood
  https://github.com/NicoHood/HID/wiki/Keyboard-API#boot-keyboard

  >> Buxtronix Arduino Rotary:

  Copyright 2011 Ben Buxton. Licenced under the GNU GPL Version 3
  https://github.com/buxtronix/arduino/tree/master/libraries/Rotary

  ---------------------------------------------------------------------------

   How the buttons and encoders are connected to the Arduino Pro Micro board:    

   Encoder 1:

   GND --> GND
    +  --> 5V
   SW1 --> 7
   DT  --> 0
   CLK --> 1

   Encoder 2:

   GND --> GND
    +  --> 5V
   SW2 --> 8
   DT  --> 3
   CLK --> 2

   Button 1 = 9;
   Button 2 = 21;
   Button 3 = 20;
   Button 4 = 19;
   Button 5 = 18;
   Button 6 = 15;
   Button 7 = 14;
   Button 8 = 16;
   Button 9 = 10;
   
  Green LED (10k resistor) = 5;
  Blue LED (1k resistor) = 6;

*/

// includes third party libraries
#include <HID-Project.h>
#include <Rotary.h>

Rotary encoder1 = Rotary(1, 0); //CLK, DATA
Rotary encoder2 = Rotary(2, 3); //CLK, DATA

// encoder 1 switch
int botaoEnc1 = 7;
int statusBotaoEnc1 = HIGH;

// encoder 2 switch
int botaoEnc2 = 8;
int statusBotaoEnc2 = HIGH;

//leds
int ledAzul = 5;   // green LED
int ledVerde = 6;  // blue LED

// buttons
int botao1 = 9;
int botao2 = 21;
int botao3 = 20;
int botao4 = 19;
int botao5 = 18;
int botao6 = 15;
int botao7 = 14;
int botao8 = 16;
int botao9 = 10;
int statusBotao1 = HIGH;
int statusBotao2 = HIGH;
int statusBotao3 = HIGH;
int statusBotao4 = HIGH;
int statusBotao5 = HIGH;
int statusBotao6 = HIGH;
int statusBotao7 = HIGH;
int statusBotao8 = HIGH;

// button 9 variables (change mode)
int statusBotao9 = HIGH;           // the current leituraBotao9 from the input pin
int ultimoStatusBotao9 = HIGH;     // the previous leituraBotao9 from the input pin
unsigned long timerReset = 0;      // the last time the output pin was toggled
unsigned long debounceDelay = 50;  // the debounce time; increase if the output flickers
unsigned long previousMillis = 0;  // will store last time LED was updated
const long interval = 600;         // interval at which to blink (milliseconds)

// sets the initial mode (1 = EQ, 2 = general control)
int modo = 2;

int counter = 0;

// SETUP
void setup() {
  Serial.begin (9600);  // starts the serial monitor and set the baud rate

  // attaches the interrupts to the encoders
  attachInterrupt(digitalPinToInterrupt(1), rotate1, CHANGE);
  attachInterrupt(digitalPinToInterrupt(0), rotate1, CHANGE);
  attachInterrupt(digitalPinToInterrupt(2), rotate2, CHANGE);
  attachInterrupt(digitalPinToInterrupt(3), rotate2, CHANGE);

  // sets the pin modes and pull up resistors
  pinMode (botaoEnc1, INPUT_PULLUP);
  pinMode (botaoEnc2, INPUT_PULLUP);
  pinMode (botao1, INPUT_PULLUP);
  pinMode (botao2, INPUT_PULLUP);
  pinMode (botao3, INPUT_PULLUP);
  pinMode (botao4, INPUT_PULLUP);
  pinMode (botao5, INPUT_PULLUP);
  pinMode (botao6, INPUT_PULLUP);
  pinMode (botao7, INPUT_PULLUP);
  pinMode (botao8, INPUT_PULLUP);
  pinMode (botao9, INPUT_PULLUP);


  //LEDS
  pinMode (ledAzul, OUTPUT);
  pinMode (ledVerde, OUTPUT);

  // inicia o controle com o BootKeyboard
  BootKeyboard.begin();

} // END OF SETUP

//LOOP

void loop() {

  // light up the LEDS to indicate the current mode. I'm using PWM to match the LEDs brightness

  if (modo == 1) {
    analogWrite(ledAzul, 50); // low brightness LED, 1kΩ resistor
    analogWrite(ledVerde, 0);
  }

  if (modo == 2) {
    analogWrite(ledAzul, 0);
    analogWrite(ledVerde, 3); // high brightness LED, 10kΩ resistor
  }

  // reads button 9 and sets the mode:
  
  int leituraBotao9 = digitalRead(botao9);

  if (leituraBotao9 != ultimoStatusBotao9) {
    timerReset = millis();
  }

  if ((millis() - timerReset) > debounceDelay) {

    if (leituraBotao9 != statusBotao9) {
      statusBotao9 = leituraBotao9;

      if (statusBotao9 == LOW) {
        modo++;

        if (modo == 3 ) {
          modo = 1;
        }

        if (modo == 1) {
          Serial.println("MODE 1");
        }

        if (modo == 2) {
          Serial.println("MODE 2");
        }
      }
    }
  }

  ultimoStatusBotao9 = leituraBotao9; // resets button 9 last status

  // once the mode is set, what each button does:

  // MODE 1: EQUALIZER

  if (modo == 1) {

    // ENCODER 1 SWITCH
    statusBotaoEnc1 = digitalRead(botaoEnc1);    

    if (statusBotaoEnc1 == LOW) {
      BootKeyboard.press(KEY_F6);
      BootKeyboard.releaseAll();
      Serial.println("MODE 1: F6 = IN/BYPASS");
      // delay para debounce
      delay(200);
    }

    // ENCODER 2 SWITCH
    statusBotaoEnc2 = digitalRead(botaoEnc2);   

    if (statusBotaoEnc2 == LOW) {
      BootKeyboard.press(KEY_F9);
      BootKeyboard.releaseAll();
      Serial.println("MODE 1: F9 = Q");
      // delay para debounce
      delay(200);
    }


    // BUTTON 1 (EQ)
    statusBotao1 = digitalRead(botao1);    

    // if button 1 is pressed:
    if (statusBotao1 == LOW) {
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();

      Serial.println("MODE 1: Open EQ");
      // debounce delay
      delay(200);
    }

    // BUTTON 2 (Pre/Post/Off)
    statusBotao2 = digitalRead(botao2);    

    // if button 2 is pressed:
    if (statusBotao2 == LOW) {
      BootKeyboard.press(KEY_F5);
      BootKeyboard.releaseAll();
      Serial.println("MODE 1: Pre/Post/Off");
      // debounce delay
      delay(200);
    }

    // BUTTON 3 (HIGH)
    statusBotao3 = digitalRead(botao3);   

    // if button 3 is pressed:
    if (statusBotao3 == LOW) {
      BootKeyboard.press(KEY_F8);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F8);
      BootKeyboard.releaseAll();
      Serial.println("MODE 1: High Band");
      // debounce delay
      delay(200);
    }

    // BUTTON 4 (MID)
    statusBotao4 = digitalRead(botao4);   

    // if button 4 is pressed:
    if (statusBotao4 == LOW) {
      BootKeyboard.press(KEY_F7);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F7);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F8);
      BootKeyboard.releaseAll();
      Serial.println("MODE 1: Mid Band");
      //debounce delay
      delay(200);
    }

    // BUTTON 5 (LOW)
    statusBotao5 = digitalRead(botao5);   

    // if button 5 is pressed:
    if (statusBotao5 == LOW) {
      BootKeyboard.press(KEY_F7);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F7);
      BootKeyboard.releaseAll();
      Serial.println("MODE 1: Low Band");
      // debounce delay
      delay(200);
    }

    // BUTTON 6 (Peak/Shelf)
    statusBotao6 = digitalRead(botao6);    

    // if button 6 is pressed:
    if (statusBotao6 == LOW) {
      BootKeyboard.press(KEY_F10);
      BootKeyboard.releaseAll();
      Serial.println("MODE 1: Peak/Shelf");
      // debounce delay
      delay(200);
    }

    // BUTTON 7 (Not mapped in MODE 1)

    // BUTTON 8 (Exit)
    statusBotao8 = digitalRead(botao8);   

    // if button 8 is pressed:
    if (statusBotao8 == LOW) {
      BootKeyboard.press(KEY_F1);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_ESC);
      BootKeyboard.releaseAll();
      Serial.println("Exit");
      // // BUTTON 6 (Peak/Shelf)
      delay(200);
    }


  } //END OF MODE 1

  // MODE 2: GENERAL CONTROL

  if (modo == 2) {

    // ENCODER 1 SWITCH
    statusBotaoEnc1 = digitalRead(botaoEnc1);   

    // if encoder 2 switch is pressed:
    if (statusBotaoEnc1 == LOW) {
      BootKeyboard.press(KEY_RIGHT_CTRL);
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();
      Serial.println("MODE 2: CTRL + ENTER");
      // debounce delay
      delay(200);
    }

    // ENCODER 2 SWITCH
    statusBotaoEnc2 = digitalRead(botaoEnc2);    

    // if encoder 2 switch is pressed:
    if (statusBotaoEnc2 == LOW) {
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();
      Serial.println("MODO 2: ENTER");
      // debounce delay
      delay(200);
    }


    // BUTTON 1 (MENU)

    statusBotao1 = digitalRead(botao1);    

    // if button 1 is pressed:
    if (statusBotao1 == LOW) {
      BootKeyboard.press(KEY_F1);
      BootKeyboard.releaseAll();
      Serial.println("MODE 2: MENU");
      // debounce delay
      delay(200);
    }

    // BUTTON 2 (ESC)
    statusBotao2 = digitalRead(botao2);    

    // if button 2 is pressed:
    if (statusBotao2 == LOW) {
      BootKeyboard.press(KEY_ESC);
      BootKeyboard.releaseAll();
      Serial.println("MODE 2: ESC");
      // debounce delay
      delay(200);
    }

    // BUTTON 3 (EDIT LAST TAKE NOTES)
    statusBotao3 = digitalRead(botao3);    

    // if button 3 is pressed:
    if (statusBotao3 == LOW) {
      BootKeyboard.press(KEY_F2);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();

      Serial.println("MODE 2: EDIT LAST TAKE NOTES");
      // debounce delay
      delay(200);
    }

    // BUTTON 4 (EDIT SCENE NAME)
    statusBotao4 = digitalRead(botao4);    

     // if button 4 is pressed:
    if (statusBotao4 == LOW) {
      BootKeyboard.press(KEY_F2);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F5);

      BootKeyboard.releaseAll();
      Serial.println("MODE 2: EDIT SCENE NAME");
      // debounce delay
      delay(200);
    }

    // BUTTON 5 (RENAME AS "REHEARSAL")
    statusBotao5 = digitalRead(botao5);   

    // if button 1 is pressed:
    if (statusBotao5 == LOW) {

      BootKeyboard.press(KEY_F2);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();
      BootKeyboard.print("ENSAIO");
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_RETURN);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_ESC);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_ESC);
      BootKeyboard.releaseAll();

      Serial.println("MODE 2: RENAME LAST TAKE AS REHEARSAL");
      // debounce delay
      delay(200);;
    }

    // BUTTON 6 (BUSES) *only works when in Meter View 1-8
    statusBotao6 = digitalRead(botao6);    

   // if button 6 is pressed:
    if (statusBotao6 == LOW) {
      BootKeyboard.press(KEY_F12);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      Serial.println("MODE 2: BUS VIEW");
      // debounce delay
      delay(200);
    }

    // BOTAO 7 (OUPUTS) *only works when in Meter View 1-8
    statusBotao7 = digitalRead(botao7);    

    // if button 7 is pressed:
    if (statusBotao7 == LOW) {
      BootKeyboard.press(KEY_F12);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();
      BootKeyboard.press(KEY_F3);
      BootKeyboard.releaseAll();

      Serial.println("MODE 2: OUTPUT VIEW");
      // debounce delay
      delay(200);
    }


    // BUTTON8 (Exit)
    statusBotao8 = digitalRead(botao8);   

    // if button 6 is pressed:
    if (statusBotao8 == LOW) {
      BootKeyboard.press(KEY_F12);
      BootKeyboard.releaseAll();
      Serial.println("Exit");
      // debounce delay
      delay(200);
    }


  }// END OF MODE 2


} // END OF LOOP

// ENCODER 1

// rotate is called anytime the rotary inputs change state.
void rotate1() {
  
   // ROTARY ENCODER 1, MODE 1
  if (modo == 1) {

    unsigned char result = encoder1.process();
    if (result == DIR_CW) {
      counter++;
      Serial.println(counter);
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
    } else if (result == DIR_CCW) {
      counter--;
      Serial.println(counter);
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
    }
  }

  // ROTARY ENCODER 1, MODE 2
  if (modo == 2) {

    unsigned char result = encoder1.process();
    if (result == DIR_CW) {
      counter--;
      Serial.println(counter);
      BootKeyboard.press(KEY_RIGHT_CTRL);
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();
    } else if (result == DIR_CCW) {
      counter++;
      Serial.println(counter);
      BootKeyboard.press(KEY_RIGHT_CTRL);
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
    }
  }
} // END OF ROTATE 1


// ENCODER 2

// rotate is called anytime the rotary inputs change state.
void rotate2() {

  // ENCODER 2, MODE 1
  if (modo == 1) {

    unsigned char result = encoder2.process();
    if (result == DIR_CW) {
      counter++;
      Serial.println(counter);
      BootKeyboard.press(KEY_RIGHT_CTRL);
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();         
    } else if (result == DIR_CCW) {
      counter--;
      Serial.println(counter);
      BootKeyboard.press(KEY_RIGHT_CTRL);
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();
    }
  }
  // ENCODER 2, MODE 2
  if (modo == 2) {

    unsigned char result = encoder2.process();
    if (result == DIR_CW) {
      counter--;
      Serial.println(counter);
      BootKeyboard.press(KEY_UP_ARROW);
      BootKeyboard.releaseAll();          
    } else if (result == DIR_CCW) {
      counter++;
      Serial.println(counter);
      BootKeyboard.press(KEY_DOWN_ARROW);
      BootKeyboard.releaseAll();

    }
  }
} // END OF ROTATE 2

Credits

luseira
1 project • 1 follower
Contact

Comments

Please log in or sign up to comment.