로그인회원등록 내글장바구니주문조회현재접속자
 상품 검색








 게시판 검색





 
 
회원등록 비번분실


온라인 입금계좌
ㆍ기업은행
ㆍ219-043192-01-028
ㆍ이건영

      거래은행 바로가기
 
 Sensor Applications
아듀이노 응용소스
작성자 avrtools™        
작성일 2018/02/07
첨부#2 arduinoFFT+ssd1306-master.zip (245KB) (Down:1)
ㆍ추천: 0  ㆍ조회: 184   
  Wemos-Lolin32 Audio FFT Analyzer 제작
youtube에서 Arduino Spectrum Analyzer라고 나온다.
Arduino-uno-nano, mic-amp, SSD-1306 OLED를 사용하여 AFFT를 제작한 동영상이다. 
참고:(Youtube 동영상) https://www.youtube.com/watch?v=5RmQJtE61zE

그런데 Wemos-Lolin32 (Aliexpress에서 12,000원, 무료배송)를 사용하면,
CPU도 빠르고 ADC감도도 높으므로,
기판 하나로 충분할 것 같아 바로 제작해 보았다.

 ESP32 개발기판을 사용한 Audio Spectrum Analyzer의 제작
대부분 저주파(Audio Frequency) FFT Analyzer를 만들때 Decoreation 용으로 만들기 때문에,

고증폭도 음성증폭기로 증폭한 신호를 분석기 입력에 연결해서, 작은 진폭의 주파수도 잘 보이도록 만든다.
그렇게 되면 주파수로는 표시가 잘 되므로 보기는 좋지만, 진폭은 전주파수 대역에서 과다 증폭되므로 알수 없다
 
주파수- 진폭 분석기는 과다 증폭할 필요가 없으므로, Audio Line 이나 Earphone 출력을 직결할 수 있다.
다음은 1 Transistor 증폭기 회로다. Decoreation FFT 표시장치도 이정도면 충분하다.
 

그러나 대부분의 치장용(Decoration) 음성 주파수영역 표시기(AFFT)의 입력회로는 위와 같이 잘 못 되어 있다.
다음과 같이 ADC 입력핀의 bias는 1/2 VDD로 만들어 주고, Audio 신호는 Capacitor로 절연해야 한다.
 
R1과 R2는 ESP32 기판(아니면 UNO)의 3.3V 전원을 1/2로 분할된 1.75V를 AO핀에 공급한다.
대부분의 ADC 입력핀 A0는 0V~3.0V 혹은 0V~5V의 단일극성의 신호만 읽을 수 있으므로,
±극성의 성분인 저주파 음성신호의 교류 파형은 0~1V 혹은 0~3V의 단일극성 교류신호로 바꾸어야 한다.
 
회로에서 -1V는 +1V와 가산되어 0V가 되고, 0V는 +1V와 가산되어 1V가 되고, 1V는 +1와 가산되어 +2V가 된다. 
위 회로에서 저주파 입력신호는 ±1.7.5V의 양극성 교류신호를 0~+3.3V의 단극성 교류신호로 변환하게 된다. 
음성 저주파신호 입력단자는 100nF의 Capacitor를 사용하여 ADC 입력핀의 1/2 VDD Bias를 유지해야 한다.

 
 Wemos-Lolin32 (ESP32) 개발모듈

 
 

Espressif 사에서 개발한 32 BIT CPU + WIFI 칩인 ESP8266이 발표된지 얼마 안되었는데,
벌써 ESP32 CPU가 나왔다. ESP32는 32 BIT CPU x 2개 + WiFi + Bluetooth가  들어간 칩이다.

Dual 32 Bit CPU + WiFi + Blutooth + Flash ROM + USB interface를 장착한 개발기판이 ESP32-DevKit다.
여기에 또 128x64 SSD1306 OLED를 추가로 장착한 모듈이 Wemos-Lolin32 개발기판이다. 

작동을 제어하는 누름 스위치는 밑면에 2개가 있는데, BOOT와 EN이다.
BOOT는 구워진(Burn) 작동코드(Firmware) 굽기(Burn)인 Bootloader를 시작한다.

