#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define CLK 2
#define DT 3
#define SEL 4
#define MORE 7
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int steps = 5;
int counter = 0;
int currentStateCLK, lastStateCLK, knob, knobSize;
int knobQty = 4;
int x_knobDot[8], y_knobDot[8], potVal[8];
int x_knobPos, y_knobPos;
int knobSelect = 0;
int timeOut = 0;
float radian[8], radianMap[8];
int presetScreen = 1;
String knobName[8] = {"OVER", "GAIN", "TONE", "LEVL"};
byte defaultNames[17] = { 16, 18, 5, 19, 5, 20, 75, 14, 71, 54, 55, 56, 57, 58, 59, 60, 61 };
char caracter[] = "?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-=()/|@#*&. ";
void setup() {
pinMode(SEL, INPUT_PULLUP);
pinMode(MORE, INPUT_PULLUP);
pinMode(CLK,INPUT);
pinMode(DT,INPUT);
lastStateCLK = digitalRead(CLK);
attachInterrupt(0, updateEncoder, CHANGE);
attachInterrupt(1, updateEncoder, CHANGE);
display.setTextSize(1);
display.setTextColor(WHITE);
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
for(;;);
}
display.clearDisplay();
}
void loop() {
if(timeOut<=200){
timeOut ++;
}
if (timeOut==100){
//timeOut = 0;
knobSelect=0;
}
if (timeOut>=200){
//timeOut = 0;
presetScreen=0;
//knobSelect=0;
}
if(presetScreen==1){
mainMenu();
}else{
namePreset();
}
buttons();
display.display();
display.clearDisplay();
}
void mainMenu(){
knob = 128/knobQty;
x_knobPos = knob/2;
knobSize = x_knobPos/1.7;
y_knobPos = 32;
for(int i=0; i<knobQty; i++){
radianMap[i] = map(potVal[i], 0, 100, 574.5, 52.5);
radian[i] = radianMap[i]/100;
int x1, y1, x2, y2;
float angle;
x_knobDot[i] = x_knobPos + sin(radian[i]) * (knobSize/2);
y_knobDot[i] = y_knobPos + cos(radian[i]) * (knobSize/2);
for(int i = 1; i<=11; i++){
angle = i*10;
angle = angle * 0.0523598;
x1 = x_knobPos + (sin(angle)) * (knobSize*1.2);
y1 = y_knobPos + (cos(angle)) * (knobSize*1.2);
x2 = x_knobPos + (sin(angle)) * (knobSize*1.3);
y2 = y_knobPos + (cos(angle)) * (knobSize*1.3);
//display.fillCircle(x1, y1, knobSize/10, WHITE);
display.drawLine(x1, y1, x2, y2, WHITE);
}
if (knobSelect == i+1){
display.fillCircle(x_knobPos, y_knobPos, knobSize/1.2, WHITE);
display.drawCircle(x_knobPos, y_knobPos, knobSize, WHITE);
display.fillCircle(x_knobDot[i], y_knobDot[i], knobSize/5, BLACK);
}else{
display.drawCircle(x_knobPos, y_knobPos, knobSize, WHITE);
display.fillCircle(x_knobDot[i], y_knobDot[i], knobSize/5, WHITE);
}
display.setTextSize(1);
display.setCursor(x_knobPos-11,0);
display.print(knobName[i]);
if(potVal[i]<=9){
display.setCursor(x_knobPos-2,y_knobPos*1.7);
}
if(potVal[i]>=10 && potVal[i]<=99){
display.setCursor(x_knobPos-6,y_knobPos*1.7);
}
if(potVal[i]>=100){
display.setCursor(x_knobPos-9,y_knobPos*1.7);
}
display.print(potVal[i]);
x_knobPos = x_knobPos + knob;
}
}
void namePreset(){
display.setTextSize(2);
display.setCursor(4,24);
for(int i = 0; i<10; i++){
display.print(caracter[defaultNames[i]]);
}
}
void buttons(){
if(digitalRead(MORE)==LOW){
display.clearDisplay();
knobQty = knobQty + 1;
delay(500);
}
if (digitalRead(SEL)==LOW){
knobSelect ++;
timeOut = 0;
presetScreen=1;
delay(500);
}
if (knobSelect >= knobQty+1){
knobSelect = 1;
}
}
void updateEncoder(){
currentStateCLK = digitalRead(CLK);
if (currentStateCLK != lastStateCLK && currentStateCLK == 1){
if (digitalRead(DT) != currentStateCLK) {
counter --;
//cuendo gira el encoder sentido antihorario
for(int i = 0; i <knobQty; i++){
if(potVal[i]>=1 && knobSelect==i+1){
potVal[i] = potVal[i] - steps;
timeOut = 0;
}
}
} else {
counter ++;
//cuando gira el encoder sentido horario
for(int i = 0; i <knobQty; i++){
if(potVal[i]<=99 && knobSelect==i+1){
potVal[i] = potVal[i] + steps;
timeOut = 0;
}
}
}
}
lastStateCLK = currentStateCLK;
}