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








 게시판 검색





 
 
회원등록 비번분실


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

      거래은행 바로가기
 
 Sensor Applications
아듀이노 응용소스
작성자 avrtools™        
작성일 2018/02/11
ㆍ추천: 0  ㆍ조회: 77   
  ESP32+OLED 기판과 PWM generator
ESP32+OLED 기판에서 PWM 주파수를 만드는 방법의 설명
Wemos-Lolin32는 Espressif (http://www.espressif.com/)의 250MHz Dual cpu+WiFi+Bluetooth 칩을 사용한다.
그리고 SSD1306 OLED (128x64 dots I2C interface)가 장착되어 있어, 간단한 문자나 그래픽을 바로 표시할 수 있다.

 Wemos-Lolin32 (ESP32+OLED) 개발 기판
 

Wemos-Lolin32 (ESP32+OLED) 개발 기판의 규격
USB : CP2102 USB2serial +micro USB-B 커넥터.
CPU : 240MHz Dual Core MPU
ROM: 4MB SPI flash 메모리
WiFi 802.11 b/g/n + Bluetooth 4.0 LE + LNA + Antenna
26개의 GPIO 핀은 3.3V 디지털 입력/출력과 PWM 펄스를 발생시킬 수 있다.
2개의 12 BIT SAR ADC와 2개의 8 BIT DAC, (SAR 변환방식은 속도가 빠르나, 변환값은 안정하지 않다)
3개의 UART, 3개의 SPI, 2개의 I2S와 2개의 I2C

 ADC : 변환속도를 바꿀 수 있으며 18개 Analog Multiflex로 GPIO 핀에 연결된다.
분해능 : 변환 Resolution 9 BIT, 10 BIT, 11 BIT, 12 BIT로 변경할 수 있다.(증가시키면 분해능이 올라간다)
설정 예 : analogReadResolution(10); // resolution bit =(9~12) default =12

변환속도 : Clock Divider 1~255는 ADC를 구동하는 Clock의 주파수를 바꾼다. (증가시키면 변환값이 안정된다)
설정 예: analogSetClockDiv(1); // adc clock divider =(1~255) default =1

변환 Cycles : 1회의 변환에 사용하는 반복횟수 1~255, Default 8 (증가시키면 변환값이 안정된다)
설정 예: analogSetCycles(8); // cycle per sample =(1~255) default =8

변환 Samples : 변환결과에 포함할 표본수 1~255, Default 1 (증가시키면 변환값이 적분된다)
설정 예: analogSetSamples(1); // number of +samples in range, default =1

입력 감쇄기 : ATT는 0db, 2.5db, 6db, 11db를 설정할 수 있다. Default 11db
구체적으로 ADC의 설정방법을 살펴보자, ADC의 최대눈금 FS은 1.1V 부터 3.3V 까지이다.
설정 예 : analogSetAttenuation(ADC_11db); // Att dB =11, default =ADC_0db

만일 0dB 감쇄기를 선택하면 1.1V FS 이므로, 그 이상의 입력신호는 외부 감쇄기를 추가해야 한다.
ADC_0db를 선택하면 ATT는 1/1 이다. 최대입력 FS은 1.1V로 변환값은 0~1088 이다.
ADC_2_5db를 선택하면 ATT는 1/1.34 이다. 최대입력 FS은 2.1V로 변환값은 0~2086 이다.
ADC_6db를 선택하면 ATT는 1/1.5 이다. 최대입력 FS은 3.0V로 변환값은 0~2975 이다.
ADC_11db를 선택하면 ATT는 1/3.6 이다. 최대입력 FS은 4.0V로 변환값은 0~3959 이다.

 ADC의 실제 사용 예

//********************************************
// init adc A0(VP) and adc A3(VN)
//********************************************
void init_ADC_2CH()
{
  // ESP32 integrates two 12-bit SAR ADCs (0~4095)
  // and supports measurements 18 channels (analog enabled pins 32~39)

  //analogSetClockDiv(1); // adc clock divider =(1~255) default =1
  analogReadResolution(10); // resolution bit =(9~12) default =12


  //analogSetCycles(8);  // cycle per sample =(1~255) default =8
  //analogSetSamples(1);  // intergration samples, default =1


  // ADC_0db =ATT 0.0 ---> 1088/1V max =1.1V
  // ADC_2_5db =ATT 1.34 ---> 2086/1V max =2.1V
  // ADC_6db =ATT 1.5 ---> 2975/1V max =3.0V
  // ADC_11db  =ATT 3.6 ---> 3959/V max =4.0V, default 11db


  analogSetPinAttenuation(36, ADC_11db);  // A0 attenuation 11db =4.0Vfs
  adcAttachPin(36); // Attach A0 to ADC, returns TRUE/FALSE result
  adcStart(36);  // Starts A0 (VP)  // Ex: adc0_Value =analogRead(36);


  analogSetPinAttenuation(39, ADC_11db);   // A3 attenuation 11db =4.0Vfs
  adcAttachPin(39); // Attach A3 to ADC, returns TRUE/FALSE result
  adcStart(39);  // Starts A3(VN)  // Ex: adc1_Value =analogRead(39);
};  

 측정 예: 실제로 ADC를 사용하면 변환속도가 1us 까지 올라가지 않는다.
 
 
10비트 분해능으로 ADC값을 120개 2채널로 읽어 보았지만 3000us이 소모되었다. 
3000us/120*2ch =12.5us/conv으로 검토결과는 12.5 us/cyc 정도 나온다.
 

ADC 변환속도를 측정해보았다.
void setup()의 끝부분에 아래 소스를 넣고 Upload한 다음 변환속도를 읽는다.
 
void setup()
{
 
  unsigned long readStartTime =0;  // time when the current sampling started
  unsigned long totalSampleTime =0; // display sampling time
  unsigned int adcVal; 

  readStartTime =micros();  // start sampling
  adcVal =analogRead(A0);
  totalSampleTime =(micros() -readStartTime); // sampling time [us]

  Serial.print(adcVal, HEX);
  Serial.print(" SampleTime=");
  Serial.print(totalSampleTime, DEC);

  Serial.println(" us");
};

 
결과는 1회 ADC 샘플링에 15~16us의 변환시간이 나온다, ESP32 ADC의 변환속도는 1us 정도이나.
Library에 들어있는 ADC 함수의 처리속도와 시간측정의 저장시간도 포함되기 때문에 15us 정도로 느려진다.
 
ADC를 interrupt로 직접 처리하면, 변환완료시 handller에서 바로 값을 읽고, 다음 완료까지 저장하면 되는데,,,
1 cycle이 1000us인 1KHz 정현파를 측정하면, 1000us/25us =40개 이므로 1KHz는 40 point를 측정한다.
Phase로 환산하면 360도/40개 =9도이고, 1Vpp 신호인 경우 진폭 분해능(resolution)은 약 0.025V가 된다.
 
연속측정 그래프를 보면 120 개 샘플링에 3 cycle이 들어왔으므로 (1000us*3)/120개 =25us 이나온다.
1KHz 정현파 발생 DDS를 끄고 시험하니 샘플링 속도가 올라간다. 여기서 문제가 있었다. 
 
아래 코드로 A0와 A3의 2ch로 1KHz 정현파를 3cycle을 읽었다.
A0는 GPIO 36번 VP로 3Vpp의 정현파 입력, A3는 GPIO 39번 VN으로 1.2Vpp 정현파 입력이다.

코드 예: 시험해 보면 for() 함수보다 while() 함수가 30~50% 정도 더 빠르다.

  unsigned int u =0;
  readStartTime =micros();  // start sampling 

  while (u <maxSamples) 
  {
    adc0_Val[u++] =analogRead(36);  // A0 =10bit (0~1023)
  } 
  totalSampleTime =(micros() -readStartTime); // sampling time [us]

 
이유는 먼저 변수를 u =0으로 초기화하고 순환 loop에서는 u++만 실행하기 때문이다.  
컴파일러는 매번 조건을 확인하는 위치에서 변수를 점검하여 탈출조건을 확인하는데
변수의 초기화코드도 읽고 필요없으면 무시하는 쓸데없는 작동을 반복한다.
 
  unsigned int u =0;
  readStartTime =micros();  // start sampling
 
  for (; u <maxSamples; u++) 
  {
    adc0_Val[u] =analogRead(36);  // A0 =10bit (0~1023)
  } 
  totalSampleTime =(micros() -readStartTime); // sampling time [us]

for 반복실행도 반복조건에서 초기화 변수를 빼면 (먼저 변수를 초기화하면) 빠르게 실행된다.

//********************************************
// init adc A0(VP) and adc A3(VN)
//********************************************
void init_ADC_2CH()
{
  // ESP32는 2개의 ADC를 내장하고 있다. 분해능은 10 bit로 설정한다.
  // Default와 같은 설정은 안바꿔도 된다. 

  analogReadResolution(10); // resolution bit =(9~12) default =12
  //analogSetCycles(8);  // cycle per sample =(1~255) default =8
  //analogSetSamples(1);  // intergration samples, default =1

 
  // ADC CH0의 설정
  analogSetPinAttenuation(36, ADC_11db);  // A0 attenuation 11db =4.0Vfs 
  adcAttachPin(36); // Attach A0 to ADC, returns TRUE/FALSE result
  adcStart(36);  // Starts A0 (VP)  // Ex: adc0_Value =analogRead(36);

 
 // ADC CH3의 설정
  analogSetPinAttenuation(39, ADC_11db);   // A3 attenuation 0db =3.0Vfs
  adcAttachPin(39); // Attach A3 to ADC, returns TRUE/FALSE result
  adcStart(39);  // Starts A3(VN)  // Ex: adc1_Value =analogRead(39);
};

void setup()
{
  init_SSD1306();   // init SSD1306 128x64 white-OLED
  init_ADC_2CH();   // init A0(VP) and A3(VN)
  init_DAC_TIMER(); // Timer interrupt for sne wave output to DAC-0

 
  Serial.begin(115200); // init debug monitor
  Serial.println();

};
 
void loop()

{
  // ADC CH0의 측정, maxSamples는 120 개이다.
  unsigned int u =0; 
 
  readStartTime =micros();  // start sampling
  while (u <maxSamples) {
    adc0_Val[u++] =analogRead(36);  // A0 =10bit (0~1023)
    } 
  totalSampleTime =(micros() -readStartTime); // sampling time [us]

 
  // ADC CH3의 측정, maxSamples는 120 개이다.
  unsigned int v =0; 
  while (u <maxSamples) {
    adc1_Val[v++] =analogRead(39);  // A3 =10bit (0~1023)
    }

 
  // ADC CH0과 CH3의 표시장치는 SSD1306 128x64 OLED 이다. 
  display.clear(); // Display the data on screen   
  drawAxis(); // draw Xaxis and Yaxis
  findTrig();   // find trigger point and draw adc0_Values[t1] with adc1_Values[t1] 

  // 측정시간의 표시 (us)      
  drawFrameTime(totalSampleTime /2); // display sampling time =3000us/total
  display.displa();

};
 
 ESP32 기판의 LED 구동용 PWM 발생방법
Arduino IDE에서 기판의 선택을 ESP32나 Wemos-Lolin32로 바꾸어야 한다.

 
// PWM 파형발생 초기화 함수
// esp32-hal-ledc.h는 기판을 ESP32로 선택하면, Default로 함수를 사용할 수 있다.
void init_PWM_FREQ(unsigned int pwm_freq, unsigned int pwm_duty)

  // frequency output pwm_freq (Hz)
  #define pwm_ch 1  // led control ch =1
  #define pwm_pin 16  // output pin =GPIO 16
  #define pwm_reso 8  // 10 bit resolution (0~256)
  
  ledcSetup(pwm_ch, pwm_freq, pwm_reso); // ch =1, 1000 Hz, 8-bit depth
  ledcAttachPin(pwm_pin, pwm_ch);  // GPIO 16 on ch =1
  ledcWrite(pwm_ch, pwm_duty);  // LED ch =1, Duty =50% 
};