하나만 누르면 작동하지 않는다. EN은 Firmware 굽기 허용(Enable)을 누르면  Reset 된다.
즉 2개를 동시에 누르고 하나를 놓으면 Bootloader가 작동하여 굽기모드로 들어간다.
자동으로 Reset 및 Reboot 되므로 거의 사용할 일이 없다. 오히려 EN을 누르면 Reset 이 된다.


 Wemos-Lolin32 개발기판의 핀 배열
  

 
검점색(black)과 적색은 전원핀이다.
하늘색(Cyan)은 Serial port이다.
회색(Grey)은 GPIO Aurduino IDE에서 호환핀으로 사용하는 GPIO 핀의 번호다.
보라(Magenta)색은 ADC 입력핀이다. 내부의 adc는 2개이며 multiplexer로 입력핀을 바꿀 수 있다.
주황색(Orange)은 Touch 입력핀으로 기능을 바꿀 수 있는 핀이다. 

 
EPS32 칩의 주요 규격은 다음과 같다.
2개의 240MHz 32 비트 MPU
4MB SPI flash memory (16M 까지 가능)
+ 와이파이 802.11 b/g/n
+ 블루투스 4.0 LE

26 개의 Digital 입출력(3.3V GPIO), 모든핀은 PWM 출력이 가능
18 개의 아날로그 입력
3 개의 UART
3 개의 SPI
2 개의 I2S
2 개의 DAC
2 개의 I2C


 Wemos-Lolin32 개발기판 (ESP32 개발기판)으로 만든 Audio Spectrum Anayzer 
 

가장 위쪽에는 장치의 이름을 ESP32 Audio FFT Analyzer라고 표시한다.
다음은 0~60 단계로 주파수 성분의 진폭을 막대그래프(여기서는 가느다란 한줄의 수직선)을 그려준다.
그리고 한화면의 주파수 분해능은 128개 이며, 각 주파수의 peak 값을 검출해서 표시한다.
 
해당 주파수의 입력이 없으면 peak hold된 값은 10ms의 주기로 -1씩 감소하여 0으로 소멸된다.
12 Bit ADC로 변환된 digital 값은 128 이상일 때 진폭을 표시하여 바닥수준(base Level)의 잡음을 제거한다.
0~4095의 digital 값은 128x64 dots의 OLED에서 너무 크므로 64로 나누어 0~60의 막대로 표시한다

 ESP32 AFFT code에 사용한 Library

  첨부파일 #2 (aduinoFFT+ssd1306-master.zip)
설치방법 : 첨부파일을 받아서 압축을 풀고, C:₩Documents₩Arduinolibraries₩ 안에 폴더를 복사해 넣는다.

Wire.h는 SSD1306 OLED에 연결되는 TWI (SPI 변형) interface를 구동하는 subroutine을 소스에 추가해 준다.
#include <Wire.h> // SSD1306 TWI interface subroutine

SSD1306.h는 128x64 dots의 Graphic OLED의 표시 subroutine을 소스에 추가해 준다.
#include <SSD1306.h>  // Initialize the OLED display using Wire library
SSD1306 display(0x3C, 5, 4);  //
Wemos-Lolin에 연결된 OLED의 주소는 0x3C다.

 
arduinoFFT.h는 64~2048 개의 ADC로 표본화(sampling)된 값을 분석하는 subroutine을 소스에 추가해 준다.
#include <arduinoFFT.h> // FFT 함수를 사용자 subroutine으로 불러 들인다
arduinoFFT FFT =arduinoFFT(); // subroutine의 소스를 사용자 이름으로 변경


 arduinoFFT.h의 사용방법
다음은 Analog 신호를 sampling하기 위한 환경변수들의 선언이다.
 
#define samplingFrequency 40000  // 샘플링 속도는 40KHZ, 최고 검출주파수는 1/2인 20KHz이다
#define signalFrequency 1000  // 샘플 주파수는 1KHz이다
#define noise_cut 256 // 바닥잡음을 제거하는 기준진폭은 256/4096 *3.3V =0.2047V 이다
unsigned int sampling_period_us; // 초기화 함수에서 샘플링 간격을 us으로 환산하여 저장하는 변수
unsigned long microseconds;  // 검출시간을 제어하기 위해 us으로 타이머 값을 저장하는 변수
 
