#include <SPI.h>
#include <Wire.h>
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
#include <RotaryEncoder.h>
#include <EEPROM.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <avr/pgmspace.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSansBold9pt7b.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#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);
RotaryEncoder encoder(A2, A3);
char buffer[5];
uint8_t x = 12;
uint8_t j = 0;
uint8_t modo = 0;
uint8_t pressionado = 0;
uint8_t BT[] = {3, 2, 5, 4};
uint8_t configline = 0;
uint8_t banco_atual = 1;
uint8_t fx = 0;
uint8_t index = 0;
uint8_t midi_Value [16] = {0};
const char msg0[] PROGMEM = "B +";
const char msg1[] PROGMEM = "B -";
const char msg2[] PROGMEM = "TAP";
const char msg3[] PROGMEM = "P +";
const char msg4[] PROGMEM = "P -";
const char msg5[] PROGMEM = "ABC";
const char msg6[] PROGMEM = "STP";
const char msg7[] PROGMEM = "A 1";
const char msg8[] PROGMEM = "A 2";
const char msg9[] PROGMEM = "A 3";
const char msg10[] PROGMEM = "A 4";
const char msg11[] PROGMEM = "A 5";
const char msg12[] PROGMEM = "A 6";
const char msg13[] PROGMEM = "B 1";
const char msg14[] PROGMEM = "B 2";
const char msg15[] PROGMEM = "B 3";
const char msg16[] PROGMEM = "B 4";
const char msg17[] PROGMEM = "B 5";
const char msg18[] PROGMEM = "B 6";
const char msg19[] PROGMEM = "TUN";
const char msg20[] PROGMEM = "CTR";
const char msg21[] PROGMEM = "SCR";
const char* const string_table[] PROGMEM = {msg0, msg1, msg2, msg3, msg4, msg5, msg6, msg7, msg8, msg9,
msg10, msg11, msg12, msg13, msg14, msg15, msg16, msg17, msg18, msg19,
msg20, msg21};
const uint8_t midi_CC[] PROGMEM = {23, 22, 76, 27, 26, 28, 28,
48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59, 60, 73, 77
};
//- Modo[0] = Operação
//- Modo[1] = Configuração
//- Modo[2] = Escolha
uint8_t midi_channel = 1;
MIDI_CREATE_DEFAULT_INSTANCE();
void handleError(int8_t err)
{
digitalWrite(LED_BUILTIN, (err == 0) ? LOW : HIGH);
}
void setup() //****************************************************
{
//Serial.begin(115200);
Serial.begin(9600);
MIDI.setHandleError(handleError);
MIDI.begin(MIDI_CHANNEL_OMNI);
Wire.begin();
/*
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
*/
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
for (uint8_t i = 0; i < 4; i++) pinMode(BT[i], INPUT_PULLUP);
pinMode(7, INPUT);
//for (uint8_t i = 0; i < 16; i++) EEPROM.write(i, i);// ***** SOMENTE NO PRIMEIRO UPLOAD *****
//for (uint8_t i = 0; i < 16; i++) Sel_fx[i] = {0};// ***** SOMENTE EM AMBIENTE DE TESTE *****
display.clearDisplay();
//display.setFont(&FreeSans9pt7b);
display.setFont(&FreeSansBold9pt7b);
display.setTextSize(2);
display.setTextColor(WHITE, BLACK);
display.setCursor(23, 35 + x);
display.print(F("MVS"));
display.display();
delay(2000);
showdisplay();
}
// BT ENVIA SINAL PARA PEDALEIRA -------------------
void Envia_Sinal() //****************************************************
{
if (modo == 0 && pressionado == 0)
{
if (midi_Value[index + j] == 0)
{
midi_Value[index + j] = 127;
}
else
{
midi_Value[index + j] = 0;
}
uint8_t Midi_Info[2];
strcpy_P(Midi_Info, (uint8_t)pgm_read_word(&(midi_CC[EEPROM.read(index + j)])));
Midi_Info[0] = pgm_read_byte(&(midi_CC[EEPROM.read(index + j)]));
Midi_Info[1] = '\0'; // Adiciona um terminador nulo para indicar o final da string
MIDI.sendControlChange(Midi_Info[0], midi_Value[index + j], midi_channel);
display.clearDisplay();
display.setCursor(38, 40 + x);
//display.setFont(&FreeSans9pt7b);
display.setFont(&FreeSansBold9pt7b);
display.setTextSize(2);
strcpy_P(buffer, (char *)pgm_read_word(&(string_table[EEPROM.read(index + j)])));
display.print(buffer);
display.display();
pressionado = 1;
delay(1000);
showdisplay();
}
}
void showdisplay() //****************************************************
{
display.clearDisplay();
//display.setFont(&FreeSans9pt7b);
display.setFont(&FreeSansBold9pt7b);
display.setTextSize(2);
display.setCursor(52, 40 + x);
if (banco_atual == 1) display.print(F("A"));
if (banco_atual == 2) display.print(F("B"));
if (banco_atual == 3) display.print(F("C"));
if (banco_atual == 4) display.print(F("D"));
display.setFont(&FreeSans9pt7b);
//display.setFont(&FreeSansBold9pt7b);
display.setTextSize(1);
display.setCursor(0, 25 + x);
strcpy_P(buffer, (char *)pgm_read_word(&(string_table[EEPROM.read(index + 2)])));
display.print(buffer);
display.setCursor(0, 50 + x);
strcpy_P(buffer, (char *)pgm_read_word(&(string_table[EEPROM.read(index + 0)])));
display.print(buffer);
display.setCursor(100, 25 + x);
strcpy_P(buffer, (char *)pgm_read_word(&(string_table[EEPROM.read(index + 3)])));
display.print(buffer);
display.setCursor(100, 50 + x);
strcpy_P(buffer, (char *)pgm_read_word(&(string_table[EEPROM.read(index + 1)])));
display.print(buffer);
//display.setFont(&FreeSans9pt7b);
display.setFont(&FreeSansBold9pt7b);
display.setCursor(45, 0 + x);
display.print(F("LIVE"));
display.display();
}
void showmenu() //****************************************************
{
//display.setFont(&FreeSans9pt7b);
display.setFont(&FreeSansBold9pt7b);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0 + x);
display.print(F("EXIT"));
display.setCursor(75, 0 + x);
display.print(F("BACK"));
uint8_t Floor_Mod = floor(configline / 2) * 2;
display.setFont(&FreeSans9pt7b);
//display.setFont(&FreeSansBold9pt7b);
for (uint8_t o = Floor_Mod; o < (Floor_Mod + 2); o++)
{
strcpy_P(buffer, (char *)pgm_read_word(&(string_table[o])));
display.setCursor(75, 25 + 20 * (o - Floor_Mod) + x);
display.print(buffer);
}
display.setCursor(62, 25 + 20 * (configline % 2) + x);
display.print(F(">"));
display.drawRect(124, 20, 4, 44, WHITE);
display.fillRect(124, 22 + ceil(1.5454 * configline), 4, 8, WHITE);
display.setTextSize(2);
//display.setFont(&FreeSans9pt7b);
display.setFont(&FreeSansBold9pt7b);
display.setCursor(0, 38 + x);
if (banco_atual == 1) display.print(F("A"));
if (banco_atual == 2) display.print(F("B"));
if (banco_atual == 3) display.print(F("C"));
if (banco_atual == 4) display.print(F("D"));
display.print(j + 1);
display.display();
}
void showoptions() //****************************************************
{
display.clearDisplay();
//display.setFont(&FreeSans9pt7b);
display.setFont(&FreeSansBold9pt7b);
display.setTextSize(2);
display.setCursor(52, 40 + x);
if (banco_atual == 1) display.print(F("A"));
if (banco_atual == 2) display.print(F("B"));
if (banco_atual == 3) display.print(F("C"));
if (banco_atual == 4) display.print(F("D"));
//display.drawRoundRect(20, 20, 88, 40, 4, WHITE);
display.setFont(&FreeSans9pt7b);
//display.setFont(&FreeSansBold9pt7b);
display.setTextSize(1);
display.setCursor(0, 25 + x);
display.print(F("3"));
display.setCursor(0, 50 + x);
display.print(F("1"));
display.setCursor(115, 25 + x);
display.print(F("4"));
display.setCursor(115, 50 + x);
display.print(F("2"));
//display.setFont(&FreeSans9pt7b);
display.setFont(&FreeSansBold9pt7b);
display.setCursor(27, 0 + x);
display.print(F("CONFIG"));
display.display();
}
void loop() //****************************************************
{
static uint8_t pos = 0;
encoder.tick();
uint8_t newPos = encoder.getPosition();
for (uint8_t i = 0; i < 4; i++)
{
if (digitalRead(BT[i]) == LOW) // PINO 2
{
j = i;
Envia_Sinal();
}
}
if (digitalRead(BT[0]) == HIGH && digitalRead(BT[1]) == HIGH && digitalRead(BT[2]) == HIGH && digitalRead(BT[3]) == HIGH)
{
pressionado = 0;
}
//TELA DE ESCOLHA DO BOTÃO A CONFIGURAR
if (digitalRead(BT[j]) == LOW && modo == 1 && pressionado == 0)
{
fx = index + j;
showmenu();
modo = 2;
pressionado = 1;
delay(50);
}
//BT scroll para cima
if (newPos > pos && modo == 2 && configline > 0)
{
configline = configline - 1;
//configlineMod = configline % 22;
display.clearDisplay();
showmenu();
}
//BT scroll para baixo
if (newPos < pos && modo == 2 && configline < 21)
{
configline = configline + 1;
//configlineMod = configline % 22;
display.clearDisplay();
showmenu();
}
//BT Seleciona
if (digitalRead(7) == LOW && pressionado == 0 && modo == 2)
{
EEPROM.write(fx, configline);
//configline = 0;
//configlineMod = 0;
//Floor_Mod = 0;
showoptions();
modo = 1;
pressionado = 1;
}
//BT SAIR
if (digitalRead(5) == LOW && pressionado == 0 && modo == 2)
{
showdisplay();
modo = 0;
pressionado = 1;
}
// BT VOLTAR
if (digitalRead(4) == LOW && pressionado == 0 && modo == 2)
{
showoptions();
modo = 1;
pressionado = 1;
}
// BANCO DOWN - MODO DE CONFIGURAÇÃO
if (newPos > pos && modo == 1 && banco_atual > 1)
{
banco_atual--;
index = ((banco_atual - 1) * 4);
showoptions();
pressionado = 1;
}
// BANCO UP - MODO DE CONFIGURAÇÃO
if (newPos < pos && modo == 1 && banco_atual < 4)
{
banco_atual++;
index = ((banco_atual - 1) * 4);
showoptions();
pressionado = 1;
}
// BANCO DOWN - MODO DE OPERAÇÃO
if (newPos > pos && modo == 0 && banco_atual > 1)
{
banco_atual--;
index = ((banco_atual - 1) * 4);
showdisplay();
}
// BANCO UP - MODO DE OPERAÇÃO
if (newPos < pos && modo == 0 && banco_atual < 4)
{
banco_atual++;
index = ((banco_atual - 1) * 4);
showdisplay();
}
unsigned long buttonPressTime;
if (digitalRead(7) == LOW && pressionado == 0 && modo == 0)
{
buttonPressTime = millis();
}
while (digitalRead(7) == LOW)
{
if (digitalRead(7) == LOW && millis() - buttonPressTime >= 2000 && modo == 0)
{
showoptions();
modo = 1;
pressionado = 1;
delay(50);
}
}
pos = newPos;
}