teensy audio design GUI

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlaySdWav           playSdWav3;     //xy=74,367
AudioPlaySdWav           playSdWav1;     //xy=77,241
AudioPlaySdWav           playSdWav7;     //xy=78,597
AudioPlaySdWav           playSdWav4;     //xy=80,425
AudioPlaySdWav           playSdWav2;     //xy=81,303
AudioPlaySdWav           playSdWav6;     //xy=82,535
AudioPlaySdWav           playSdWav5;     //xy=86,476
AudioMixer4              mixer1;         //xy=291,316
AudioMixer4              mixer2;         //xy=449,424
AudioOutputI2S           i2s1;           //xy=626,430
AudioConnection          patchCord1(playSdWav3, 0, mixer1, 2);
AudioConnection          patchCord2(playSdWav1, 0, mixer1, 0);
AudioConnection          patchCord3(playSdWav7, 0, mixer2, 3);
AudioConnection          patchCord4(playSdWav4, 0, mixer1, 3);
AudioConnection          patchCord5(playSdWav2, 0, mixer1, 1);
AudioConnection          patchCord6(playSdWav6, 0, mixer2, 2);
AudioConnection          patchCord7(playSdWav5, 0, mixer2, 1);
AudioConnection          patchCord8(mixer1, 0, mixer2, 0);
AudioConnection          patchCord9(mixer2, 0, i2s1, 0);
AudioConnection          patchCord10(mixer2, 0, i2s1, 1);
// GUItool: end automatically generated code

AudioControlSGTL5000     sgtl5000_1;

// 오디오보드의 sd카드 슬롯을 이용
//#define SDCARD_CS_PIN    10
//#define SDCARD_MOSI_PIN  7
//#define SDCARD_SCK_PIN   14

// Teensy4.1보드의 sd카드 슬롯을 이용
#define SDCARD_CS_PIN    BUILTIN_SDCARD
#define SDCARD_MOSI_PIN  11  // not actually used
#define SDCARD_SCK_PIN   13  // not actually used


//기타와 관련된 상수들
#define TOUCHED 1
#define UNTOUCHED 0

#define STRING1 24
#define STRING2 25
#define STRING3 26
#define STRING4 27
#define STRING5 28
#define STRING6 29


void setup() {
  Serial.begin(115200);
  delay(1000);

  // put your setup code here, to run once:
  AudioMemory(8);
  sgtl5000_1.enable();
  sgtl5000_1.volume(1.0);
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);

 
  if (!(SD.begin(SDCARD_CS_PIN))) {
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  
  
  Serial.println("Ready.");
  
  pinMode(STRING1,INPUT);
  pinMode(STRING2,INPUT);
  pinMode(STRING3,INPUT);
  pinMode(STRING4,INPUT);
  pinMode(STRING5,INPUT);
  pinMode(STRING6,INPUT);
  
}


bool prevString1 = UNTOUCHED;
bool prevString2 = UNTOUCHED;
bool prevString3 = UNTOUCHED;
bool prevString4 = UNTOUCHED;
bool prevString5 = UNTOUCHED;
bool prevString6 = UNTOUCHED;

///*
#define TIME_WAIT_TO_PLAY 2
void forcePlay(AudioPlaySdWav *ptrPlaySdWav, const char *wav){
  ptrPlaySdWav->stop();
  do{
    ptrPlaySdWav->play(wav);
    delay(TIME_WAIT_TO_PLAY);
  } while(!ptrPlaySdWav->isPlaying());
}
//*/