#define samples 128 
// adc값을 저장하는 배열변수들의 크기는 128 개 이다.
double img[samples];  // 허수(imaginary) 128 개가 저장되는 배열변수
double real[samples];  // 실수(real) 128 개가 저장되는 배열변수
byte peak[samples];  // 첨두값(peak) 128개가 저장되는 베열변수
 
unsigned long newTime;
// 측정을 끝내고 현재 us 타이머의 값을 저장한다
unsigned long oldTime;  // 측정 시작시 us 타이머의 값을 저장한 변수
 
char x =0; 
// 수평축(X-axis)의 기준은 0 (좌측 끝) 이다
char y_bottom =60; // 수직축(Y-axis)의 기준은 60 (바닥 끝)이다.
int i = 0;  // 반복 카운터, 지역변수로 사용해도 된다.
int adcVal;  // 현재 측정된 adc값을 저장, 값을 수정해서 해당위치의 배열변수에 저장한다

 ESP-32 AFFT의 초기화 함수 seup()
 void setup() {
  Wire.begin(5, 4); // SDA =5, SCL =4,

  display.init();

  display.flipScreenVertically();
  display.clear();
  display.setContrast(255);
  display.display();

 
  Serial.begin(115200);
  Serial.println();

  display.setFont(ArialMT_Plain_10);  // min
  display.setColor(WHITE);

 
  analogSetSamples(9);  // number of +samples in range, default =1
  analogSetAttenuation(ADC_11db); // Att dB =(0, 2.5, 6, 11), default =ADC_0db
 
  sampling_period_us =round(1000000 *(1.0 /samplingFrequency));
  for (int i=0; i<=samples; i++) peak[i] =0; // init peak value
};


 arduinoFFT.h의 사용방법

FFT.h Libaray는 real[]과 img[]에 들어있는 sample값을 변환하여 rea[]과 ima[]에 저장한다.
배열변수위 크기는 대부분 library에 안에서 정의되어 있지만, (arduinoFFT.h는 64개) 
이번 코드와 같이 사용자 값으로 변경 할 수 있다. 예:  #define samples 128
물론 samples[], real[], img[]의 배열 크기도 128로 바꾸어 준비해야 한다.
 
  FFT.Windowing(real, samples, FFT_WIN_TYP_HAMMING, 0);  // FFT 주파수창을 찾는다
  Serial.println("Weighed data:");
  PrintVector(real, samples, SCL_TIME)  // 주파수창에 들어온 변환안된 샘플값을 표시한다. 
  
  FFT.Compute(real, img, samples, FFT_FORWARD);   // FFT 연산, samples값은 128개이다
  Serial.println("Computed Real values:");
  PrintVector(real, samples, SCL_INDEX); // 변환된 실수(real) 값을 표시한다


  Serial.println("Computed Imaginary values:");
  PrintVector(img, samples, SCL_INDEX);  // 변환된 허수(imaginary) 값을 표시한다
 
  FFT.ComplexToMagnitude(real, img, samples);  // 진폭변환 real =sqrt(real^2 +imag^2)
  Serial.println("Computed magnitudes:"); // 검출된 진폭을 표시한다
  PrintVector(real, (samples >> 1), SCL_FREQUENCY);  // 검출된 주파수를 표시한다


  double peakVal = FFT.MajorPeak(real, samples, samplingFrequency); // 첨두값을 찾는다
  Serial.println(pealVal, 6);  // 진폭(magnitude) 값에서 찾은 첨두(peak to peak)값을 표시한다  

 
 FFT 검출값을 Serial port로 전송하는 debug용 함수 PrintVector()

사용방법 ---> PrintVector(real, samples, SCL_INDEX); // 값이 들어있는 배열변수, 표본수, 변환기능

#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02

 
void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType)
{
  for (uint16_t i = 0; i < bufferSize; i++)
  {
    double abscissa;
    // Print abscissa value

    switch (scaleType)
    {
      case SCL_INDEX:
        abscissa =(i *1.0);
        break;
       
      case SCL_TIME:
        abscissa =((i *1.0) /samplingFrequency);
        break;
       
      case SCL_FREQUENCY:
        abscissa =((i *1.0 *samplingFrequency) /samples);
        break;
    }
   
    Serial.print(abscissa, 6);
    Serial.print(" ");
    Serial.print(vData[i], 4);
    Serial.println();
  }
  Serial.println();
};


 주함수 loop()

  첨부파일 #1 (esp32-afft-ssd1306.ino)