void setup()

{
 // PWM 파형발생 초기화 함수를 한번 호출하면, Hradware Timer 설정이므로 계속 작동된다.
 // PWM파형 발생기를 5KHz 50% duty로 초기화 한다
  init_PWM_FREQ(5000, 127); // freq =Hz, duty =0~256(100%)

};
 
void loop()
{
  // 주함수에서 PWM 출력을 바꾸고 싶으면 다음과 같이 CH과 PWM을 바꾸면 된다.
  // CH은 GPIO 26개 중에서 아무거나 고르면 되고, PWM은 0~100%를 설정할 수 있다.
  // 즉 26개의 LED의 PWM Duty를 바꾸면, LED 밝기가 변하므로 LED 조명을 연출할 수 있다.
  ledcWrite(pwm_ch, pwm_duty);  // LED ch =1, Duty =50% 
};

 응용 예: ADC CH0의 값으로 LED CH1 --> GPIO 16 핀에 연결된 LED 밝기를 변화시키는 코드

void setup()
{
  // frequency output pwm_freq (Hz)
  #define pwm_ch 1  // led control ch =1
  #define pwm_pin 16  // output pin =GPIO 16
  #define pwm_reso 8  // 10 bit resolution (0~256)

 
  ledcSetup(pwm_ch, pwm_freq, pwm_reso); // ch =1, 1000 Hz, 8-bit depth
  ledcAttachPin(pwm_pin, pwm_ch);  // GPIO 16 on ch =1

};
 
