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";*/³³€