void loop(){
  int minVal =1024; // real value range =10 bit
  int maxVal =0;
 
  for (i = 0; i <samples; i++) {
    newTime =micros() -oldTime;
    oldTime =newTime;
   
    adcVal =analogRead(A0);  // read real value =A0 (GPIO =36)
    real[i] =(double)adcVal;  // save 12 bit adc
    img[i] =0;
   
    while (micros() < (newTime +sampling_period_us)) { }  // wait sample time
  }

  FFT.Windowing(real, samples, FFT_WIN_TYP_HAMMING, 0);  // find window of FFT
  FFT.Compute(real, img, samples, FFT_FORWARD);   // samples =128 
  FFT.ComplexToMagnitude(real, img, samples);  // real =sqrt(real^2 +imag^2)

  display.clear();
  display.drawString(0, 0, "ESP32 Audio FFT Analyzer");

  for (i =10; i <(samples /2); i++)  // X-axis =128 // cut-off low-freq <10/128 of freq span
  {
    if (real[i] >noise_cut)   // adc value =(0~1024), 512 =0 Volt <--- cut-off noise-amplitude <128
    { 
      int hor_bar =(real[i] -noise_cut) /64;  // Y-axis =64.max, Y-sacle =1/64 (gain control)

      if (hor_bar >60) hor_bar =60;   // Y-axis max draw =60     
      display.drawLine((i*2)-10, y_bottom, (i*2)-10, y_bottom -hor_bar);  // Y-axis draw
 
      if (hor_bar > peak[i]) peak[i] =hor_bar;  // make new peak
      display.setPixel(i*2-10, y_bottom -peak[i]);  // peak draw
    } // end of Y-axis draw of each freq.
  } // end of X-axis loop (10~127)
   
    if (millis() %10 ==0) 
{ // Decay the peak =peak display time
      for (int j =1; j <=samples; j++) { // freq scale =1~127 
        if (peak[j] >0) peak[j] -=1;  // decay the peak display
      }
    } // end of decay time
    display.display();  // update display
};  // end of loop()


 ESP32 AFFT 표시를 바꾼 예(내용이 길어지면 불편하므로 소스는 다음에 소개한다)
 

 
 이 펌웨어 소스를 응용한 FFT Analyzer 장치의 개발이나, 주문형 펌웨어가 들어간 모듈 주문 받습니다.
 이자료의 무단 복제 및 무단 배포를 금지합니다.
이 프로그램은 무료 소프트웨어로, 신체와 재산 상의 어떤 위험과 손해를 보상하지 않습니다.
이 프로그램은 GNU 무료 소프트웨어 배포규정을 따릅니다.
 AVRTOOLS™
   
윗글 ESP32+OLED 기판과 PWM generator
아래글 DUE SAM3X8E Audio FFT Analyzer 제작
    N         제목    글쓴이 작성일 조회 추천
