Macro keyboard

Download project arduino files [main_GFX.ino.zip ]
		int numdigits(int i){
		  char str[20];
		  sprintf(str,"%d",i);
		  return(strlen(str));
		}
		int volumeChange(int toValue, int fromValue){
		  if(toValue == 1){
		    Consumer.write(MEDIA_VOLUME_UP);
		    toValue = fromValue + volScale;
		  }else{
		    Consumer.write(MEDIA_VOLUME_DOWN);
		    toValue = fromValue - volScale;
		  }
		  // 1 is increase, 0 is decrease
		
		  if(toValue > 100){
		    toValue = 100;
		  }else if(toValue < 0){
		    toValue = 0;
		  }
		  return(toValue);
		
		}
		int fillAmbient(int startled, int endled){
		  int pwm_val = 20*(exp(-(pow(((timer/smoothness_pts)-beta)/gamma,2.0))/2.0));
		  pixels.fill(pixels.Color(pwm_val,pwm_val,pwm_val),startled,endled);
		  //pixels.fill(pixels.Color(random(20,100),random(20,100),random(20,100)),startled,endled);
		}
		int setRing(int volSet){
		  int volLedsOn = volSet / 10;   // 84 -> 8
		  int volRemain = volSet - (volLedsOn * 10); // 84 -> 84 - (8 * 10) = 4
		  int offLeds = 0;
		  if(volSet < 100){
		    for(int i = 8;i < 18;i++){
		      if(i < (volLedsOn + 7) ){ // Led full on
		        pixels.setPixelColor(i, pixels.Color(0,50,0));
		      }else if(i == (volLedsOn + 7)){ // Led dim (volRemain)
		        if(volRemain != 0){
		          pixels.setPixelColor(i, pixels.Color(0,volRemain * 5,0));
		        }
		      }else{ // Led off
		        //pixels.setPixelColor(i, pixels.Color(10,0,0));
		        offLeds++;
		        //pixels.setPixelColor(17, pixels.Color(10,0,0));
		      }
		    }
		  }else{
		    pixels.fill(pixels.Color(0,50,0),8,17);
		    offLeds = 0;
		  }
		  return offLeds;
		}
		
		int drawScreen(int active,int muted){
		  for(int i=0;i<8;i++){
		    if(i == active){
		      display.writeFillRect(buttonLocs[i][0],buttonLocs[i][1],32,32,BLACK);
		      display.writeFillRect(buttonLocs[i][0] + 1,buttonLocs[i][1] + 1,30,30,WHITE);
		      display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,empty,24,24,INVERSE);
		      /*display.setTextColor(BLACK);
		      display.setCursor(buttonLocs[i][0]+2,buttonLocs[i][1]+2);
		      display.println(keyBinds[i]);*/
		    }else{
		      display.writeFillRect(buttonLocs[i][0],buttonLocs[i][1],32,32,WHITE);
		      display.writeFillRect(buttonLocs[i][0] + 1,buttonLocs[i][1] + 1,30,30,BLACK);
		      switch (i){
		        case 0:
		          display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,play,24,24,WHITE);
		        break;
		        case 1:
		          display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,folder,24,24,WHITE);
		        break;
		        case 2:
		          display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,game,24,24,WHITE);
		        break;
		        case 3:
		          display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,web,24,24,WHITE);
		        break;
		        case 4:
		          display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,record,24,24,WHITE);
		        break;
		        case 5:
		          display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,code,24,24,WHITE);
		        break;
		        case 6:
		          display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,next,24,24,WHITE);
		        break;
		        case 7:
		          display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,prev,24,24,WHITE);
		        break;
		
		        default:
		          display.drawBitmap(buttonLocs[i][0]+4,buttonLocs[i][1]+4,empty,24,24,WHITE);
		        break;
		      }
		    }
		  }
		  if(active == 8){
		    display.fillCircle(volPos[0],volPos[1],volPos[2],BLACK);
		    display.fillCircle(volPos[0],volPos[1],volPos[2]-2,WHITE);
		    if(muted != 0){ // is muted
		      display.drawBitmap(volPos[3],volPos[4],speaker,volPos[5],volPos[6],INVERSE);
		    }else{
		      display.drawBitmap(volPos[3],volPos[4],mute,volPos[5],volPos[6],INVERSE);
		    }
		  }else{
		    display.fillCircle(volPos[0],volPos[1],volPos[2],WHITE);
		    display.fillCircle(volPos[0],volPos[1],volPos[2]-2,BLACK);
		    if(muted != 0){ // is muted
		      display.drawBitmap(volPos[3],volPos[4],speaker,volPos[5],volPos[6],WHITE);
		    }else{
		      display.drawBitmap(volPos[3],volPos[4],mute,volPos[5],volPos[6],WHITE);
		    }
		  }
		  display.display();
		}
		
		
		// http://grauonline.de/pushbuttonwww/keyboard.html
		void executeCommand(int i){
		  switch (i){
		    case 0:
		      // Play/pause
		      Consumer.write(MEDIA_PLAY_PAUSE);
		    break;
		    case 1:
		      // Open explorer
		      Consumer.write(CONSUMER_EXPLORER);
		    break;
		    case 2:
		      // Steam
		      Keyboard.press(KEY_LEFT_CTRL);
		      Keyboard.press(KEY_LEFT_ALT);
		      Keyboard.press(51);
		      delay(keyPressDelay);
		      Keyboard.releaseAll();
		    break;
		    case 3:
		      // Browser
		      Consumer.write(HID_CONSUMER_AL_INTERNET_BROWSER);
		      /*Keyboard.press(KEY_LEFT_CTRL);
		      Keyboard.press(KEY_LEFT_ALT);
		      Keyboard.press(52);
		      delay(keyPressDelay);
		      Keyboard.releaseAll();*/
		    break;
		    case 4:
		      // record (radeon) ctrl shift r
		      Keyboard.press(KEY_LEFT_CTRL);
		      Keyboard.press(KEY_LEFT_SHIFT);
		      Keyboard.press('R');
		      delay(keyPressDelay);
		      Keyboard.releaseAll();
		    break;
		    case 5:
		      // Code
		      Keyboard.press(KEY_LEFT_CTRL);
		      Keyboard.press(KEY_LEFT_ALT);
		      Keyboard.press(53);
		      delay(keyPressDelay);
		      Keyboard.releaseAll();
		    break;
		    case 6:
		      // Next
		      Consumer.write(MEDIA_NEXT);
		    break;
		    case 7:
		      // Previous
		      Consumer.write(MEDIA_PREVIOUS);
		    break;
		
		    default:
		      // Nothing
		    break;
		  }
		}
	
		const unsigned char play [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xde, 0x00, 0x00, 0xc7,
		  0x80, 0x00, 0xc3, 0xc0, 0x00, 0xc3, 0xc0, 0x00, 0xc7, 0x80, 0x00, 0xde, 0x00, 0x00, 0xfc, 0x00,
		  0x00, 0xf0, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		
		const unsigned char pause [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
		  0xc3, 0xc0, 0x03, 0xc3, 0xc0, 0x03, 0xc3, 0xc0, 0x03, 0xc3, 0xc0, 0x03, 0xc3, 0xc0, 0x03, 0xc3,
		  0xc0, 0x03, 0xc3, 0xc0, 0x03, 0xc3, 0xc0, 0x03, 0xc3, 0xc0, 0x03, 0xc3, 0xc0, 0x03, 0xc3, 0xc0,
		  0x03, 0xc3, 0xc0, 0x03, 0xc3, 0xc0, 0x03, 0xc3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		
		const unsigned char web [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x01, 0xff, 0x80, 0x07, 0xff, 0xc0, 0x0f,
		  0xfe, 0xe0, 0x0f, 0xfc, 0x30, 0x1f, 0xe0, 0x38, 0x1f, 0xe0, 0x18, 0x3f, 0xc0, 0x1c, 0x3f, 0x00,
		  0x0c, 0x37, 0x00, 0x0c, 0x33, 0xfc, 0x0c, 0x31, 0xfe, 0x0c, 0x30, 0xfe, 0x0c, 0x18, 0x7e, 0x18,
		  0x18, 0x7f, 0x98, 0x0c, 0x3f, 0xf0, 0x0e, 0x1f, 0xf0, 0x07, 0x9f, 0xe0, 0x01, 0xff, 0x80, 0x00,
		  0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		
		const unsigned char speaker [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x80, 0x00,
		  0x13, 0xc0, 0x00, 0x30, 0xe0, 0x00, 0x70, 0x70, 0x00, 0xf0, 0x30, 0x1f, 0xb3, 0x38, 0x1f, 0x33,
		  0x18, 0x18, 0x33, 0x18, 0x18, 0x33, 0x18, 0x1f, 0x33, 0x18, 0x1f, 0xb3, 0x38, 0x01, 0xf2, 0x30,
		  0x00, 0xf0, 0x70, 0x00, 0x70, 0xe0, 0x00, 0x33, 0xc0, 0x00, 0x13, 0x80, 0x00, 0x02, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		
		const unsigned char mute [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x1c, 0x13, 0x80, 0x0e,
		  0x13, 0xc0, 0x07, 0x10, 0xe0, 0x03, 0x80, 0x70, 0x01, 0xc2, 0x30, 0x1f, 0xe3, 0x38, 0x1f, 0x71,
		  0x18, 0x18, 0x38, 0x18, 0x18, 0x3c, 0x18, 0x1f, 0x3e, 0x18, 0x1f, 0xb7, 0x18, 0x01, 0xf3, 0x80,
		  0x00, 0xf1, 0xc0, 0x00, 0x70, 0xe0, 0x00, 0x33, 0xf0, 0x00, 0x13, 0xb8, 0x00, 0x02, 0x10, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		
		const unsigned char empty [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		const unsigned char folder [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x3f,
		  0xf0, 0x00, 0x30, 0x3f, 0xf8, 0x30, 0x1f, 0xfc, 0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c, 0x30, 0x00,
		  0x0c, 0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c,
		  0x30, 0x00, 0x0c, 0x30, 0x00, 0x0c, 0x3f, 0xff, 0xfc, 0x1f, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		const unsigned char game [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
		  0xff, 0xc0, 0x0f, 0xff, 0xf0, 0x0c, 0x00, 0x70, 0x1c, 0x83, 0x30, 0x18, 0x83, 0x38, 0x1b, 0xe0,
		  0x18, 0x18, 0x80, 0xd8, 0x18, 0x80, 0xd8, 0x18, 0x00, 0x18, 0x18, 0xff, 0x18, 0x39, 0xff, 0x98,
		  0x33, 0x81, 0xd8, 0x1f, 0x00, 0xf8, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		const unsigned char minecraft [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe1, 0xf8, 0x00, 0x20, 0x0c, 0x08, 0x71, 0x0c, 0x0f,
		  0xff, 0xce, 0x00, 0x38, 0x9e, 0x10, 0x3c, 0xdf, 0x10, 0x00, 0x1e, 0x10, 0x00, 0x1e, 0x38, 0x00,
		  0x1e, 0x2d, 0x8c, 0x3e, 0x0b, 0x88, 0x3e, 0x4f, 0x98, 0x3c, 0x43, 0xf8, 0x3c, 0x7f, 0xf8, 0x7c,
		  0x7f, 0xff, 0xfc, 0x3f, 0xff, 0xfc, 0x1f, 0xe3, 0xf8, 0x0f, 0xe1, 0xf8, 0x07, 0xc1, 0xf8, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		const unsigned char next [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x02, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x80, 0xc0, 0x03, 0xe0, 0xc0, 0x03, 0x70,
		  0xc0, 0x03, 0x3c, 0xc0, 0x03, 0x3c, 0xc0, 0x03, 0x70, 0xc0, 0x03, 0xe0, 0xc0, 0x03, 0x80, 0xc0,
		  0x03, 0x00, 0xc0, 0x02, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		const unsigned char prev [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x03, 0x00, 0x40, 0x03, 0x00, 0xc0, 0x03, 0x01, 0xc0, 0x03, 0x07, 0xc0, 0x03, 0x0e,
		  0xc0, 0x03, 0x3c, 0xc0, 0x03, 0x3c, 0xc0, 0x03, 0x0e, 0xc0, 0x03, 0x07, 0xc0, 0x03, 0x01, 0xc0,
		  0x03, 0x00, 0xc0, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		const unsigned char code [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x81, 0x80, 0x03, 0x00, 0xc0, 0x06, 0x00, 0x60, 0x0c, 0x00,
		  0x30, 0x18, 0x00, 0x18, 0x18, 0x00, 0x18, 0x0c, 0x00, 0x30, 0x06, 0x00, 0x60, 0x03, 0x00, 0xc0,
		  0x01, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
		const unsigned char record [] PROGMEM = {
		  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x01, 0xff, 0x80, 0x03, 0x85, 0xc0, 0x06,
		  0x08, 0x60, 0x0c, 0x08, 0x30, 0x1a, 0x10, 0x18, 0x19, 0x10, 0x18, 0x31, 0x3f, 0xfc, 0x30, 0xbc,
		  0x0c, 0x30, 0xfe, 0x0c, 0x30, 0x7f, 0x0c, 0x30, 0x3f, 0x0c, 0x3f, 0xfc, 0x8c, 0x18, 0x08, 0x98,
		  0x18, 0x08, 0x58, 0x0c, 0x10, 0x30, 0x06, 0x10, 0x60, 0x03, 0xa1, 0xc0, 0x01, 0xff, 0x80, 0x00,
		  0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
		};
	
		// Libraries
		  #include <Adafruit_SSD1306.h>
		  #include <Adafruit_GFX.h>
		  #include <Wire.h>
		  #include <math.h>
		  #include <SPI.h>
		  #include <HID-Project.h>
		  #include <Adafruit_NeoPixel.h>
		  #include <Pin.h>
		
		// Custom files
		  #include "icons.h"
		  #include "variables.h"
		
		
		// Define LEDS
		  Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM, PIN, NEO_GRB + NEO_KHZ800);
		  Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, RST_PIN);
		// Define functions AFTER variables
		  #include "functions.h"
		
		int drawScreen(int active,int muted = 0);
		
		void setup(){
		
		  // Keyboard begin
		    Consumer.begin();
		    Keyboard.begin();
		    pixels.begin();
		    pixels.clear();
		    pixels.fill(pixels.Color(10,0,0),0,17);
		    ambLeds = setRing(volSet);
		
		  // Display begin, settings and draw menu
		    display.begin(SSD1306_SWITCHCAPVCC, I2C_ADDRESS);
		    display.setTextColor(WHITE);
		    display.setFont();
		    display.setTextSize(1);
		    delay(100);
		    display.clearDisplay();
		    //drawScreen(-1,0);
		
		  // Set pins
		    for (int i = 0; i < keyPinsSize; i++) { // Iterate over array of Pins
		      keyPins[i].setInputPullupOn(); // Set Pin to input
		    }
		    pinMode(enc_sw, INPUT_PULLUP);
		
		  // Set encoder base values
		    enc_base = digitalRead(enc_sw);
		    encclklast = digitalRead(enc_clk);
		
		    delay(100);
		}
		
		void loop(){
		  // SET ALL LEDS
		  fillAmbient(0,8);
		  fillAmbient(NUM-ambLeds,NUM - 1);
		
		
		  // BUTTON PRESS ACTION
		  for(int i = 0; i < keyPinsSize; i++){
		    while(keyPins[i].getValue() == 1){
		      aVal = digitalRead(enc_clk);
		
		      // check if wheel is rotating
		      if(aVal != encclklast){
		        dontPress = 1;
		        if(digitalRead(enc_dt) != aVal){ // Means pin A Changed first - We're Rotating Clockwise
		          encoderPosCount ++;
		          bCW = true;
		          if((encoderPosCount & 0x01) == 0){  // Check if value is even (full click)
		            // CHANGE FUNCTION CW
		          }
		        }else{ // Otherwise B changed first and we're moving CCW
		          bCW = false;
		          encoderPosCount--;
		          if((encoderPosCount & 0x01) == 0){  // Check if value is even (full click)
		            // CHANGE FUNCTION CCW
		          }
		        }
		      }
		      encclklast = aVal;
		      if(firstExec == 0){
		        pixels.setPixelColor(ledMatch[i], pixels.Color(0,10,0));
		        pixels.show();
		        drawScreen(i,volSet);
		        sendOnRelease = i;
		
		        //sendOnRelease = keyStrokes[i];
		      }
		      firstExec = 1;
		    }
		    // key released
		    if(firstExec == 1 ){
		      if(dontPress != 1){
		        executeCommand(sendOnRelease);
		        sendOnRelease = -1;
		        firstExec = 0;
		      }else{
		        //function changed
		      }
		      dontPress = 0;
		      sendOnRelease = -1;
		      firstExec = 0;
		      drawScreen(-1,volSet);
		    }
		  }
		
		
		
		  // MUTE SWITCH IS PRESSD
		  while(digitalRead(enc_sw) != enc_base){
		    if(firstExec == 0){
		      sendOnRelease = MEDIA_VOLUME_MUTE;
		      //display mute img
		      drawScreen(8,1);
		    }
		    firstExec = 1;
		  }
		  if(firstExec == 1 ){
		    Consumer.write(sendOnRelease);
		    if(volSet != 0){ // is to be muted
		      mutedVol = volSet;
		      volSet = 0;
		
		    }else{
		      volSet = mutedVol;
		      mutedVol = 0;
		    }
		    ambLeds = setRing(volSet);
		    sendOnRelease = -1;
		    firstExec = 0;
		    drawScreen(-1,volSet);
		  }
		  /*
		   * WHEEL IS BEING ROTATED
		   */
		  aVal = digitalRead(enc_clk);
		  if(aVal != encclklast){
		    if(mutedVol == 0){
		      // Update ring LEDS
		      ambLeds = setRing(volSet);
		      if(digitalRead(enc_dt) != aVal){ // Means pin A Changed first - We're Rotating Clockwise
		        encoderPosCount ++;
		        bCW = true;
		        if((encoderPosCount & 0x01) == 0){
		          /*
		           * WHEEL ROTATING CW
		           */
		          encValue++;
		          newVolSet = 1;
		          volSet = volumeChange(newVolSet, volSet);
		        }
		      }else{ // Otherwise B changed first and we're moving CCW
		        bCW = false;
		        encoderPosCount--;
		        if((encoderPosCount & 0x01) == 0){ // Check if value is even
		          /*
		           * WHEEL ROTATING CCW
		           */
		          encValue--;
		          newVolSet = 0;
		          volSet = volumeChange(newVolSet, volSet);
		        }// Check if value is even
		      }
		    }
		  }
		
		  // RESET VALUES
		  newVolSet = 0;
		  encclklast = aVal;
		
		  // SHOW PIXELS
		  pixels.show();
		
		  // SET TIMERS AT END OF LOOP
		  subTime++;
		  if(subTime > 20){
		    subTime = 0;
		    timer = timer + 1;
		  }
		  if(timer > timerMax){ timer = timerOffset; }
		
		
		}
	
		// Keyboard system
		  // Pins
		    #define k_one 4
		    #define k_two 5
		    #define k_three 16
		    #define k_four 10
		    #define k_five 8
		    #define k_six 9
		    #define k_seven 6
		    #define k_eight 7
		
		    int sendOnRelease = -1;
		    Pin keyPins[] = {k_one,k_two,k_three,k_four,k_five,k_six,k_seven,k_eight};
		    int keyPinsSize = sizeof(keyPins) / sizeof(Pin);
		    // Set keyboard layout
		      //  1 2 8 7
		      //  3 4 6 5
		    String keyBinds[] = {"1","2","3","4","8","7","6","5"};
		    int buttonLocs[8][2] = {{0,0},{32,0},{0,32},{32,32},{96,32},{64,32},{96,0},{64,0}};
		
		// Leds
		    #define PIN 14
		    #define NUM 18
		    #define BRIGHT 50
		    #define DELAYVAL 100
		    #define loopTime 100 // animations are looped every x milliseconds
		    int ledMatch[] = {1,0,2,3,6,7,5,4};
		
		    // Ambient lighting settings
		    float smoothness_pts = 200;//larger=slower change in brightness
		    float gamma = 0.14; // affects the width of peak (more or less darkness)
		    float beta = 0.5; // shifts the gaussian to be symmetric
		    int timerOffset = 60;
		    int timer = timerOffset;
		    int timerMax = smoothness_pts - timerOffset;
		    int ambLeds = 10;
		
		
		// Menu system
		  // Pins
		    #define enc_clk 15 // Encoder clock
		    #define enc_dt  A0 // Encoder Dt
		    #define enc_sw  A1 // Encoder switch
		    #define lcd_scl 3 // LCD SCL
		    #define lcd_sda 2 // LCD SDA
		    #define SCREEN_WIDTH 128 // OLED display width, in pixels
		    #define SCREEN_HEIGHT 64 // OLED display height, in pixels
		    #define I2C_ADDRESS 0x3C
		    #define RST_PIN -1
		
		// Menu system
		  // Menu variables
		    int encoderPosCount = 0;
		    int encclklast;
		    int encValue = 0;
		    bool enc_base = 0;
		    int aVal;
		    boolean bCW;
		    int dontPress = 0;
		    int volPos[] = {64,80,32,52,50,24,24};
		    int keyPressDelay = 20;
		    int firstExec = 0;
		    int ia = 0;
		    int animL = 3;
		    int subTime = 0;
		
		// Volume settings
		    int volScale = 2; // Increment by x% each time
		    int volSet = 100; // Initial volume setting at boot (is probably not the same as system volume
		    int newVolSet = 0;
		    int mutedVol = 0;
		
		/*
		// TO IMPLEMENT: SELECT FUNCTION FOR EACH BUTTON
		      //  1 2 8 7
		      //  3 4 6 5
		    String buttonAction[1] = "playpause";
		    String buttonAction[2] = "explorer";
		    String buttonAction[3] = "steam";
		    String buttonAction[4] = "minecraft";
		    String buttonAction[5] = "record";
		    String buttonAction[6] = "code";
		    String buttonAction[7] = "next";
		    String buttonAction[8] = "prev";*/³³€