void loop() {

  int tm=millis();
///*
  bool str1 = digitalRead(STRING1);
  if (prevString1==UNTOUCHED and str1==TOUCHED){
    forcePlay(&playSdWav1, "g100E.wav");
  }

  bool str2 = digitalRead(STRING2);
  if (prevString2==UNTOUCHED and str2==TOUCHED){
    forcePlay(&playSdWav2, "g200B.wav");
  }

  bool str3 = digitalRead(STRING3);
  if (prevString3==UNTOUCHED and str3==TOUCHED){
    forcePlay(&playSdWav3, "g300G.wav");
  }

  bool str4 = digitalRead(STRING4);
  if (prevString4==UNTOUCHED and str4==TOUCHED){
    forcePlay(&playSdWav4, "g400D.wav");
  }


  bool str5 = digitalRead(STRING5);
  if (prevString5==UNTOUCHED and str5==TOUCHED){
    forcePlay(&playSdWav5, "g500A.wav");
  }

  bool str6 = digitalRead(STRING6);
  if (prevString6==UNTOUCHED and str6==TOUCHED){
    forcePlay(&playSdWav6, "g600E.wav");
  }

  
  prevString1=str1;
  prevString2=str2;
  prevString3=str3;
  prevString4=str4;
  prevString5=str5;
  prevString6=str6;
//*/
  

/*
  playSdWav1.stop();
  do{
    playSdWav1.play("g600E.wav");
    delay(TIME_WAIT_TO_PLAY);
  } while(!playSdWav1.isPlaying());
*/
  
  Serial.print(millis()-tm);
  Serial.print(", S1:");Serial.print(str1);
  Serial.print(", S2:");Serial.print(str2);
  Serial.print(", S3:");Serial.print(str3);
  Serial.print(", S4:");Serial.print(str4);
  Serial.print(", S5:");Serial.print(str5);
  Serial.print(", S6:");Serial.print(str6);
  Serial.println();
  delay(10);
}

Posted by 살레시오
,

// 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 살레시오
,

//2021년10월29일:Wemos LOLIN32 Lite 보드 실험

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

// 터치입력핀(8개)과 출력핀번호(8개)를 저장한 배열들
// gpio22핀은 내부적으로 LED에 연결되어 LOW 값에 켜진다.(역동작)
// gpio22핀을 출력핀으로 사용하는 데에는 문제가 없다.
byte inTouch[8] ={T0, T2, T3, T4, T5, T6, T7, T8};
byte outPin[8] = {22, 19, 23, 18, 17, 16, 26, 25};


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


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


void setup() {
  
  // 소모전력을 줄이기 위해서 WiFi와 bt는 끈다.
  // ADC도 사용하지 않으므로 꺼야 한다.
  adc_power_off();
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  btStop();
    
  // 출력핀들을 OUTPUT으로 설정한다.
  for(byte k=0;k<8;k++){
    pinMode(outPin[k], OUTPUT);
  }

  //아래의 (1),(2),(3)은 소요시간을 확인하기 위한 코드
  //Serial.begin(115200); delay(100);//(1)
}


void loop() {
  //int tm = millis();//(2)

  for(byte k=0;k<8;k++) {
    int totalRead = 0;
    for(byte n=0; n<SAMPLES; n++) {
      totalRead += touchRead(inTouch[k]);
    }
    int averageRead = totalRead/SAMPLES;
    digitalWrite(outPin[k], averageRead<THRESHOLD);
  }

  //Serial.println(millis()-tm);//(3)소요 시간 표시
}

Posted by 살레시오
,

ESP32보드를 아두이노 IDE에서 C++   로 코딩할 수 있는 데 매우 간단하게 세팅할 수 있다.

(1) 아두이노 IDE에서 [파일]>[환경설정] 창의 "추가적인 보드 매니저 URLs"에 아래 주소를 붙여넣기(ctrl+v)로 추가하고 [확인]버튼을 누른다.

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json 

(2) 위 과정이 끝났다면 [툴]>[보드]>[보드 매니저] 창의 검색칸에 ESP32라고 입력하면 보드매니저를 설치할 수 있다. (현재 1.0.4 버전)

(3) 이제 esp32보드를 선택할 수 있다. 통신 포트(serial port)도 맞게 설정한다.



위의 과정을 다 했다면 이제 ESP32보드를 아두이노IDE로 코딩할 수 있다. WeMos LOLIN32 보드의 테스트 LED를 블링킹하려면 다음과 같이 코딩하고 업로드 버튼을 클릭한다.

void setup() {

    pinMode(5,OUTPUT);

}

 void loop() {

    digitalWrite(5,HIGH);

    delay(500);

    digitalWrite(5,LOW);

    delay(500);    

}


참고로 유튜브 관련 영상에 보면 컴파일이 끝나면 BOOT(gpio0)핀이 LOW가 되어야 업로드가 된다고 하는데.. 현재 최신 버전의 esp32매니저와 적어도 LOLIN32 보드에서는 그렇지 않고 자동으로 업로딩되고 업로딩 완료시 리셋까지 되는 것 같다.

Posted by 살레시오
,