아듀이노 응용소스 게시판 avrtools™ 2016/02/05 (금) 462 0
41 STM32F103C 12비트 정현파 DDS V2 avrtools™ 2018/03/08 (목) 145 0
40 STM32F103C ILI9341 TFTLCD Scope V2 avrtools™ 2018/03/05 (월) 173 0
39 STM32F103C 32비트 ARM-CPU 2채널 Scope avrtools™ 2018/02/25 (일) 173 0
38 STM32F103C의 ILI9341 ILI9163 TFT-LCD 연결방법 avrtools™ 2018/02/19 (월) 168 0
37 STM32F103C+MCP4725 DDS 1KHz 정현파 발생기 avrtools™ 2018/02/18 (일) 184 0
36 STM32F103C 기판의 1~8CH ADC DMA 전송 avrtools™ 2018/02/17 (토) 187 0
35 STM32F103C 기판의 SSD1306 OLED 구동 avrtools™ 2018/02/16 (금) 165 0
34 STM32F103C ARM32 기판의 독립 IDE 소개 avrtools™ 2018/02/14 (수) 216 0
33 STM32F103C ARM32 기판의 Bootloader 개조 avrtools™ 2018/02/14 (수) 229 0
32 ESP32+OLED 기판과 PWM generator avrtools™ 2018/02/11 (일) 181 0
31 Wemos-Lolin32 Audio FFT Analyzer 제작 avrtools™ 2018/02/07 (수) 184 0
30 DUE SAM3X8E Audio FFT Analyzer 제작 avrtools™ 2018/01/30 (화) 196 0
29 AD5933 LCR-Impedance Analyzer 제작 avrtools™ 2012/03/17 (토) 711 0
28 ESP-01 펌웨어 업그레이드와 WiFi 2 Relay Control avrtools™ 2017/12/24 (일) 170 0
27 ESP12E-devKit로 만드는 WiFi 4 Relay 제어장치 avrtools™ 2017/12/23 (토) 197 0
26 M328-mini로 만드는 Touch 용량검출센서 avrtools™ 2017/12/19 (화) 183 0
25 ESP8266 MQTT Relay Control avrtools™ 2016/03/03 (목) 669 0
24 2 채널 ESP8266 WiFi Switch의 제작 avrtools™ 2016/02/25 (목) 878 0
23 ESP-12E SDK 0.9.5 사용방법 avrtools™ 2016/02/18 (목) 718 0
22 ESP8266 ESP-12E WiFi 센서 서버의 제작 avrtools™ 2016/02/17 (수) 693 0
21 Arduino DS3231 RTC to 5110 LCD avrtools™ 2016/02/16 (화) 703 0
20 ESP8266 Weather Server의 제작 avrtools™ 2016/02/15 (월) 738 0
19 Arduino 온습도 센서 DHT-22 avrtools™ 2016/02/12 (금) 589 0
18 ESP8266 WiFi 펌웨어 업그레이드 avrtools™ 2016/02/11 (목) 962 0
17 Arduion ESP8266 WiFi 설정 방법 avrtools™ 2016/02/10 (수) 935 0
16 Arduino 정전용량식 수분센서의 분석과 제작 avrtools™ 2016/02/07 (일) 515 0
15 Arduino 전극식 수분센서의 분석과 제작 avrtools™ 2016/02/07 (일) 660 0
14 Arduino 정밀 전력계의 ADC avrtools™ 2016/02/02 (화) 991 0
13 Arduino 정밀 전력계의 LPF avrtools™ 2016/02/02 (화) 643 0
12 Ardunio 16비트 ADC Data Logger avrtools™ 2016/01/31 (일) 563 0
11 Arduino AC/DC Power Meter의 제작 avrtools™ 2016/01/29 (금) 1090 0
10 Arduino 교류 역율계(power factor)의 제작 avrtools™ 2016/01/29 (금) 702 0
9 Arduino DUE Pezo-SPeaker LCQ Meter 소스 avrtools™ 2016/01/24 (일) 447 0
8 QTouch ADC 근접검출 스위치 avrtools™ 2016/01/21 (목) 724 0
7 Arduino 음성인식 Speech/Voice Recognition avrtools™ 2013/09/14 (토) 1908 0
6 Arduino Uno로 만드는 3축 CNC avrtools™ 2013/09/10 (화) 2863 0
5 Arduino로 만드는 mySpectral 분광기 avrtools™ 2013/09/04 (수) 2375 0
4 8채널 12비트 ADC MCP3208 오실로스코프 avrtools™ 2012/03/29 (목) 746 0
3 교류저항 (impedance) 측정 AD5933 avrtools™ 2012/03/17 (토) 698 0
2 Arduino DMX512 수신기 제작 avrtools™ 2012/03/15 (목) 3974 0
1 TSL2561 조도 측정기의 제작 avrtools™ 2011/09/11 (일) 2909 0
1

바구니 : 0
 보관함 : 0
오늘뷰 : 0
HOME   |   회사소개   |   제휴안내   |   회사위치   |   서비스이용 약관   |   개인정보 보호정책   |   사이트맵
17015 경기도 용인시 기흥구 동백중앙로16번길 16-25, 508호. 전화 : 031-282-3310
사업자 등록번호 : 697-47-00075 / 대표 : 이건영 / 업태 : 제조업 / 종목 : LED조명, LED전원, 제어장치.
개인정보 관리책임자 : 홈페이지 관리자 . Copyright ⓒ2016 아크레즈 (ACLEDS INC.)
HOME TOP PREVNEXT 0 0 0