How to Make Volume Control with Digispark
It'll make your life better!
Components and supplies
1
Rotary Encoder with Push-Button
1
DigiSpark
Apps and platforms
1
Arduino IDE
Project description
Code
editingKnob.ino
c_cpp
1// see tutorial at http://learn.adafruit.com/trinket-usb-volume-knob 2 3#include "TrinketHidCombo.h" 4#define turningRight 1 5#define turningLeft 0 6 7 8 9#define PIN_ENCODER_A 2 10#define PIN_ENCODER_B 0 11#define ATTINY_PINx PINB 12#define PIN_ENCODER_SWITCH 1 13#define numberOfStates 4 14 15static uint8_t enc_prev_pos = 0; 16static uint8_t enc_flags = 0; 17static char sw_was_pressed = 0; 18uint8_t state = 3-1; 19bool startup = true; 20const char * stateType[] = { "arrow shift", "media", "premiere pro", "photoshop" }; 21 22//clicking variables 23static long holdTime = 500; 24static long longHoldTime = 700; 25unsigned long buttonTimer = 0; 26unsigned long doubleClickTimer = 0; 27bool checkForDoubleClick = false; 28 29void setup() { 30 // set pins as input with internal pull-up resistors enabled 31 pinMode(PIN_ENCODER_A, INPUT); 32 pinMode(PIN_ENCODER_B, INPUT); 33 digitalWrite(PIN_ENCODER_A, HIGH); 34 digitalWrite(PIN_ENCODER_B, HIGH); 35 36 pinMode(PIN_ENCODER_SWITCH, INPUT); 37 // the switch is active-high, not active-low 38 // since it shares the pin with Trinket's built-in LED 39 // the LED acts as a pull-down resistor 40 digitalWrite(PIN_ENCODER_SWITCH, HIGH); 41 42 TrinketHidCombo.begin(); // start the USB device engine and enumerate 43 44 // get an initial reading on the encoder pins 45 if (digitalRead(PIN_ENCODER_A) == LOW) { 46 enc_prev_pos |= (1 << 0); 47 } 48 if (digitalRead(PIN_ENCODER_B) == LOW) { 49 enc_prev_pos |= (1 << 1); 50 } 51} 52 53void loop() { 54 int8_t enc_action = 0; // 1 or -1 if moved, sign is direction 55 56 // note: for better performance, the code will now use 57 // direct port access techniques 58 // http://www.arduino.cc/en/Reference/PortManipulation 59 uint8_t enc_cur_pos = 0; 60 // read in the encoder state first 61 if (bit_is_clear(ATTINY_PINx, PIN_ENCODER_A)) { 62 enc_cur_pos |= (1 << 0); 63 } 64 if (bit_is_clear(ATTINY_PINx, PIN_ENCODER_B)) { 65 enc_cur_pos |= (1 << 1); 66 } 67 68 // if any rotation at all 69 if (enc_cur_pos != enc_prev_pos) { 70 if (enc_prev_pos == 0x00) { 71 // this is the first edge 72 if (enc_cur_pos == 0x01) { 73 enc_flags |= (1 << 0); 74 } 75 else if (enc_cur_pos == 0x02) { 76 enc_flags |= (1 << 1); 77 } 78 } 79 80 if (enc_cur_pos == 0x03) { 81 // this is when the encoder is in the middle of a "step" 82 enc_flags |= (1 << 4); 83 } 84 else if (enc_cur_pos == 0x00) { 85 // this is the final edge 86 if (enc_prev_pos == 0x02) { 87 enc_flags |= (1 << 2); 88 } 89 else if (enc_prev_pos == 0x01) { 90 enc_flags |= (1 << 3); 91 } 92 93 // check the first and last edge 94 // or maybe one edge is missing, if missing then require the middle state 95 // this will reject bounces and false movements 96 if (bit_is_set(enc_flags, 0) && (bit_is_set(enc_flags, 2) || bit_is_set(enc_flags, 4))) { 97 enc_action = 1; 98 } 99 else if (bit_is_set(enc_flags, 2) && (bit_is_set(enc_flags, 0) || bit_is_set(enc_flags, 4))) { 100 enc_action = 1; 101 } 102 else if (bit_is_set(enc_flags, 1) && (bit_is_set(enc_flags, 3) || bit_is_set(enc_flags, 4))) { 103 enc_action = -1; 104 } 105 else if (bit_is_set(enc_flags, 3) && (bit_is_set(enc_flags, 1) || bit_is_set(enc_flags, 4))) { 106 enc_action = -1; 107 } 108 109 enc_flags = 0; // reset for next time 110 } 111 } 112 113 enc_prev_pos = enc_cur_pos; 114 115 if (enc_action > 0) turnAction(turningRight); 116 else if (enc_action < 0) turnAction(turningLeft); 117 118 119 if (bit_is_set(ATTINY_PINx, PIN_ENCODER_SWITCH)) { 120 if (sw_was_pressed == 0) {// only on initial press, so the keystroke is not repeated while the button is held down 121 122 } 123 sw_was_pressed = 1; 124 } 125 else { 126 if (sw_was_pressed != 0) { 127 buttonTimer = millis(); 128 while (!digitalRead(PIN_ENCODER_SWITCH)); 129 if (millis() - buttonTimer > longHoldTime) { 130 state++; 131 if (state > numberOfStates - 1)state = 0; //cycle modes (n) in n-1 132 printOut(stateType[state]); 133 } 134 else { 135 if (!checkForDoubleClick) { 136 checkForDoubleClick = true; 137 doubleClickTimer = millis(); 138 } 139 else if (millis() - doubleClickTimer < holdTime && checkForDoubleClick) { 140 clickAction(true); 141 checkForDoubleClick = false; 142 doubleClickTimer = 0; 143 } 144 } 145 delay(5); // debounce delay 146 } 147 sw_was_pressed = 0; 148 } 149 if (checkForDoubleClick) { 150 if (millis() - doubleClickTimer > holdTime) { 151 clickAction(false); 152 checkForDoubleClick = false; 153 doubleClickTimer = 0; 154 } 155 } 156 TrinketHidCombo.poll(); // check if USB needs anything done 157} 158 159 160void printOut(const char* c) { 161 TrinketHidCombo.pressKey(KEYCODE_MOD_LEFT_GUI, KEYCODE_R); 162 TrinketHidCombo.pressKey(0, 0); 163 delay(200); 164 TrinketHidCombo.print(c); 165 delay(500); 166 TrinketHidCombo.pressKey(0,KEYCODE_ESC); 167 TrinketHidCombo.pressKey(0, 0); 168 delay(5); // debounce delay 169} 170 171
Downloadable files
bandicam_2019-06-12_10-32-49-255_JxXjhGtz7S.jpg
bandicam_2019-06-12_10-32-49-255_JxXjhGtz7S.jpg

bandicam_2019-06-12_10-32-49-255_JxXjhGtz7S.jpg
bandicam_2019-06-12_10-32-49-255_JxXjhGtz7S.jpg

Comments
Only logged in users can leave comments