// 2021/11/8: Lolin32+OLED final

//#define DEBUG_SERIAL

#include <WiFi.h>
#include <driver/adc.h> // for adc_power_off()


#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 oled(128, 64, &Wire, -1);

// 한 번만 샘플링하면 1~2%의 확률로 0에 가까운 값이 읽힌다고 한다(잡음)
// 따라서 여러번 샘플링하여 평균값으로 판단하는 것이 안정적이다.
// SAMPLES가 20이면 loop()함수 한 번 실행 시간이 76ms 정도이다.
// 30이면 113ms 정도이다.
#define SAMPLES 20


// touchRead() 평균값이 아래 문턱값 이하이면 터치된 걸로 판단
#define THRESHOLD 20


#define PAD1    36 //(1) C#
#define PAD2    39 //(2) C
#define PAD3    34 //(3) D#
#define PAD4    35 //(4) D
#define PAD5    25 //(5) E
#define PAD6    26 //(6) F#
#define PAD7    19 //(7) F
#define PAD8    23 //(8) G#
#define PAD9    18 //(9) G
#define TPAD10  T9 //(10)A#
#define TPAD11  T8 //(11)A
#define TPAD12  T7 //(12)B
#define TPAD13  T6 //(13)
#define TPAD14  T5 //(14)
#define TPAD15  T4 //(15)

#define OUT_1  5
#define OUT_2  17
#define OUT_3  16
#define OUT_4  4
#define OUT_A  0
#define OUT_B  2
#define OUT_C  15

void setup() {

  // 소모전력을 줄이기 위해서 WiFi와 bt는 끈다.
  // ADC도 사용하지 않으므로 꺼야 한다.
  adc_power_off();
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  btStop();

  // put your setup code here, to run once:
  
  ///*
  pinMode(PAD1, INPUT);
  pinMode(PAD2, INPUT);
  pinMode(PAD3, INPUT);
  pinMode(PAD4, INPUT);
  pinMode(PAD5, INPUT);
  pinMode(PAD6, INPUT);
  pinMode(PAD7, INPUT);
  pinMode(PAD8, INPUT);
  pinMode(PAD9, INPUT);
  
  pinMode(OUT_1, OUTPUT); //LED_BUILTIN
  pinMode(OUT_2, OUTPUT);
  pinMode(OUT_3, OUTPUT);
  pinMode(OUT_4, OUTPUT);
  pinMode(OUT_A, OUTPUT);
  pinMode(OUT_B, OUTPUT);
  pinMode(OUT_C, OUTPUT);

  // Address 0x3D for 128x64
  boolean isDisplayReady = oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);

#ifdef DEBUG_SERIAL //#######################
  Serial.begin(115200);
  delay(100);
  if(!isDisplayReady) { 
    Serial.println(F("OLED(SSD1306) diaplay detection failed"));
  }
#endif //####################################

  oled.clearDisplay();
  oled.display();
}


byte getTouchAverage(byte tN){
  int totalRead = 0;
  for(byte n=0; n<SAMPLES; n++){
    totalRead += touchRead(tN);
  }
  return totalRead/SAMPLES;
}

char notes[] = {' ', 'C', 'D', 'E', 'F', 'G', 'A', 'B'};
char *chords[] = {
    "",  //CBA:000
    "7", //CBA:001
    "m", //CBA:010
    "m7",//CBA:011
    "M", //CBA:100
    "M7",//CBA:101
    "sus4", //CBA:110
    "dim7", //CBA:111
};
byte idNote=0;
boolean isHalfHigh=false;
byte idChord=0;
byte prevChordByte=0;



