// 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
}
'하드웨어 > ESP32' 카테고리의 다른 글
teensy4.1+audio board with ESP32 touch sensing (0) | 2021.11.12 |
---|---|
esp32 lolin32 lite보드의 터치핀 이용하기 (0) | 2021.10.30 |
ESP32보드를 아두이노IDE로 코딩하기 (0) | 2021.01.28 |