Hardware | EPS32 PWM 기능 확인해 보기

|

ESP32 에 관한 포스트는 아래를 참고해 주세요.


* Hardware | ESP32 의 internal sensor 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-internal-sensors

* Hardware | ESP32 의 Dual core 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-Dual-core

* Hardware | ESP32 스펙 확인해 보기
    - https://chocoball.tistory.com/entry/Hardware-ESP32-spec-check

* Hardware | ESP32 간단 사용기
    - https://chocoball.tistory.com/entry/Hardware-simple-review-ESP32




1. PWM


ESP32 에는 PWM (Pulse Width Modulation) 기능이 들어가 있습니다.

LED 의 dimming (밝기) 조절이나, LCD panel 의 색조절 등에 사용되는 기법입니다.


일전에 8x8 LED matrix 를 다양한 색을 표현하기 위해, PWM 을 구현해 주는 전용 보드를 사용해서 확인해 본 적이 있습니다.


* Hardware | 8x8 LED matrix 와 Colorduino 이용해 보기
    - https://chocoball.tistory.com/entry/Hardware-8x8-LED-matrix-Colorduino


이반적인 Arduino 에는 이 기능이 기본 내장이 아닌지라, PWM 을 구현하려면 대응 보드를 사용해야 하는 번거로움이 존재합니다.

그치만, ESP32 는 기본 내장이에요!



PWM 을 통한 활용은 LED 뿐 만 아니라, step motor 난 piezo speaker 등에서도 활용할 수 있습니다.



기본 동작은 높은 주파수를 통해, on/off 를 해주는 시간 (duty) 를 변경하면서 조절하는 방법입니다.

당연히 duty 가 길면 길수록 밝기가 세다거나, 지속적인 동작을 보여주는 원리 입니다.

LED, Step motor, 그리고 Piezo 스피커를 작동시키는 동작원리와 완벽히 같습니다.




2. 코딩


지금까지 몇 번 봐왔던 원리인지라, 바로 코딩에 들어가 봅니다. 참조한 사이트는 아래 입니다.


* ESP32 PWM Example
    - https://circuits4you.com/2018/12/31/esp32-pwm-example/


PWM 을 구현하기 위한 명령어는 라이브러리에 준비되어 있으니, 그냥 사용해 줍니다.


* ledcSetup(PWM_Channel_Number, Frequency, resolution)

- Pass three arguments as an input to this function, channel number, frequency and the resolution of PWM channel at inside the setup function only.


* ledcAttachPin(GPIO_PIN , CHANNEL)

- Two arguments. One is the GPIO pin on which we want to get the OUTPUT of signal and second argument is the channel which we produce the signal.


* ledcWrite(CHANNEL, DUTY_CYCLE)

- ledcWrite function is used to generate the signal with a duty cycle value.


ledcSetupledcAttachPin 은 setup() 에서, 실제 구동은 loop() 에서 ledcWrite 를 사용합니다. digitalWrite 와 비슷하죠.

최종적으로 ESP32 보드에 실장되어 있는 LED 를 가지고 PWM 을 확인한 코드가 아래 입니다.


// Generates PWM on Internal LED Pin GPIO 2 of ESP32
#define LED 2 //On Board LED

int brightness = 0; // how bright the LED is
int fadeAmount = 5; // how many points to fade the LED by

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 10; // Resolution 8, 10, 12, 15

void setup() {
	Serial.begin(115200);
	pinMode(LED, OUTPUT);
	
	// configure LED PWM functionalitites
	ledcSetup(ledChannel, freq, resolution);
	
	// attach the channel to the GPIO2 to be controlled
	ledcAttachPin(LED, ledChannel);
}

void loop() {
	// PWM Value varries from 0 to 1023
	Serial.println("10 % PWM");
	ledcWrite(ledChannel, 102);
	delay(2000);
	
	Serial.println("20 % PWM");
	ledcWrite(ledChannel,205);
	delay(2000);
	
	Serial.println("40 % PWM");
	ledcWrite(ledChannel,410);
	delay(2000);
	
	Serial.println("70 % PWM");
	ledcWrite(ledChannel,714);
	delay(2000);
	
	Serial.println("100 % PWM");
	ledcWrite(ledChannel,1024);
	delay(2000);
	
	// Continuous Fading
	Serial.println("Fadding Started");
	while(1) {
		// set the brightness of pin 2:
		ledcWrite(ledChannel, brightness);
		
		// change the brightness for next time through the loop:
		brightness = brightness + fadeAmount;
		
		// reverse the direction of the fading at the ends of the fade:
		if (brightness <= 0 || brightness >= 1023) {
			fadeAmount = -fadeAmount;
		}
		
		// wait for 30 milliseconds to see the dimming effect
		delay(10);
	}
}