void loop()
{  unsigned int pwm_duty;
 
  pwm_duty =analogRead(36);  // A0 =10bit (0~1023)
  ledcWrite(pwm_ch, pwm_duty);  // LED ch =16, Duty =A0(VP) 

};

 소감
ESP32는 12,000원 (USD 10.50) 이면 입수할 수 있는 250MHz로 작동하는 32비트 CPU가 2개들어 있고
ROM은 4M로 2개의 12비트 ADC, 2개의 8비트 DAC, WiFi, Bluetooth, Hardware Timer를 사용할 수 있다.


Wemos-Lolin32 기판은 OLED도 달려있어, USB 케이블만 연결하면 간단한 그래픽 표시를 할 수 있다.
  
ESP32 기판의 Library는 Arduio IDE에 등록되어 있으므로, Arduino IDE에서 기판 설정만 바꾸면, 
Arduino를 사용하던 경험을 바로 적용할 수 있고, Arduino 코드를 거의 그대로 사용할 수 있다.

실제로 ESP32를 써 본 경험으로, 단순하게 UNO에서 ESP32로 기판만 바꾸었다고 생각하면 된다.  
단지, UNO에는 없던 12BIT ADC, 8 BIT DAC, Hardware PWM Timer, WiFi, Bluetooth,
On board OLED 등이 있지만, 점차적으로 사용해 보면 되는 것이고, 필요 없으면 안쓰면 된다.
 
