#include <Arduino.h>
#include <U8g2lib.h>
#include <Complex.h>
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE, /* clock=*/ 16, /* data=*/ 17); // ESP32 Thing, HW I2C with pin remapping
volatile int encoderWertMulti = 1; //encoder Wert vom multi purpose
int chActive = 1; //aktive channel
boolean activeFx[]={0,0,0,0,0,0}; //speichert welche fx aktive sind
byte activePage = 1; //the Page that was set as active
int calcTransferF(double w,double t,double m,double l){
double r1=250000.0; //werte der Bauelemente
double r2=250000.0;
double r3=10000.0;
double r4=100000.0;
double c1=0.000000000250;
double c2=0.0000001;
double c3=0.000000050;
//double t=0.5;
//double m=0.5;
//double l=0.5;
Complex i(0.0,1.0); //define img i
double b1=r3*(m*c3+c1+c2)+(t*c1*r1)+(l*r2-(1-m)*r3)*(c1+c2);
double b2=t*(c1*c2*r1*r4+c1*c3*r1*r4)-m*m*(c1*c2*(r3*r3)+c2*c3*r3*r3)+m*(c1*c3*r1*r3+c1*c3*r3*r3+c2*c3*r3*r3)+(l*r2-(1-m)*r3)*(c1*c2*r1+c1*c2*r4+c1*c3*r4)+m*(l*r2-(1-m)*r3)*(c1*c3*r3+c2*c3*r3)+c1*r3*(c2*r1+c2*r4+c3*r4);
double b3=m*(l*r2-(1-m)*r3)*c1*c2*c3*r3*(r1+r4)-m*m*r3*r3*c1*c2*c3*(r1+r4)+m*c1*c2*c3*r3*r3*(r1+r4)+t*c1*c2*c3*r1*r3*r4*(1-m)+t*(l*r2-(1-m)*r3)*c1*c2*c3*r1*r4;
double a1=c1*r1+c1*r3+c2*r3+c2*r4+c3*r4+m*r3*c3+(l*r2-(1-m)*r3)*(c1+c2);
double a2=m*c3*r3*(c1*r1-c2*r4+c1*r3+c2*r3)+m*(l*r2-(1-m)*r3)*c3*r3*(c1+c2)-m*m*c3*r3*r3*(c1+c2)+(l*r2-(1-m)*r3)*(c1*c2*r4+c1*c2*r1+c1*c3*r4+c2*c3*r4)+(c1*c2*r1*r4+c1*c3*r1*r4+c1*c2*r3*r4+c1*c2*r1*r3+c1*c3*r3*r4+c2*c3*r3*r4);
double a3=m*(l*r2-(1-m)*r3)*c1*c2*c3*r3*(r1+r4)-m*m*c1*c2*c3*r3*r3*(r1+r4)+m*c1*c2*c3*r3*(r1*r3+r4*r3+r3*r4)+(l*r2-(1-m)*r3)*(c1*c2*c3*r1*r4)+c1*c2*c3*r1*r3*r4;
Complex h(0.0,0.0); //define transferfunction_name
int g = 0; //value of attenuation in dB
h=-(i*b1*w-b2*w*w-i*b3*w*w*w)/(i*a1*w-a2*w*w-i*a3*w*w*w+1); //calculate transferfunction
g = h.modulus()*41; //calculate betrag
return g;
}
void cursPosCh(int pos){
u8g2.drawFrame((pos*25)-24,0,(25*pos-25*(pos-1)-1),11); //curser for channel top
}
void cursPage2(boolean pos){
if(pos==0){u8g2.drawFrame(66,0,36,11);}
else{u8g2.drawFrame(103,0,25,11);}
}
void cursPage3(boolean pos){
if(pos==0){u8g2.drawFrame(6,52,34,11);}
else{u8g2.drawFrame(41,52,17,11);}
}
void cursPosFx(int pos){ //curser for fx chain
if(pos<4){u8g2.drawFrame(pos*17-16,55,16,9);}
if(pos>=4 && pos<7){u8g2.drawFrame(pos*17+9,55,16,9);}
if(pos==7){u8g2.drawFrame(101,0,27,11);}
}
void fxSet(boolean activeFx[] ){ //methode to draw arrows
u8g2.setFont(u8g2_font_7x13_t_symbols); //set to symbol font and color
u8g2.setDrawColor(1);
if(activeFx[0]==1){
u8g2.drawGlyph(0, 44, 0x21b4);
u8g2.drawGlyph(11, 44, 0x21b1);
}
else{
u8g2.drawGlyph(11, 41, 0x2192);
u8g2.drawLine(0,46,10,46);
}
if(activeFx[1]==1){
u8g2.drawGlyph(17, 44, 0x21b4);
u8g2.drawGlyph(28, 44, 0x21b1);
}
else{
u8g2.drawGlyph(28, 41, 0x2192);
u8g2.drawLine(17,46,27,46);
}
if(activeFx[2]==1){
u8g2.drawGlyph(34, 44, 0x21b4);
u8g2.drawGlyph(46, 44, 0x21b1);
}
else{
u8g2.drawGlyph(46, 41, 0x2192);
u8g2.drawLine(34,46,45,46);
}
if(activeFx[3]==1){
u8g2.drawGlyph(76, 44, 0x21b4);
u8g2.drawGlyph(88, 44, 0x21b1);
}
else{
u8g2.drawGlyph(88, 41, 0x2192);
u8g2.drawLine(76,46,87,46);
}
if(activeFx[4]==1){
u8g2.drawGlyph(94, 44, 0x21b4);
u8g2.drawGlyph(106, 44, 0x21b1);
}
else{
u8g2.drawGlyph(105, 41, 0x2192);
u8g2.drawLine(93,46,104,46);
}
if(activeFx[5]==1){
u8g2.drawGlyph(111, 44, 0x21b4);
u8g2.drawGlyph(122, 44, 0x21b1);
}
else{
u8g2.drawGlyph(122, 41, 0x2192);
u8g2.drawLine(109,46,121,46);
}
}
void encoderLesen(){ //ISR für encoder rotation
if(activePage == 1){
if(digitalRead(24)==HIGH && encoderWertMulti<7){encoderWertMulti++;}
if(digitalRead(24)==LOW && encoderWertMulti>1){encoderWertMulti--;}
else{encoderWertMulti=encoderWertMulti;}
return;
}
if(activePage == 2 || activePage ==3){
if(digitalRead(24)==HIGH){encoderWertMulti++;}
if(digitalRead(24)==LOW){encoderWertMulti--;}
else{encoderWertMulti=encoderWertMulti;}
return;
}
}
void changeSetting(){ //ISR für encoder button
if(activePage == 1){ //check the active page
if(encoderWertMulti<=6){activeFx[encoderWertMulti-1] = !activeFx[encoderWertMulti-1];}
if(encoderWertMulti==7){activePage = 2;}
return;
}
if(activePage == 2){
if(encoderWertMulti%2==0){
activePage=1;
encoderWertMulti=1; //set curser back to position 1 on page 1
return;
}
if(encoderWertMulti%2==1){activePage=3;}
return;
}
if(activePage == 3){
if(encoderWertMulti%2==0){
activePage=1;
encoderWertMulti=1; //set curser back to position 1 on page 1
return;
}
if(encoderWertMulti%2==1){activePage=2;}
return;
}
}
void setChActive(){ //get the pressed button and set LEDs...
if(digitalRead(25)==LOW){
digitalWrite(53, HIGH);
digitalWrite(49, LOW);
digitalWrite(51, LOW);
digitalWrite(52, LOW);
chActive = 1;
}
if(digitalRead(27)==LOW){
digitalWrite(51, HIGH);
digitalWrite(53, LOW);
digitalWrite(49, LOW);
digitalWrite(52, LOW);
chActive = 2;
}
if(digitalRead(29)==LOW){
digitalWrite(49, HIGH);
digitalWrite(52, LOW);
digitalWrite(53, LOW);
digitalWrite(51, LOW);
chActive = 3;
}
if(digitalRead(31)==LOW){
digitalWrite(52, HIGH);
digitalWrite(49, LOW);
digitalWrite(51, LOW);
digitalWrite(53, LOW);
chActive = 4;
}
}
void page1(int gainCh, int volCh, int chNum, int fxNum){
u8g2.clearBuffer();
u8g2.setDrawColor(1);
u8g2.setFont(u8g2_font_6x12_tf);
u8g2.drawLine(0, 11, 127, 11); //draw top line
for( int x = 0; x<101; x=x+25 ){//divide in sections
u8g2.drawLine(x, 0, x, 11);
}
u8g2.drawStr( 5, 0, "Ch1");
u8g2.drawStr( 30, 0, "Ch2");
u8g2.drawStr( 55, 0, "Ch3");
u8g2.drawStr( 80, 0, "Ch4");
u8g2.drawStr( 107,0, "EQ");
cursPosCh(chNum); //draw cursers
cursPosFx(fxNum);
u8g2.drawStr( 0, 13, " Gain:"); //draw sound settings
u8g2.drawStr( 0, 24, "Volume: ");
u8g2.setCursor(102, 14);
String gain = String(gainCh);
gain=gain+"%";
u8g2.print(gain);
u8g2.setCursor(102, 25);
String vol = String(volCh);
vol=vol+"%";
u8g2.print(vol);
u8g2.drawBox(40,15,gainCh*0.6,9); //sound bars
u8g2.drawBox(40,26,volCh*0.6,9);
fxSet(activeFx); //draw fx arrows
u8g2.setFont(u8g2_font_5x8_tf);
u8g2.drawStr(2,56,"FX1");
u8g2.drawStr(19,56,"FX2");
u8g2.drawStr(36,56,"FX3");
u8g2.drawStr(78,56,"FX4");
u8g2.drawStr(95,56,"FX5");
u8g2.drawStr(112,56,"FX6");
for(int i = 0; i<=55; i=i+17){u8g2.drawLine(i,55,i,64);} //draw fx boxes
u8g2.drawLine(0,54,51,54); //draw fx long line
u8g2.drawLine(76,54,128,54); //draw fx long line right
u8g2.drawFrame(52,41,24,23); //draw ampbox
for(int i = 76; i<=128; i=i+17){u8g2.drawLine(i,55,i,64);} //draw fx loop boxes
u8g2.drawStr(57,44,"Pre");
u8g2.drawStr(57,52,"Amp");
u8g2.sendBuffer();
delay(30);
}
void page2(float treb, float mids, float bass){
int w = 68;
u8g2.clearBuffer();
u8g2.setDrawColor(1);
u8g2.setFont(u8g2_font_5x8_tf);
for(int j=0;j<105;j++){ //draw bode plot
u8g2.drawPixel(j+14,64-calcTransferF(w,treb,mids,bass)-15);
w=w*1.07;
}
u8g2.drawLine(12,51,127,51);
u8g2.drawLine(12,0,12,53);
u8g2.drawPixel(11,1);
u8g2.drawPixel(13,1);
u8g2.drawPixel(10,2);
u8g2.drawPixel(14,2);
u8g2.drawPixel(126,50);
u8g2.drawPixel(125,49);
u8g2.drawPixel(126,52);
u8g2.drawPixel(125,53);
u8g2.drawLine(69,50,69,53);
u8g2.drawLine(109,50,109,53);
u8g2.drawStr(0,20,"10-");
u8g2.drawStr(0,47,"30-");
u8g2.drawStr(8,55,"20");
u8g2.drawStr(62,55,"500");
u8g2.drawStr(105,55,"9k");
u8g2.drawStr(15,0,"-dB");
u8g2.drawStr(112,40,"Frq");
u8g2.setFont(u8g2_font_open_iconic_all_1x_t);
u8g2.setDrawColor(2);
u8g2.drawGlyph(115, 1, 0x0b8); //draw symbols for menu
u8g2.drawGlyph(105, 1, 0x004e);
u8g2.drawLine(65,11,127,11);
u8g2.drawLine(65,0,65,10);
u8g2.drawLine(102,0,102,10);
u8g2.setFont(u8g2_font_6x12_tf);
u8g2.drawStr(69,0,"Ch/FX");
cursPage2(encoderWertMulti%2);
u8g2.sendBuffer();
}
void page3(){
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x12_tf);
u8g2.drawStr(5,5,"Anode Voltage: ");
u8g2.drawStr(5,15, "Plate Current: ");
u8g2.drawStr(5,25, "Temperature 1: ");
u8g2.drawStr(5,35, "Temperature 2: ");
u8g2.drawFrame(5,51,54,13);
u8g2.drawLine(40,52,40,62);
u8g2.drawStr(8,52,"Ch/FX");
u8g2.drawStr(44,52,"EQ");
cursPage3(encoderWertMulti%2);
u8g2.sendBuffer();
}
void setup() {
u8g2.begin();
u8g2.setFont(u8g2_font_6x12_tf);
u8g2.setFontRefHeightExtendedText();
u8g2.setFontPosTop();
u8g2.setFontDirection(0);
pinMode(25,INPUT_PULLUP);
pinMode(27,INPUT_PULLUP);
pinMode(29,INPUT_PULLUP);
pinMode(31,INPUT_PULLUP);
pinMode(49, OUTPUT);
pinMode(51, OUTPUT);
pinMode(53, OUTPUT);
pinMode(52, OUTPUT);
pinMode(2, INPUT);
pinMode(24, INPUT);
attachInterrupt(digitalPinToInterrupt(2), encoderLesen, FALLING);
attachInterrupt(digitalPinToInterrupt(3), changeSetting, FALLING);
page1(50,60,1,1); //draw first page
digitalWrite(53, HIGH);
digitalWrite(49, LOW);
digitalWrite(51, LOW);
digitalWrite(52, LOW);
}
void loop() {
setChActive(); //check for pressed button
switch(activePage){ //draw pages
case 1:
page1(100,100,chActive,encoderWertMulti);
break;
case 2:
page2(0.5,0.5,0.5);
break;
case 3:
page3();
break;
}
}
Ch1 Ch2 Ch3 Ch4
Ch1 ---- Ch2 ----- Ch3 ----- Ch4