void loop() {

  
#ifdef DEBUG_SERIAL //#######################
  int tm = millis();//(2)
#endif //####################################

  byte chordByte;

  boolean p1=digitalRead(PAD1);
  boolean p2=digitalRead(PAD2);
  boolean p3=digitalRead(PAD3);
  boolean p4=digitalRead(PAD4);
  boolean p5=digitalRead(PAD5);
  boolean p6=digitalRead(PAD6);
  boolean p7=digitalRead(PAD7);
  boolean p8=digitalRead(PAD8);
  boolean p9=digitalRead(PAD9);

  byte tp10=getTouchAverage(TPAD10);
  byte tp11=getTouchAverage(TPAD11);
  byte tp12=getTouchAverage(TPAD12);
  byte tp13=getTouchAverage(TPAD13);
  byte tp14=getTouchAverage(TPAD14);
  byte tp15=getTouchAverage(TPAD15);
  
  boolean p10 = tp10 < THRESHOLD;
  boolean p11 = tp11 < THRESHOLD;
  boolean p12 = tp12 < THRESHOLD;
  boolean p13 = tp13 < THRESHOLD;
  boolean p14 = tp14 < THRESHOLD;
  boolean p15 = tp15 < THRESHOLD;


  if(p1==HIGH){ //C#
    
    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p4); //gpio0
    digitalWrite(OUT_B, p5);
    digitalWrite(OUT_C, p7);   

    idNote=1;
    isHalfHigh = true; 
    idChord = p4+p5*2+p7*4;

    chordByte = 1+idChord*16;
    
  } else if (p2==HIGH){ //C
    
    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p4); //gpio0
    digitalWrite(OUT_B, p5);
    digitalWrite(OUT_C, p7);  

    idNote=1;
    isHalfHigh = false; 
    idChord = p4+p5*2+p7*4;

    chordByte = 2+idChord*16;

  } else if (p3==HIGH){ //D#

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p5); //gpio0
    digitalWrite(OUT_B, p7);
    digitalWrite(OUT_C, p9);  

    idNote=2;
    isHalfHigh = true; 
    idChord = p5+p7*2+p9*4;

    chordByte = 3+idChord*16;

  } else if (p4==HIGH){ //D

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p5); //gpio0
    digitalWrite(OUT_B, p7);
    digitalWrite(OUT_C, p9);  

    idNote=2;
    isHalfHigh = false; 
    idChord = p5+p7*2+p9*4;

    chordByte = 4+idChord*16;

  } else if (p5==HIGH){ //E

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p7); //gpio0
    digitalWrite(OUT_B, p9);
    digitalWrite(OUT_C, p11);  

    idNote=3;
    isHalfHigh = false; 
    idChord = p7+p9*2+p11*4;

    chordByte = 5+idChord*16;
    
  } else if (p6==HIGH){ //F#

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p9); //gpio0
    digitalWrite(OUT_B, p11);
    digitalWrite(OUT_C, p12);

    idNote=4;
    isHalfHigh = true; 
    idChord = p9 + p11*2 + p12*4;

    chordByte = 6+idChord*16;

  } else if (p7==HIGH){ //F

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, p9); //gpio0
    digitalWrite(OUT_B, p11);
    digitalWrite(OUT_C, p12);  

    idNote=4;
    isHalfHigh = false; 
    idChord = p9+p11*2+p12*4;

    chordByte = 7+idChord*16;


  } else if (p8==HIGH){ //G#

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p11); //gpio0
    digitalWrite(OUT_B, p12);
    digitalWrite(OUT_C, p13);  

    idNote=5;
    isHalfHigh = true; 
    idChord = p11 + p12*2 + p13*4;

    chordByte = 8+idChord*16;

  } else if (p9==HIGH){ //G

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p11); //gpio0
    digitalWrite(OUT_B, p12);
    digitalWrite(OUT_C, p13);  

    idNote=5;
    isHalfHigh = false; 
    idChord = p11 + p12*2 + p13*4;

    chordByte = 9+idChord*16;

  } else if (p10==HIGH){ //A#

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p12); //gpio0
    digitalWrite(OUT_B, p13);
    digitalWrite(OUT_C, p14);  

    idNote=6;
    isHalfHigh = true; 
    idChord = p12 + p13*2 + p14*4;

    chordByte = 10+idChord*16;

  } else if (p11==HIGH){ //A

    digitalWrite(OUT_1, 1);
    digitalWrite(OUT_2, 1);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p12); //gpio0
    digitalWrite(OUT_B, p13);
    digitalWrite(OUT_C, p14);  

    idNote=6;
    isHalfHigh = false; 
    idChord = p12 + p13*2 + p14*4;

    chordByte = 11+idChord*16;

  } else if (p12==HIGH){ //B

    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 1);
    digitalWrite(OUT_4, 1);
    digitalWrite(OUT_A, p13); //gpio0
    digitalWrite(OUT_B, p14);
    digitalWrite(OUT_C, p15);  

    idNote=7;
    isHalfHigh = false; 
    idChord = p13 + p14*2 + p15*4;

    chordByte = 12+idChord*16;

  } else { //아무 코드도 짚지 않았을 때
  
    digitalWrite(OUT_1, 0);
    digitalWrite(OUT_2, 0);
    digitalWrite(OUT_3, 0);
    digitalWrite(OUT_4, 0);
    digitalWrite(OUT_A, 0);
    digitalWrite(OUT_B, 0);
    digitalWrite(OUT_C, 0);      

    idNote=0;
    isHalfHigh = false; 
    idChord = 0;

    chordByte = 0;
  }


  // 만약 oled가 갱신된다면 87ms 가 소요되고
  // 갱신되지 않는다면 58ms가 소요된다.
  // (OLED에 코드를 새로 표시하는데 30ms정도가 소요됨)
  
  if (chordByte != prevChordByte) {

    oled.clearDisplay();
    oled.setTextColor(WHITE);
    if (idNote>0) {
      oled.setCursor(0, 5);
      oled.setTextSize(8);
      oled.print( notes[idNote] );
    }
    if (isHalfHigh){
      oled.setCursor(48, 0);
      oled.setTextSize(4);
      oled.print("#");
    }
    if (idChord>0){
      oled.setCursor(48, 32);
      oled.setTextSize(4);
      oled.print( chords[idChord] );
    }
    oled.display(); //display the text on the screen


    prevChordByte = chordByte;
  }


#ifdef DEBUG_SERIAL
  Serial.print(millis()-tm);//(3)소요 시간 표시
  Serial.print("ms per 1 loop :");Serial.print(p1);
  Serial.print(':');Serial.print(p2);
  Serial.print(':');Serial.print(p3);
  Serial.print(':');Serial.print(p4);
  Serial.print(':');Serial.print(p5);
  Serial.print(':');Serial.print(p6);
  Serial.print(':');Serial.print(p7);
  Serial.print(':');Serial.print(p8);
  Serial.print(':');Serial.print(p9);
  Serial.print(':');Serial.print(tp10);
  Serial.print(':');Serial.print(tp11);
  Serial.print(':');Serial.print(tp12);
  Serial.print(':');Serial.print(tp13);
  Serial.print(':');Serial.print(tp14);
  Serial.print(':');Serial.print(tp15);
  Serial.println();
#endif


}

Posted by 살레시오

댓글을 달아 주세요