3. LED_BUILTIN


위의 코드를 실행하면 Serial Monitor 에서는 다음과 같이 표시됩니다.


소스에서도 알 수 있듯이, 10% > 20% > 40% > 70% > 100% 으로 LED 를 키고, 그 다음부터는 5/1024 씩 증감하면서 dimming 을 표현해 줍니다.

실제 동작 동영상은 다음과 같습니다.




4. 오실로스코프 확인


여기서 끝내면 심심하니, 실제 파형을 확인해 보려 합니다. 참고한 사이트는 다음과 같습니다.


* ESP32 PWM with Arduino IDE (Analog Output)
    - https://randomnerdtutorials.com/esp32-pwm-arduino-ide/


소스 코드는 다음과 같습니다.


// the number of the LED pin
const int ledPin = 16;  // 16 corresponds to GPIO16
const int ledPin2 = 17; // 17 corresponds to GPIO17
const int ledPin3 = 5;  // 5 corresponds to GPIO5

// setting PWM properties
const int freq = 5000;
const int ledChannel = 0;
const int resolution = 8;
 
void setup() {
	// configure LED PWM functionalitites
	ledcSetup(ledChannel, freq, resolution);
	
	// attach the channel to the GPIO to be controlled
	ledcAttachPin(ledPin, ledChannel);
	ledcAttachPin(ledPin2, ledChannel);
	ledcAttachPin(ledPin3, ledChannel);
}

void loop() {
	// increase the LED brightness
	for(int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
		// changing the LED brightness with PWM
		ledcWrite(ledChannel, dutyCycle);
		delay(15);
	}
	
	// decrease the LED brightness
	for(int dutyCycle = 255; dutyCycle >= 0; dutyCycle--) {
		// changing the LED brightness with PWM
		ledcWrite(ledChannel, dutyCycle);
		delay(15);
	}
}


3개의 LED 에 PWM 을 거는 소스 입니다.

2개 pin 에는 실제로 LED 를 연결해서 dimming 을 확인하고, 나머지 하나의 pin 에는 오실로스코프를 연결하여 파형을 확인해 봅니다.



이론과 실험이 만나는 동영상 입니다.



당연히 이렇게 될 것이라 알지만, 너무 이쁘게 그래프가 나와서 조금 놀랬습니다. Frequency 와 Duty 값이 정확하게 측정되는 군요.

ESP32 의 PWM 기능은 완벽하군요.




5. Piezo 연결


원리는 같으나, 눈으로 보면 다르게 느껴지는 Piezo 스피커도 확인해 보았습니다. 아래 링크를 참조하였습니다.


* ESP32 Arduino: Controlling a buzzer with PWM
    - https://techtutorialsx.com/2017/07/01/esp32-arduino-controlling-a-buzzer-with-pwm/


PWM 동작하는 GPIO 하나 잡아서 연결하면 됩니다.



저는 piezo 를 D4 = GPIO4 에 연결했습니다.


int freq = 2000;
int channel = 0;
int resolution = 8;
  
void setup() {
	Serial.begin(115200);
	ledcSetup(channel, freq, resolution);
	ledcAttachPin(4, channel);
}
  
void loop() {
	ledcWriteTone(channel, 2000);
	for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle = dutyCycle + 10) {
		Serial.println(dutyCycle);
		ledcWrite(channel, dutyCycle);
		delay(1000);
	}
	
	ledcWrite(channel, 125);
	for (int freq = 255; freq < 10000; freq = freq + 250){
		Serial.println(freq);
		ledcWriteTone(channel, freq);
		delay(1000);
	}
}


처음에는 2000Hz 에서 duty 사이클을 10씩 증가하는 소리이고,

그 다음은 duty 를 125로 고정한 다음, 주파수만 바꿔가면서 소리를 내는 소스 입니다.





FIN


지금까지 ESP32 의 내부 기능들을 확인해 봤습니다.

확인하지 않고 남아있는 기능들이 Deep Sleep 과 Hardware Acceleration (Cryptographic) 정도가 남았네요.


And