지금은 ADC의 변환속도인 1us를 최대로 활용해야 하는 응용 과제가 있어 조금 바쁘지만,,,
시간이 나는데로 OLED의 그래픽 표시방법, DAC의 사용방법, WiFi와 Blutooth의 응용 예를 소개하겠다.
 
 이 펌웨어 소스를 응용한 장치의 개발이나, 주문형 펌웨어가 들어간 모듈 주문 받습니다.
 이자료의 무단 복제 및 무단 배포를 금지합니다.


이 프로그램은 무료 소프트웨어로, 신체와 재산 상의 어떤 위험과 손해를 보상하지 않습니다.
이 프로그램은 GNU 무료 소프트웨어 배포규정을 따릅니다.
 AVRTOOLS™ 
   
윗글 STM32F103C ARM32 기판의 Bootloader 개조
아래글 Wemos-Lolin32 Audio FFT Analyzer 제작
    N         제목    글쓴이 작성일 조회 추천
아듀이노 응용소스 게시판 avrtools™ 2016/02/05 (금) 346 0
41 STM32F103C 12비트 정현파 DDS V2 avrtools™ 2018/03/08 (목) 43 0
40 STM32F103C ILI9341 TFTLCD Scope V2 avrtools™ 2018/03/05 (월) 60 0
39 STM32F103C 32비트 ARM-CPU 2채널 Scope avrtools™ 2018/02/25 (일) 66 0
38 STM32F103C의 ILI9341 ILI9163 TFT-LCD 연결방법 avrtools™ 2018/02/19 (월) 74 0
37 STM32F103C+MCP4725 DDS 1KHz 정현파 발생기 avrtools™ 2018/02/18 (일) 76 0
36 STM32F103C 기판의 1~8CH ADC DMA 전송 avrtools™ 2018/02/17 (토) 74 0
35 STM32F103C 기판의 SSD1306 OLED 구동 avrtools™ 2018/02/16 (금) 75 0
34 STM32F103C ARM32 기판의 독립 IDE 소개 avrtools™ 2018/02/14 (수) 83 0
33 STM32F103C ARM32 기판의 Bootloader 개조 avrtools™ 2018/02/14 (수) 89 0
32 ESP32+OLED 기판과 PWM generator avrtools™ 2018/02/11 (일) 77 0
31 Wemos-Lolin32 Audio FFT Analyzer 제작 avrtools™ 2018/02/07 (수) 75 0
30 DUE SAM3X8E Audio FFT Analyzer 제작 avrtools™ 2018/01/30 (화) 85 0
29 AD5933 LCR-Impedance Analyzer 제작 avrtools™ 2012/03/17 (토) 605 0
28 ESP-01 펌웨어 업그레이드와 WiFi 2 Relay Control avrtools™ 2017/12/24 (일) 80 0
27 ESP12E-devKit로 만드는 WiFi 4 Relay 제어장치 avrtools™ 2017/12/23 (토) 79 0
26 M328-mini로 만드는 Touch 용량검출센서 avrtools™ 2017/12/19 (화) 79 0
25 ESP8266 MQTT Relay Control avrtools™ 2016/03/03 (목) 534 0
24 2 채널 ESP8266 WiFi Switch의 제작 avrtools™ 2016/02/25 (목) 635 0
23 ESP-12E SDK 0.9.5 사용방법 avrtools™ 2016/02/18 (목) 597 0
22 ESP8266 ESP-12E WiFi 센서 서버의 제작 avrtools™ 2016/02/17 (수) 564 0
21 Arduino DS3231 RTC to 5110 LCD avrtools™ 2016/02/16 (화) 575 0
20 ESP8266 Weather Server의 제작 avrtools™ 2016/02/15 (월) 598 0
19 Arduino 온습도 센서 DHT-22 avrtools™ 2016/02/12 (금) 497 0
18 ESP8266 WiFi 펌웨어 업그레이드 avrtools™ 2016/02/11 (목) 769 0
17 Arduion ESP8266 WiFi 설정 방법 avrtools™ 2016/02/10 (수) 752 0
16 Arduino 정전용량식 수분센서의 분석과 제작 avrtools™ 2016/02/07 (일) 416 0
15 Arduino 전극식 수분센서의 분석과 제작 avrtools™ 2016/02/07 (일) 554 0
14 Arduino 정밀 전력계의 ADC avrtools™ 2016/02/02 (화) 818 0
13 Arduino 정밀 전력계의 LPF avrtools™ 2016/02/02 (화) 563 0
12 Ardunio 16비트 ADC Data Logger avrtools™ 2016/01/31 (일) 444 0
11 Arduino AC/DC Power Meter의 제작 avrtools™ 2016/01/29 (금) 862 0
10 Arduino 교류 역율계(power factor)의 제작 avrtools™ 2016/01/29 (금) 572 0
9 Arduino DUE Pezo-SPeaker LCQ Meter 소스 avrtools™ 2016/01/24 (일) 370 0
8 QTouch ADC 근접검출 스위치 avrtools™ 2016/01/21 (목) 598 0
7 Arduino 음성인식 Speech/Voice Recognition avrtools™ 2013/09/14 (토) 1809 0
6 Arduino Uno로 만드는 3축 CNC avrtools™ 2013/09/10 (화) 2736 0
5 Arduino로 만드는 mySpectral 분광기 avrtools™ 2013/09/04 (수) 2259 0
4 8채널 12비트 ADC MCP3208 오실로스코프 avrtools™ 2012/03/29 (목) 639 0
3 교류저항 (impedance) 측정 AD5933 avrtools™ 2012/03/17 (토) 597 0
2 Arduino DMX512 수신기 제작 avrtools™ 2012/03/15 (목) 3830 0
1 TSL2561 조도 측정기의 제작 avrtools™ 2011/09/11 (일) 2814 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